gpt4 book ai didi

java - Spring @ExceptionHandler 和 HttpMediaTypeNotAcceptableException

转载 作者:IT老高 更新时间:2023-10-28 13:59:29 27 4
gpt4 key购买 nike

我有一个用 @ControllerAdvice 注释的类,其中有这个方法:

@ExceptionHandler(ResourceNotFoundException.class)
@ResponseStatus(HttpStatus.NOT_FOUND)
@ResponseBody
public ExceptionInfo resourceNotFoundHandler(ResourceNotFoundException ex) {
List<ErrorContent> errors = new ArrayList<>();
errors.add(new ErrorContent(ExceptionsCodes.NOT_FOUND_CODE, null,
"test"));
return fillExceptionInfo(HttpStatus.NOT_FOUND, errors, ex);
}

这里是fillExceptionInfo:

public ExceptionInfo fillExceptionInfo(HttpStatus status, List<ErrorContent> errors, 
Exception ex) {
String msg = ex.getMessage();

return new ExceptionInfo(status.toString(), errors, (msg != null && !msg.equals(""))
? ex.getMessage()
: ExceptionUtils.getFullStackTrace(ex));
}

当 web 客户端发送一些 json 数据的请求,但无法找到时,此方法可以正常工作。但是,当服务器收到图像请求时,会抛出 HttpMediaTypeNotAcceptableException 而不是我的异常。我知道这是由于内容类型错误造成的,但我该如何解决这个问题?

更新

我的目标是在 json 数据和文件两种情况下都抛出 ResourceNotFoundException

我得到的异常(所以它是从 AbstractMessageConverterMethodProcessor 抛出的):

ERROR o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - doResolveHandlerMethodException - Failed to invoke @ExceptionHandler method: public com.lia.utils.GlobalExceptionHandler$ExceptionInfo com.lia.utils.GlobalExceptionHandler.resourceNotFoundHandler(com.lia.app.controllers.exceptions.ResourceNotFoundException) 
org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:168) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:101) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:198) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71) ~[spring-web-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver.doResolveHandlerMethodException(ExceptionHandlerExceptionResolver.java:362) ~[spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerMethodExceptionResolver.doResolveException(AbstractHandlerMethodExceptionResolver.java:60) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver.resolveException(AbstractHandlerExceptionResolver.java:138) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processHandlerException(DispatcherServlet.java:1167) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1004) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:955) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) [spring-webmvc-4.1.1.RELEASE.jar:4.1.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:717) [jetty-servlet-9.1.1.v20140108.jar:9.1.1.v20140108]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1644) [jetty-servlet-9.1.1.v20140108.jar:9.1.1.v20140108]
....

最佳答案

问题在于请求的内容类型和返回的对象不兼容。见 my response关于如何配置 ContentNegotiationConfigurer 以便 Spring 根据您的需要确定请求的内容类型(查看路径扩展、URL 参数或 Accept header )。

根据请求内容类型的确定方式,当客户端请求图像时,您有以下选项:

  • 如果请求的内容类型由 Accept header 确定,并且如果客户端可以/想要处理 JSON 响应而不是图像数据,则客户端应使用 接受:图像/*、应用程序/json。这样,Spring 就知道它可以安全地返回图像字节数据或错误 JSON 消息。
  • 在任何其他情况下,您最好的解决方案是只返回 HTTP 错误代码,而不返回任何错误消息。您可以在 Controller 中通过以下几种方式做到这一点:

直接在响应上设置错误码

public byte[] getImage(HttpServletResponse resp) {
try {
// return your image
} catch (Exception e) {
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}

使用ResponseEntity

public ResponseEntity<?> getImage(HttpServletResponse resp) {
try {
byte[] img = // your image
return ReponseEntity.ok(img);
} catch (Exception e) {
return new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR);
}
}

在那个 Controller 中使用一个单独的@ExceptionHandler方法,它会覆盖默认的Spring异常处理。这假设您有一个用于图像请求的专用异常类型或一个单独的 Controller 仅用于提供图像。否则,异常处理程序也会处理来自该 Controller 中其他端点的异常。

关于java - Spring @ExceptionHandler 和 HttpMediaTypeNotAcceptableException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32123540/

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