gpt4 book ai didi

java - 已为此响应调用 HandlerInterceptor getOutputStream()

转载 作者:太空宇宙 更新时间:2023-11-04 13:10:42 24 4
gpt4 key购买 nike

我正在使用 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com