Java Spring在处理之前更改响应

时间:2016-08-03 13:00:48

标签: java spring spring-mvc servlet-filters interceptor

好的,我一直在尝试实现一个系统,其中在检查请求上的参数后,如Path,我将实际修改响应以回答不同的数据。想法是创建后端演示功能,这样客户端可以在不实际发出数据库请求的情况下演示(NOT TEST)应用程序。

所以,我的第一次尝试是使用servlet过滤器,可以找到一个非常好的答案here,还有一些名为The Essentials of Filters的好文档。但我无法让它工作,我认为因为我使用带有@Controller和@ResponseBody的spring,即使我遵循完全相同的样本,我也会得到一个null作为wrapperResponse。

然后我尝试了Interceptorshere这是一个很好的例子,一个好的回答here。但问题是通常人们会使用postHandle来修改主体,我真的不希望句柄甚至触发,因为这意味着DB调用也会被触发。如果我将preHandler用作here,那么它只会创建一个新的servlet,而我并不想要它。

最后我尝试@ControllerAdvice,它基本上允许你在发送之前重新编写正文,但同样,处理程序得到处理并且所有数据库调用它。

我的目标是,我不必在每个处理程序中放置重复的代码,我可以让preHandler插入一些额外的头并在@ControllerAdvice中检查该头,但这意味着我必须制作一些IF / ELSE在处理程序中所以它没有得到处理,我必须在系统中的100个@Controllers上重复这个,我想要干。

我非常确定解决方案是以answer

的方式在过滤器上
public void doFilter(ServletRequest request, ServletResponse response,
    FilterChain chain) throws IOException, ServletException {

System.out.println("BEFORE filter");
PrintWriter out = response.getWriter();
CharResponseWrapper responseWrapper = new CharResponseWrapper(
        (HttpServletResponse) response);

chain.doFilter(request, responseWrapper);

String servletResponse = new String(responseWrapper.toString());

out.write(servletResponse + " filtered"); // Here you can change the response


System.out.println("AFTER filter, original response: "
        + servletResponse);

}

但我无法使用spring和@ResponseBody调用。说实话,this并没有回答我的问题。

1 个答案:

答案 0 :(得分:0)

这是我设法做到这一点的方式。

首先我创建了一个拦截器,它实际上过滤了我们想要进行演示的请求。在预处理程序中,我没有尝试使用Response outstream创建响应,而是使用RequestDispatcher将请求转发给新控制器,我称之为Demo控制器。

exports.addStatement = function (db, description, data) {
    return new Promise(function (resolve, reject) {
        validator.validateStatement(description, data)
        .then(function (data) {
            //......
            if(cnd1)
               resolve(res);
            if(cnd2)
               reject(err);
            //......
            //How to check if this promise is rejected or resolved yet? 

        })
        .catch(function (err) {
            reject(err);
        })
    })
};

在演示控制器中,您可以创建想要演示的正确响应。这里的好处是,在新的演示转发请求中将具有原始请求javax.servlet.forward.request_uri的属性,并且您可以在转发之前作为controllerName插入数据。所有这些数据都可以在Demo控制器中提取,以生成所需的数据。

相关问题