Spring Boot 2.X
错误信息如下:
org.springframework.http.converter.HttpMessageNotWritableException: No converter for [xxxx] with preset Content-Type 'text/plain;version=0.0.4;charset=utf-8' at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:312) at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:181) at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:78) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:124) at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:428) at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:75) at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:141) at org.springframework.web.servlet.handler.HandlerExceptionResolverComposite.resolveException(HandlerExceptionResolverComposite.java:80) at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1323) at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1134) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1080) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) at javax.servlet.http.HttpServlet.service(HttpServlet.java:655) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
例如上述错误信息,项目出现了某种异常,并且响应对象设置了响应头,如: Content-Type ‘text/plain;version=0.0.4;charset=utf-8’。
当内部抛出了异常后,项目中的全局异常处理返回了一个通用的实体对象,是JSON格式,和响应头的Content-Type不一致,导致SpringMVC在转换的时候报此类错误。
问题出现场景:
一般出现在,文件下载接口的实现上;
或者,程序内部抛出:ClientAbortException: java.io.IOException: 断开的管道
适合场景:返回格式只需兼容的情况
手动指定响应头,设置兼容其它格式,例如:
@PostMapping(value = "xxxx", produces = {MediaType.APPLICATION_OCTET_STREAM_VALUE, MediaType.APPLICATION_JSON_VALUE})
适合场景:文件下载接口等
解决:原来有返回值的话,修改为返回void。因为文件下载接口,一般是借助HttpServletResponse对象来直接返回的。
解决:在全局异常的处理中,加上下面的逻辑:
@ControllerAdvice @Slf4j public class GlobalExceptionHandler { public static final String CLIENT_ABORT_EXCEPTION_CLASS = "org.apache.catalina.connector.ClientAbortException"; @ExceptionHandler(Exception.class) public void handleException(Exception e, HttpServletResponse response) { if (CLIENT_ABORT_EXCEPTION_CLASS.equals(e.getClass().getName())) { log.warn("出现ClientAbortException"); return; }; log.error("全局异常信息:{}", e.getMessage(), e); } }