在 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()
方法。
我想覆盖同样导出到 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()
方法。