- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在使用 Spring @RestController
并以 Json 格式发送响应。这工作正常,但我需要向记录器发送响应,所以我已经实现了 Spring 的 HandlerInterceptor 和
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
System.out.println("--afterCompletion method executed--"+ request.getRequestURL());
System.out.println("--afterCompletion method executed--"+ response.getWriter());
}
获取异常
--afterCompletion方法执行-- http://localhost:8080/login2015-11-29 05:48:29.184错误9116 --- [nio-8080-exec-1] o.s.web.servlet.HandlerExecutionChain:HandlerInterceptor.afterCompletion抛出异常
java.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.catalina.connector.Response.getWriter(Response.java:578) at org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:212) at to.lookup.api.logger.LoggingInterceptor.afterCompletion(LoggingInterceptor.java:32)
最佳答案
您不能在 Spring 拦截器中执行此操作,因为在处理响应的 OutputStream
时,一旦您读取了一部分或一个流,它就会被“消耗”,并且无法返回并再次读取它。
要启用对请求或响应的重新读取,您必须将它们包装起来并在 servlet 过滤器中执行此操作,然后将包装的实现沿着过滤器链传播。
您可以找到一个已经实现的包装器,您可以从中学习,例如spring-mvc-logger 。实现基于TeeInputStream将从 OutputStream
读取的所有字节复制到允许重新读取的辅助 OutputStream
。
发布所使用的ResponseWrapper
类的代码
public class ResponseWrapper extends HttpServletResponseWrapper {
private final ByteArrayOutputStream bos = new ByteArrayOutputStream();
private PrintWriter writer = new PrintWriter(bos);
private long id;
public ResponseWrapper(Long requestId, HttpServletResponse response) {
super(response);
this.id = requestId;
}
@Override
public ServletResponse getResponse() {
return this;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new ServletOutputStream() {
private TeeOutputStream tee = new TeeOutputStream(ResponseWrapper.super.getOutputStream(), bos);
@Override
public void write(int b) throws IOException {
tee.write(b);
}
};
}
@Override
public PrintWriter getWriter() throws IOException {
return new TeePrintWriter(super.getWriter(), writer);
}
public byte[] toByteArray(){
return bos.toByteArray();
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
}
关于java - 已为此响应调用 HandlerInterceptor getOutputStream(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33982515/
我尝试通过 HandlerInterceptorAdapter 记录所有 http 请求: public class LogRequestInterceptor extends HandlerInte
我正在尝试从 HttpServletRequest 记录请求正文,我添加了一个包装器来执行此操作,但在检索它后我仍然得到一个空请求正文。请问我怎么能多次得到尸体呢? public class Logg
我正在使用 Spring @RestController 并以 Json 格式发送响应。这工作正常,但我需要向记录器发送响应,所以我已经实现了 Spring 的 HandlerInterceptor
每个请求是否有一个新的 Spring HandlerInterceptors 实例? 我在 Spring 中有一个拦截器,它有一个类字段。 public class MyInterceptor ext
在一个库项目中(使用 Spring 3.2.4)我定义了多个拦截器。 servlet 配置 xml 文件包含在要导入 Web 应用程序的 jar 中。拦截器用于多个 servlet xml,因为它们应
我知道我们可以将不同的 url 映射到不同的拦截器,或者我们也可以将多个 url 映射到单个拦截器。我只是想知道我们是否也有排除选项。例如,如果我在应用程序中有 50 个 url 映射,除了 1 个映
我正在尝试将 Spring 项目从 XML 转换为 Java 配置,但在 HandlerInterceptors 方面遇到了以下问题: XML 配置(有效): Java Config(
我有一个 HandlerInterceptor,我在 spring applicationContext.xml 文件中定义了它,如下所示 现在
我知道在 JavaEE 中,过滤器可以拦截对 servlet 的任何请求。但 Spring MVC 中的拦截器并不完全相同。如果你看下图,你会发现拦截器出现在 Dispatcher Servlet 之
总的来说,我对 Spring 和 Web 开发非常陌生,所以如果问题看起来很困惑或不完整,请耐心等待...... 我目前正在开发一个 Spring 项目,其中有一个我称之为“requestContex
在为我的应用程序编写拦截器时,我注意到 HandlerInterceptor 和 WebRequestInterceptor here . 我注意到 HandlerInterceptor 的方法接受
美好的一天。我在里面有一个 spring mvc 应用程序和 2 个 Controller 。第一个 Controller (PublicController)可以处理来自所有用户的请求,第二个(Pr
我在 Spring 3.0.6 中使用 @Configuration 来使用依赖注入(inject)而不使用 .xml 定义文件。 我使用混合方法来定义 Controller ,我将它们放在 Disp
HandlerInterceptor Spring 中的 s 现在可以使用 配置为仅在某些 URL 上调用. Servlet 过滤器可以实现相同的功能(日志记录、安全等)。那么应该使用哪一个呢? 我
我正在为我的 Controller 创建一个日志管理器,用于记录其中的每个操作并返回值 我的 Controller 是这样定义的: @Controller @RequestMapping(value=
我正在实现 HandlerInterceptor需要在处理对多个路径的请求之前/之后执行业务逻辑。我想通过模拟请求句柄生命周期来测试拦截器的执行。 以下是拦截器的注册方式:
我创建了一个简单的 WebMVC 应用程序 - 配置了处理程序拦截器。拦截器的职责很简单 - 它应该检查 HttpRequest 中是否存在有效 session - 如果是,则重定向到注册页面。 我遇
我已经设置了一个 Spring HandlerInterceptor 来向 HttpServletRequest 添加一个属性,以便能够从 Controller 读取它,遗憾的是这似乎不起作用,这对我
让我们看一下这个示例代码: @RequestMapping(value = "/", method = RequestMethod.POST) public ResponseEntity update
我目前正在努力正常关闭服务,为此我们需要在启动关闭之前检查所有当前请求是否已完成。这是我的关机处理程序: @Service public class ShutdownHandler implement
我是一名优秀的程序员,十分优秀!