有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java重写Spring数据Rest POST方法

我需要为POST方法添加额外的业务逻辑。现在,我将重用RepositoryEntityController中的逻辑来获取和保存所需的对象

@RepositoryRestController
@RequestMapping("/customPost")
public class UserController implements ApplicationEventPublisherAware {

private final UserRepository userRepository;
private final RepositoryRestConfiguration config;
private final HttpHeadersPreparer headersPreparer;
private ApplicationEventPublisher publisher;

@Autowired
public UserController(UserRepository userRepository, RepositoryRestConfiguration config, HttpHeadersPreparer headersPreparer) {
    this.userRepository = userRepository;
    this.config = config;
    this.headersPreparer = headersPreparer;
}

public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
    this.publisher = publisher;
}

@ResponseBody
@RequestMapping(
        value = {"/{repository}"},
        method = {RequestMethod.POST}
)
public ResponseEntity<ResourceSupport> postCollectionResource(PersistentEntityResource payload, PersistentEntityResourceAssembler assembler, @RequestHeader(value = "Accept", required = false) String acceptHeader) throws HttpRequestMethodNotSupportedException {
    return this.createAndReturn(payload.getContent(), assembler, this.config.returnBodyOnCreate(acceptHeader));
}

private ResponseEntity<ResourceSupport> createAndReturn(Object domainObject, PersistentEntityResourceAssembler assembler, boolean returnBody) {
    publisher.publishEvent(new BeforeCreateEvent(domainObject));
    Object savedObject = userRepository.save((User) domainObject);
    publisher.publishEvent(new AfterCreateEvent(savedObject));
    PersistentEntityResource resource = returnBody ? assembler.toFullResource(savedObject) : null;
    HttpHeaders headers = headersPreparer.prepareHeaders(resource);
    addLocationHeader(headers, assembler, savedObject);
    return ControllerUtils.toResponseEntity(HttpStatus.CREATED, headers, resource);
}

private void addLocationHeader(HttpHeaders headers, PersistentEntityResourceAssembler assembler, Object source) {
    String selfLink = assembler.getSelfLinkFor(source).getHref();
    headers.setLocation((new UriTemplate(selfLink)).expand(new Object[0]));
}

}

我发送的代码-工作正常。但问题是,我需要向控制器添加一些请求映射@RequestMapping(“/customPost”)

如果没有这个映射,方法将无法工作。我尝试使用相同的控制器,但没有“/customPost”映射。我在应用程序开始时遇到此异常:

caused by: java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'repositoryEntityController' method 
public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> org.springframework.data.rest.webmvc.RepositoryEntityController.postCollectionResource(org.springframework.data.rest.webmvc.RootResourceInformation,org.springframework.data.rest.webmvc.PersistentEntityResource,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException
to {[/{repository}],methods=[POST],produces=[application/hal+json || application/json]}: There is already 'userController' bean method
public org.springframework.http.ResponseEntity<org.springframework.hateoas.ResourceSupport> com.project.controller.UserController.postCollectionResource(org.springframework.data.rest.webmvc.PersistentEntityResource,org.springframework.data.rest.webmvc.PersistentEntityResourceAssembler,java.lang.String) throws org.springframework.web.HttpRequestMethodNotSupportedException mapped.
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.assertUniqueMethodMapping(AbstractHandlerMethodMapping.java:576) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry.register(AbstractHandlerMethodMapping.java:540) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.registerHandlerMethod(AbstractHandlerMethodMapping.java:264) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]

我还尝试从控制器中删除“/customPost”映射,并将metod中的映射更改为“/users”。但对于这种情况,我有一个例外:

java.lang.NullPointerException: null
at org.springframework.data.rest.webmvc.config.RootResourceInformationHandlerMethodArgumentResolver.resolveArgument(RootResourceInformationHandlerMethodArgumentResolver.java:86) ~[spring-data-rest-webmvc-2.6.10.RELEASE.jar:na]
at org.springframework.data.rest.webmvc.config.PersistentEntityResourceHandlerMethodArgumentResolver.resolveArgument(PersistentEntityResourceHandlerMethodArgumentResolver.java:113) ~[spring-data-rest-webmvc-2.6.10.RELEASE.jar:na]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128) ~[spring-web-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) ~[tomcat-embed-core-8.5.27.jar:8.5.27]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) ~[spring-webmvc-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) ~[tomcat-embed-core-8.5.27.jar:8.5.27]

问题是:在不添加“/customPost”映射的情况下,我如何能够拥有所需的逻辑


共 (1) 个答案

  1. # 1 楼答案

    使用实体时,Spring Data REST会发出自己的events

    • 事件发生前
    • 后创建事件
    • 事件发生前
    • 余震
    • 事件之前
    • AfterLinkSaveEvent
    • 事件发生前
    • 后删除事件

    您可以收听这些事件来添加额外的业务逻辑。例如,要在SDR创建一个新的User(使用POST方法)或保存现有的User(使用PUT/PATCH方法)后执行,您可以使用这样的处理程序:

    @Component
    @RepositoryEventHandler 
    public class UserEventHandler {
    
      private final UserServie userServie;
    
      public UserEventHandler(UserServie userServie) {
          this.userServie = userServie;
      }
    
      @HandleAfterCreate
      public void handleAfterCreateUser(User user) {
          userService.afterCreate(user)  
      }
    
      @HandleAfterSave
      public void handleAfterSaveUser(User user) {
          userService.afterSave(user)  
      }
    }
    

    注:如果我没弄错的话,SDR只在当前交易开始之前或提交之后,才会在当前交易之外发出这些事件。在实现业务逻辑时,您需要考虑到这一点