6

我正在使用 Spring 的@RequestBody注释将我的请求的 JSON POST 数据映射到一个对象中MappingJacksonHttpMessageConverter。但是在那之后,我想读取String表单中的数据以进行一些额外的身份验证。但是当编组发生时,InputStreaminHttpServletRequest是空的。一旦我@RequestBody从方法中删除参数,将 POST 数据读入 aString就可以按预期工作。

我是否必须通过放弃@RequestBody并以某种方式手动进行绑定来妥协,还是有更优雅的解决方案?

4

3 回答 3

2

所以,基本上你需要计算请求体的哈希值。优雅的方法是将装饰器应用于InputStream.

例如,在处理程序方法内部(在这种情况下您不能使用@RequestBody并且需要HttpMessageConverter手动创建):

@RequestMapping(...)
public void handle(HttpServletRequest request) throws IOException {
    final HashingInputStreamDecorator d = 
        new HashingInputStreamDecorator(request.getInputStream(), secretKey);
    HttpServletRequest wrapper = new HttpServletRequestWrapper(request) {
        @Override
        public ServletInputStream getInputStream() throws IOException {
            return d;
        }
    };

    HttpMessageConverter conv = ...;
    Foo requestBody = (Foo) conv.read(Foo.class, new ServletServerHttpRequest(wrapper));
    String hash = d.getHash();

    ...
}

其中哈希是在 的覆盖read方法中增量计算的HashingInputStreamDecorator

@RequestBody如果您创建一个Filter来应用装饰器,您也可以使用。在这种情况下,装饰器可以将计算出的哈希作为请求属性传递给处理程序方法。但是,您需要仔细映射此过滤器以将其仅应用于特定处理程序方法的请求。

于 2010-11-04T14:34:16.693 回答
0

在您的 urlMapping bean 中,您可以声明其他拦截器列表:

  <bean id="urlMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
    <property name="interceptors">
      <list>
        <bean class="org.foo.MyAuthInterceptor"/>
      </list>
    </property>
  </bean>

这些拦截器可以访问 HttpServletRequest,但如果您从流中读取,则参数映射器可能无法读取它。

public class AuthInterceptor extends HandlerInterceptorAdapter {

  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    ...
  }

  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView mav) {
    ...
  }
}
于 2010-11-04T13:24:16.230 回答
0

如果我理解正确,与 JAX-RS 一起使用的一种常用方法(在绑定请求方面有点类似于 Spring MVC)是首先“绑定”到一些中间原始类型(通常是字节 [],但字符串也可以) , 并使用底层数据绑定器 (Jackson) 手动将其绑定到对象。我经常这样做是为了能够完全自定义数据绑定的错误处理。

于 2010-11-17T00:13:01.850 回答