好的,我一直在尝试实现一个系统,其中在检查请求上的参数后,如Path,我将实际修改响应以回答不同的数据。想法是创建后端演示功能,这样客户端可以在不实际发出数据库请求的情况下演示(NOT TEST)应用程序。
所以,我的第一次尝试是使用servlet过滤器,可以找到一个非常好的答案here,还有一些名为The Essentials of Filters的好文档。但我无法让它工作,我认为因为我使用带有@Controller和@ResponseBody的spring,即使我遵循完全相同的样本,我也会得到一个null作为wrapperResponse。
然后我尝试了Interceptors,here这是一个很好的例子,一个好的回答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并没有回答我的问题。
答案 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控制器中提取,以生成所需的数据。