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

时间:2016-04-19 14:57:12

标签: java spring spring-restcontroller

我有一个复杂的bean保存其余参数,例如:

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

    //getter, setter
}

用法:

@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
    }
}

问题:HttpServletRequest始终为空。是不是可以在bean本身中添加这个参数?

2 个答案:

答案 0 :(得分:1)

您可以提供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;
    }
}

然后在WebMvcConfigurerAdapter

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

答案 1 :(得分:-1)

当使用这种形式的方法签名时,Spring将使用您的bean作为模型属性。 Spring将使用WebDataBinder(例如ServletRequestDataBinder)将您的请求参数绑定到匹配名称的bean属性。

由于没有与您的bean属性req匹配的请求参数,因此永远不会设置该字段。即使您的请求中存在名称为req的请求参数,它也不会转换为HttpServletRequest。

要接收实际请求,请在您的处理程序方法

中添加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
 }

如果您不想将自己绑定到Servlet API,请使用WebRequest类型的参数。