简体   繁体   English

如何将HttpServletRequest参数添加到复杂的RestController bean?

[英]How to add HttpServletRequest param to complex RestController bean?

I have a complex bean holding the rest parameters, eg: 我有一个包含其余参数的复杂bean,例如:

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. 问题: HttpServletRequest始终为null。 Isn't it possible to add this parameter within the bean itself? 是否可以在Bean本身中添加此参数?

You can provide an implementation for HandlerMethodArgumentResolver to resolve your MyRestParams : 您可以提供HandlerMethodArgumentResolver的实现来解析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 : 然后在您的WebMvcConfigurerAdapter注册它:

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        argumentResolvers.add(new MyRestParamsArgumentResolver());
    }
}

When using that form of method signature Spring will use your bean as a model attribute. 当使用这种形式的方法签名时,Spring会将您的bean用作模型属性。 Spring will bind your request parameters to bean properties of matching names using a WebDataBinder eg ServletRequestDataBinder. Spring将使用WebDataBinder(例如ServletRequestDataBinder)将您的请求参数绑定到匹配名称的Bean属性。

Since there is no request parameter which matches your bean property req the field will never be set. 由于没有与您的bean属性要求匹配的请求参数,因此永远不会设置该字段。 Even if the request parameter with name req existed in your request it wont be convertible to a HttpServletRequest. 即使您的请求中存在名称为req的请求参数,也无法将其转换为HttpServletRequest。

To receive the actual request add a parameter of type HttpServletRequest to your handler method 要接收实际的请求,请在处理程序方法中添加HttpServletRequest类型的参数

 @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. 如果您不想将自己绑定到Servlet API,则可以使用WebRequest类型的参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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