0

I have a complex bean holding the rest parameters, eg:

public class MyRestParams {
    private HttpServletRequest req;
    private @NotBlank String name;

    //getter, setter
}

Usage:

@RestController 
@RequestMapping("/xml")
public class MyServlet {
    @RequestMapping(value = "/")
    public void getTest(@Valid MyRestParams p) {
        Sysout(p.getName()); //works when invoked with /xml?name=test
        Sysout(p.getReq()); //always null
    }
}

Problem: the HttpServletRequest is always null. Isn't it possible to add this parameter within the bean itself?

membersound
  • 81,582
  • 193
  • 585
  • 1,120

2 Answers2

1

You can provide an implementation for HandlerMethodArgumentResolver to resolve your MyRestParams:

public class MyRestParamsArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(MyRestParams.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, 
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) throws Exception {
        MyRestParams restParam = new MyRestParams();
        restParam.setReq((HttpServletRequest) webRequest.getNativeRequest());

        return restParam;
    }
}

Then register it in your WebMvcConfigurerAdapter:

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new MyRestParamsArgumentResolver());
    }
}
Ali Dehghani
  • 46,221
  • 15
  • 164
  • 151
-1

When using that form of method signature Spring will use your bean as a model attribute. Spring will bind your request parameters to bean properties of matching names using a WebDataBinder e.g ServletRequestDataBinder.

Since there is no request parameter which matches your bean property req the field will never be set. Even if the request parameter with name req existed in your request it wont be convertible to a HttpServletRequest.

To receive the actual request add a parameter of type HttpServletRequest to your handler method

 @RequestMapping(value = "/")
 public void getTest(@Valid MyRestParams p , HttpServletRequest request) {
    Sysout(p.getName()); //works when invoked with /xml?name=test
    Sysout(request); //always null
 }

Or a parameter of type WebRequest if you dont want to tie yourself to the Servlet API.

ekem chitsiga
  • 5,523
  • 2
  • 17
  • 18
  • Your answer says "it's not possible" but apparently it's not true: http://stackoverflow.com/a/36722594/1240557 – kryger Apr 21 '16 at 15:25
  • I didnt say its not possible. I explained why with standard Spring implementation the field wont be set. Besides why do you have to complicate your design just to have an HttpServletRequest set to a POJO when you can do it the easier. Do you notice that with the suggested implementation you lose databinding which you have to implement yourself. Why complicate when you can do it clean and simple – ekem chitsiga Apr 21 '16 at 16:13