Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom HTTP Methods in Spring MVC

I am trying to create a custom Spring MVC Controller for a resource that would handle the COPY HTTP method.

@RequestMapping accepts only the following RequestMethod values: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS and TRACE.

Is there any recommended way of handling custom HTTP methods in Spring MVC Controller?

like image 378
wo.arciuch Avatar asked Oct 23 '15 12:10

wo.arciuch


1 Answers

The Servlet specification allows only for GET, HEAD, POST, PUT, DELETE, OPTIONS or TRACE HTTP methods. This can be seen in the Apache Tomcat implementation of the Servlet API.

And this is reflected in the Spring API's RequestMethod enumeration.

You can cheat your way around those by implementing your own DispatcherServlet overriding the service method to allow COPY HTTP method - changing it to POST method, and customize the RequestMappingHandlerAdapter bean to allow it as well.

Something like this, using spring-boot:

@Controller
@EnableAutoConfiguration
@Configuration
public class HttpMethods extends WebMvcConfigurationSupport {

    public static class CopyMethodDispatcher extends DispatcherServlet {
        private static final long serialVersionUID = 1L;

        @Override
        protected void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
            if ("COPY".equals(request.getMethod())) {
                super.doPost(request, response);
            }
            else {
                super.service(request, response);
            }
        }
    }

    public static void main(final String[] args) throws Exception {
        SpringApplication.run(HttpMethods.class, args);
    }

    @RequestMapping("/method")
    @ResponseBody
    public String customMethod(final HttpServletRequest request) {
        return request.getMethod();
    }

    @Override
    @Bean
    public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
        final RequestMappingHandlerAdapter requestMappingHandlerAdapter = super.requestMappingHandlerAdapter();
        requestMappingHandlerAdapter.setSupportedMethods("COPY", "POST", "GET"); // add all methods your controllers need to support

        return requestMappingHandlerAdapter;
    }

    @Bean
    DispatcherServlet dispatcherServlet() {
        return new CopyMethodDispatcher();
    }
}

Now you can invoke the /method endpoint by using COPY HTTP method. Using curl this would be:

curl -v -X COPY http://localhost:8080/method
like image 84
Zoran Regvart Avatar answered Sep 20 '22 15:09

Zoran Regvart