Java Spring在单独的类中获取和发布映射

Java Spring在单独的类中获取和发布映射,java,spring,spring-mvc,http,request-mapping,Java,Spring,Spring Mvc,Http,Request Mapping,我们试图将Spring控制器中的GET和POST@RequestMapping方法分为两个独立的类 原因是我们希望POST调用具有一个异常处理程序,该处理程序将响应序列化为JSON有效负载,而GET调用应该通过Spring堆栈冒泡 但是,当我们尝试分离这些映射时,会收到错误,提示映射已注册两次: Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'or

我们试图将Spring控制器中的GET和POST
@RequestMapping
方法分为两个独立的类

原因是我们希望POST调用具有一个异常处理程序,该处理程序将响应序列化为JSON有效负载,而GET调用应该通过Spring堆栈冒泡

但是,当我们尝试分离这些映射时,会收到错误,提示映射已注册两次:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping#0' defined in OSGi resource[classpath:/dispatcher-servlet.xml|bnd.id=21|bnd.sym=com.company.application]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot map handler 'settingsController' to URL path [/settings.html]: There is already handler of type [class com.company.application.controller.SettingsModelAndViewController$$EnhancerBySpringCGLIB$$54324809] mapped.
可以将GET和POST请求映射分为两个不同的类吗?基本上我们想要(请原谅伪命名约定):


但目前,我们无法找到解决Spring双重映射问题的方法。

看看DispatcherServlet将URL路由到控制器(实际上是一个HandlerAdapter接口)的设计和代码,这显然是可能的,但并不容易,而且现有的HandlerMapping类也无法做到(查看在上实现此接口的现有类)。您必须编写HandlerMapping类(现有处理程序映射的代码可以指导您进行此操作),该类将基于URL和HTTP方法返回正确的控制器并对其进行配置(此链接应有助于HandlerMapping配置:)。当前的HandlerMapping类在为URL选择控制器时都不会查看HTTP方法


您可以通过向其中一个HTTP方法处理程序(例如)添加通配符来调整GET和POST请求映射,但不能在两个不同的控制器中使用完全相同的URL。

更好的选择是在不同的类(例如服务类)中执行GET和POST的大部分逻辑-并从请求处理程序进行一行调用,以调用服务类来处理请求。大多数逻辑要么已经重构,要么没有共享。分离的原因归结为我们希望根据呈现JSP,还是处理传入POST请求来不同地处理错误。在一种情况下,我们要重定向到一个错误页面,在另一个页面中,我们希望通过JSON将异常序列化回来。
class PostHandler {
    @ExceptionHandler
    public void handleException(...) { // Serialize to JSON }

    @RequestMapping(value = "/settings.html", method = RequestMethod.POST)
    public void saveChanges() { ... }
}

class GetHandler {
    @RequestMapping(value = "/settings.html", method = RequestMethod.GET)
    public ModelAndView getSettings() { ... }
}