在 Spring 数据 Rest 上覆盖默认保存实体

Override default save Entity on Spring Data Rest

我想覆盖同样导出到 Rest 的默认 CrudRepository 保存方法 api:

@RepositoryRestResource(path = "users")
public interface UserRepository extends JpaRepository<User, Long> {


    @Override
    @RestResource(exported=false)
    User save(User user);


}

在我的 ApiController 中,我设置了这样的请求映射:

    @RequestMapping(value = "/", produces = "application/json", method = RequestMethod.POST)
        @ResponseBody
        public ResponseEntity<Resource<User>> registerUser(
          @RequestParam("name") String name, 
          @RequestParam("alias") String alias, 
          @RequestParam("email") String email, 
          @RequestParam("password") String password,
          @RequestParam("dateOfBirth") String dateOfBirth,
          @RequestParam("imageIdentifier") String imageIdentifier) {

         User user = new User();
         //try {
         // userReposiotry.save(user);
         //} catch (Exception e) {

         //}
         Resource<User> resource = toResource(user);
         return new ResponseEntity<Resource<User>>(resource, HttpStatus.OK);
}

问题是当我尝试 POST 到 localhost:8080/api/users 它 returns 一个 "Method Not allowed" 这很好,因为它被设置 "exported=false" 但是我如何为 localhost:8080/api/users 实现我自己的 POST 呢? 谢谢

找到解决方案:

@BasePathAwareController
@RequestMapping("/users")
public class RestApiController implements ResourceProcessor<Resource<User>>{
    @Autowired
    private EntityLinks entityLinks;

    @RequestMapping(method=RequestMethod.POST)
    @ResponseBody
    public ResponseEntity<Resource<User>> saveUser(@Param("name") String name) {
        // Testing
        System.out.println(name);
        Resource<User> resource = new Resource<>(new User());
        return new ResponseEntity<>(resource , HttpStatus.OK);
    }

    @Override
    public Resource<User> process(Resource<User> resource) {
            LinkBuilder lb = entityLinks.linkFor(User.class);
            resource.add(new Link(lb.toString()));
        return resource;
    }
}

在我的问题中,CrudRepository 保存仍然设置为 exported=false。

另一种方法是创建自定义存储库实现,如下所示:

@RepositoryRestResource(path = "users")
    public interface UserRepository extends JpaRepository<User, Long>, UserRepositoryCustom {

    @Override
    @RestResource(exported=false)
    User save(User user);
}

public interface UserRepositoryCustom {
    <S extends User> S save(T entity);
}

public UserRepositoryImpl implements UserRepositoryCustom {
    <S extends User> S save(T entity) {
        // implementation code...
    }
}

如果你查看 CrudRepository,你会发现一个方法 <S extends T> S save(S entity);,那是我从中获得 save(..) 的地方,只是将 extends T 更改为 extends User.

我要注意的另一件事是 classes/interfaces 的命名,尽量保持一致。我命名它们的方式应该适合您,UserRepositoryImpl 必须具有该名称才能起作用。

执行此操作时,您不必设置 exported=false,您可以像往常一样使用 save() 方法。