哈尔滨企业制作网站,lnmpa安装wordpress,网站后台上传文件,企业网站建设 新天地网络这个错误通常表明您尝试从Spring MVC返回一个已使用的HttpServletResponse对象。 原因#xff1a;这可能是由于直接调用HttpServletResponse的getWriter()或getOutputStream()方法#xff0c;或者由于在控制器方法中抛出异常而自动调用HttpServletResponse的write()方法。 修… 这个错误通常表明您尝试从Spring MVC返回一个已使用的HttpServletResponse对象。 原因这可能是由于直接调用HttpServletResponse的getWriter()或getOutputStream()方法或者由于在控制器方法中抛出异常而自动调用HttpServletResponse的write()方法。 修改建议您可以确保在控制器方法中没有调用任何HttpServletResponse的方法并且不要在控制器方法中抛出异常。 规避建议如果需要向客户端返回响应请使用返回相应的对象例如String、 ModelAndView或RedirectView。 此外您还可以使用ResponseStatus和ExceptionHandler注解来处理异常情况并生成适当的响应。
问题重现
ResponsePostInterceptor 里注入response.getWriter().write
package com.zhangziwa.practisesvr.interceptor;import com.zhangziwa.practisesvr.utils.response.ResponseContext;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;Component
public class ResponsePostInterceptor implements HandlerInterceptor {# 调用 response.getWriter().writeOverridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.err.println(***ResponsePostInterceptor.preHandle***);response.setHeader(test-test, test-test);response.getWriter().write(Response content);response.flushBuffer();return true;}Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.err.println(***ResponsePostInterceptor.postHandle***);}Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.err.println(***ResponsePostInterceptor.afterCompletion***);ResponseContext.clear();}
}Controller 正常返回 ResponseEntity RequestMapping(value /getAllStudents4, method RequestMethod.GET)public ResponseEntityListStudent getAllStudents4() {System.err.println(***Controller.getAllStudents4***);ListStudent students userService.listStudents3(1, 5);HttpHeaders httpHeaders new HttpHeaders();httpHeaders.add(test, test);return ResponseEntity.ok().headers(httpHeaders).contentType(MediaType.APPLICATION_JSON).body(students);}ResponseBodyAdvice 对 ResponseEntity进行增强
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import static java.util.Objects.nonNull;ControllerAdvice
public class ResponsePostAdvice implements ResponseBodyAdvice {Overridepublic boolean supports(MethodParameter returnType, Class converterType) {System.err.println(***ResponsePostAdvice.supports***);return true;}Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class clazz, ServerHttpRequest request, ServerHttpResponse response) {System.err.println(***ResponsePostAdvice.beforeBodyWrite***);HttpHeaders headers response.getHeaders();// 分页信息添加到ServerHttpResponseHttpHeaders headersContext ResponseContext.getHeaders();if (nonNull(headersContext) !headersContext.isEmpty()) {headersContext.forEach((key, values) - values.forEach((value) - {headers.addIfAbsent(key, value);}));}// 状态码添加到ServerHttpResponseif (nonNull(ResponseContext.getResponseCode())) {response.setStatusCode(ResponseContext.getResponseCode());}# 这里会报错return body;}
}异常拦截GlobalExceptionHandler
ControllerAdvice
public class GlobalExceptionHandler {ExceptionHandler(Exception.class)ResponseBodypublic ResponseEntityString handleException(Exception ex) {System.err.println(***GlobalExceptionHandler.handleException: ex.getMessage() ***);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(An error occurred);}ExceptionHandler(NotFoundException.class)public ResponseEntityString handleNotFoundException(NotFoundException ex) {System.err.println(***GlobalExceptionHandler.handleNotFoundException***);return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Resource not found);}
}调用路径分析
# 拦截器的preHandle 这里注入了response.getWriter().write
***ResponsePostInterceptor.preHandle***
# Controller层
***Controller.getAllStudents4***# ResponsePostAdvice进行增强后返回ServerHttpResponse
***ResponsePostAdvice.supports***
***ResponsePostAdvice.beforeBodyWrite***
## 这里报IllegalStateException了 被 ControllerAdvice修饰的GlobalExceptionHandler 拦截到
***GlobalExceptionHandler.handleException:getWriter() has already been called for this response***# 异常返回ResponseEntity 又被ResponsePostAdvice捕捉然后进行增强
***ResponsePostAdvice.supports***
***ResponsePostAdvice.beforeBodyWrite***
# 又报IllegalStateException但是此时没被GlobalExceptionHandler 拦截
java.lang.IllegalStateException: getWriter() has already been called for this response
# 吃啥程序蹦了故ResponsePostInterceptor.postHandle未执行。但是afterCompletion是否异常都会执行所以执行了
***ResponsePostInterceptor.afterCompletion***# 这里又执行一遍拦截器但是未进入Controller层不是很懂
***ResponsePostInterceptor.preHandle***
***ResponsePostInterceptor.postHandle***
***ResponsePostInterceptor.afterCompletion***