簡體   English   中英

覆蓋Spring Data Rest POST方法

[英]Override Spring Data Rest POST method

我需要為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”映射的情況下獲得所需的邏輯?

在處理實體時,Spring Data REST會發出自己的事件

  • BeforeCreateEvent
  • AfterCreateEvent
  • BeforeSaveEvent
  • AfterSaveEvent
  • BeforeLinkSaveEvent
  • AfterLinkSaveEvent
  • BeforeDeleteEvent
  • AfterDeleteEvent

您可以收聽這些事件以添加其他業務邏輯。 例如,要在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)  
  }
}

PS如果我沒有弄錯的話,SDR會在當前事務之外發出這些事件,僅在它啟動之前或提交之后。 在實施業務邏輯時,您需要考慮到這一點......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM