Pivotal Knowledge Base

Follow

Consolidating Request Header, Request Parameter, and Cookies in One Object Parameter in a Controller Method

Environment

 Product  Version
 Spring  All

Purpose

There are too many parameters in Spring MVC controller handler method (Too Many Parameters "code smell").

Symptom

The controller has a method that heavily uses request parameters, headers, and cookie similar to:

package foo.bar;
 
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
 
@Controller
public class MyContoller{
...
     @RequestMapping(value = "/someurl", method = RequestMethod.GET)
     public void myVeryVerboseMethod(@CookieValue("JSESSIONID") String cookie, 
     @RequestHeader("Accept-Encoding") String encoding,
     @RequestHeader("header1") String header1,
     @RequestHeader("header2") String header2,
     @RequestHeader("header3") String header3 ){
...
     }
}

Resolution

The very verbose method above can be converted to just a one-object-method parameter:

@RequestMapping(value = "/someurl", method = RequestMethod.GET)
public ModelAndView myNotSoVerboseMethod(MyRequestParams requestParams) {
   ...
 }

To achieve this method, add the following on your specified resolver for your custom parameter: 

The custom resolver should implement the WebArgumentResolver where you need to add the resolveArgument method where a NativeWebRequest is one of its parameters. The NativeWebRequest exposes requestParams, Headers, as well as cookies (via WebUtil). Here is an example of a custom resolver implementation:

package com.mycase.resolver;
  
import org.springframework.web.context.request.*;
 
public class MyCustomResolver implements WebArgumentResolver{
     public Object resolveArgument(MethodParameter methodParam, NativeWebRequest      webRequest){
          //check if parameter is of your bean
 
          if (methodParam.getParameterType()==MyRequestParams.class){
               MyRequestParams requestParams = new MyRequestParams();
 
               //set request param, header and cookie can be set here
               requestParams.setRequestParam1(webRequest.getParameter("param1"));
               requestParams.setRequestHeader1(webRequest.getHeader("header1"));
 
               HttpServletRequest servletRequest = (HttpServletRequest) webRequest.getNativeRequest();
               requestParams.setCookie1(WebUtils.getCookie(servletRequest, "cookie1").getValue());
 
               return requestParams;
          }
          return UNRESOLVED;
     }
}

Comments

Powered by Zendesk