【问题标题】:Trying to get Spring Boot app to send an error response message when request does not have "Content-type" HTTP request header尝试让 Spring Boot 应用程序在请求没有“Content-type”HTTP 请求标头时发送错误响应消息
【发布时间】:2021-12-03 02:13:24
【问题描述】:

我仍然是 Spring Boot 的新手,但我有一个 Web 应用程序,它设置为处理 XML 请求(当请求具有“Content-type: application/xml”标头时)或 JSON 请求(当请求有一个“内容类型:应用程序/xml”标头),我注意到如果“内容类型”标头丢失,或者包含“内容类型:应用程序/xml”或“内容类型”以外的其他内容: application/json”,我收到“415”响应错误代码。日志还显示如下消息:

.w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded' not supported]

我发现了这个较旧的 SO 线程:

Springboot exception handler doesn't catch exception

并且一直在尝试实现由“Sannu”于 2016 年 12 月 17 日 13:55 发布的代码。这是我构建并正在测试的代码(作为测试,我试图将错误响应代码更改为“500”并且还有错误响应消息):

import org.apache.logging.log4j.LogManager;

import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;

import mil.nga.geoaxis.pdp.models.ErrorResponse;

import org.springframework.http.HttpStatus;


@ControllerAdvice  
public class SpringExceptionHandler extends ExceptionHandlerExceptionResolver
{
    @ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
    public ResponseEntity<Object>     handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
{
    ErrorResponse errorResponse = null;
    //ex.printStackTrace();
    errorResponse = new ErrorResponse();
    errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
    System.out.println("In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[" + HttpStatus.INTERNAL_SERVER_ERROR.value() + "]");
    System.out.println("In SpringExceptionHandler.handleControllerException: ex.getMessage()=[" + ex.getMessage() + "]");
    int myCode = errorResponse.getCode();
    System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");

    
    errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
    errorResponse.setMessage(ex.getMessage());

    myCode = errorResponse.getCode();
    System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");

    return new ResponseEntity<Object>(errorResponse, HttpStatus.valueOf(errorResponse.getCode()));
    
}
}

但是,当我测试并发送一个没有“Content-type:”标头的请求(使用 curl)时,我仍然收到看起来是带有“100”响应代码的响应,然后是带有“ 415" 响应代码,没有响应消息。

仅供参考,这是正在出现的日志记录的一部分:

In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[500]
In SpringExceptionHandler.handleControllerException: ex.getMessage()=[Content type 'application/x-www-form-urlencoded' not supported]
In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[0]
In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[500]
WARN 15428 --- [io-18443-exec-1] .m.m.a.ExceptionHandlerExceptionResolver : Failure in @ExceptionHandler      ....errorhandling.SpringExceptionHandler#handleControllerException(HttpMediaTypeNotSupportedException, WebRequest)

谁能指出为什么这似乎无法发送错误代码和响应消息?

[仅供参考,我在 Spring Boot 2.5.6 下执行此操作。]

提前致谢!

吉姆

编辑 1:我根据 huy 的建议修改了这个类:

import org.apache.logging.log4j.LogManager;

import org.springframework.http.ResponseEntity;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;



@ControllerAdvice  
public class SpringExceptionHandler 
{
    @ExceptionHandler(org.springframework.web.HttpMediaTypeNotSupportedException.class)
public ResponseEntity handleControllerException(HttpMediaTypeNotSupportedException ex, WebRequest req)
{
    ErrorResponse errorResponse = null;
    //ex.printStackTrace();
    errorResponse = new ErrorResponse();
    //errorResponse.setCode(HttpCodes.HTTP_CODE_INTERNAL_ERROR);
    System.out.println("In SpringExceptionHandler.handleControllerException: HttpStatus.INTERNAL_SERVER_ERROR.value()=[" + HttpStatus.INTERNAL_SERVER_ERROR.value() + "]");
    System.out.println("In SpringExceptionHandler.handleControllerException: ex.getMessage()=[" + ex.getMessage() + "]");
    int myCode = errorResponse.getCode();
    System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");

    
    errorResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
    errorResponse.setMessage(ex.getMessage());

    myCode = errorResponse.getCode();
    System.out.println("In SpringExceptionHandler.handleControllerException: errorResponse.getCode()/String.valueOf(myCode)=[" + String.valueOf(myCode) + "]");

    return ResponseEntity
            .status(HttpStatus.valueOf(415))
            .body(ex.getMessage());
    
}
}

上面的代码会导致错误代码为 415 的响应,以及来自 HttpMediaTypeNotSupportedException 异常的文本错误消息。

【问题讨论】:

  • 其实不需要扩展ExceptionHandlerException...,默认是用来解决错误的。你只需要ControllerAdvice和ExceptionHandler,ExceptionHandlerExceptionResolver会自动扫描注解ExceptionHandler并进行处理。
  • 喂——你能澄清一下吗?你是说如果我只是创建 SpringExceptionHandler 类(并且它不扩展 ExceptionHandlerExceptionResolver),那么 handleControllerException() 方法将能够成功返回 ResponseEntity 并导致我想要的响应?吉姆
  • extend ExceptionHandlerExceptionResolver 很奇怪,有时可能会导致解析器冲突...我不推荐它...顺便说一下,spring 的默认解析器会自动检测和处理注释 ExceptionHandler.. .
  • huy - 我让它工作(有点),并将使用新/最终代码更新原始帖子。您可以将您的评论更改为答案,以便我可以选择它吗?谢谢!
  • 我添加了答案

标签: java spring-boot


【解决方案1】:

你不需要扩展 ExceptionHandlerException...,它默认用于解决错误。

你只需要ControllerAdvice和ExceptionHandler,ExceptionHandlerExceptionResolver会自动扫描注解ExceptionHandler并进行处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    相关资源
    最近更新 更多