如何在将请求体传递给Controller之前对其进行预处理?

时间:2012-04-23 18:55:51

标签: java spring servlets servlet-filters

我正在实现一个RESTful服务,我希望在拦截器上对XSD进行验证,然后再将其传递给CastorUnmarshaller。 虽然,在WebRequestInterceptor我必须读取只能读取一次的请求体,因此unmarshaller无法读取它。有办法吗?

我知道我可以在Controller中手动执行验证和解组,但是我想使用@RequestBody <DomainObject>方法来取消它。

或者,作为另一种解决方案,有没有办法告诉CastorUnmarshaller针对xsd验证它?

3 个答案:

答案 0 :(得分:0)

您可以附加@Before方面(spring AOP)。在那里,您可以获得与传递给控制器​​方法相同的请求体参数。

另一种选择是将请求包装成一个支持多次读取主体的请求(通过第一次缓存它)

答案 1 :(得分:0)

过滤器也可用于验证传递的XML。 org.springframework.oxm.castor.CastorMarshaller 具有验证属性,可以对正在进行的文档进行验证。 但是必须解决在Spring-MVC的默认编组器中启用它的问题。

答案 2 :(得分:0)

很长一段时间过去了,但其他人可能从中受益:

您可以定义@Around方面并拦截传入的请求及其各自的主体,如下所示:

@Aspect
@Component
public class RequestResponseLoggingAdvice {

    private static final Logger logger = LoggerFactory.getLogger(RequestResponseLoggingAdvice.class);

    @Pointcut("within(@org.springframework.web.bind.annotation.RestController*)") 
    public void restcontroller() {}

    @Pointcut("@annotation(org.springframework.web.bind.annotation.PostMapping)") 
    public void postmapping() {}

    @Around("restcontroller() && postmapping() && args(.., @RequestBody body, request)") 
    public Object logPostMethods(ProceedingJoinPoint joinPoint, Object body, HttpServletRequest request) throws Throwable {
        logger.debug(request.toString()); // You may log request parameters here.
        logger.debug(body.toString()); // You may do some reflection here

        Object result;
        try {
            result = joinPoint.proceed();
            logger.debug(result.toString());
        } catch(Throwable t) {}
    }
}

请注意,您的REST控制器方法必须具有适合上述方面的签名。示例可以如下:

@PostMapping
public SampleDTO saveSample(@RequestBody Sample sample, HttpServletRequest request) { 
    //.....
}