简体   繁体   中英

Spring GET and POST mappings in separate classes

We are attempting to separate our GET and POST @RequestMapping methods in our Spring controllers into two separate classes.

The reason is that we want the POST calls to have an exception handler which serializes responses as JSON payloads, while the GET calls should be bubbled up through the Spring stack.

However, when we attempt to separate these, we receive errors suggesting that the mappings are being registered twice:

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.

Is it possible to separate GET and POST request mappings into two different classes? Basically we want (excuse the pseudo-naming conventions):

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() { ... }
}

But currently are unable to find a way around Spring's double-mapping complaints.

Looking at the design and code for DispatcherServlet that routes a URL to a Controller (actually to a HandlerAdapter interface), it certainly seems possible, but not easy and not by existing HandlerMapping classes (look at existing classes implementing this interface at https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/HandlerMapping.html ). You would have to write a HandlerMapping class (existing handler mappings' code can guide you with this), which would return the right controller based on the URL and HTTP method and configure it (this link should help with HandlerMapping configuration: http://www.baeldung.com/spring-handler-mappings ). None of the current HandlerMapping classes look at the HTTP method when choosing a controller for a URL.

You may be able to tweak the GET and POST request mapping, by adding let's say a wildcard to one of the HTTP method handlers (eg How do I set priority on Spring MVC mapping? ), but not by using the exact same URL in 2 different controllers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM