[英]How to send custom response for 400, 401, 405, 403 and 500 errors in spring boot?
我想在 spring 引导中针对 400、401、405、403 和 500 错误发送自定义 JSON 响应。 对于这些错误 spring 启动有时会发送 HTML 响应,有时会发送空响应正文响应,有时会发送带有时间戳、异常、消息等的完整响应。我想要一个单一且一致的 Z0ECD11C1D7A287401D148A23BBD7 响应,例如所有这些错误的响应,
{
statusCode : 405,
message: "HTTP Method not allowed"
}
我使用@ControllerAdvice
为很多异常发送自定义响应。 这些 400、401、405、403 和 500 错误我面临的问题是我不知道当这些错误发生时会引发哪些异常,以便我可以为它们编写@ExceptionHandlers
。 即使我不知道这是否可能,或者即使可能,但它是实现这一点的正确方法。
有没有办法在 Spring 引导中实现这一点?
所有传出异常都由 Spring Boot with BasicErrorController
处理。
我们可以使用 controller 建议来处理/更改大多数异常消息。 但是,在到达 controller 之前抛出的异常,如NotFound
、 BadRequest
等,再次由BasicErrorController
处理
我们也可以通过覆盖BasicErrorController
来改变它。
@RestController
@RequestMapping({"${server.error.path:${error.path:/error}}"})
@Slf4j
public class BasicErrorControllerOverride extends AbstractErrorController {
public BasicErrorControllerOverride(ErrorAttributes errorAttributes) {
super(errorAttributes);
}
@RequestMapping
public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
HttpStatus status = this.getStatus(request);
Map<String, Object> errorCustomAttribute = new HashMap<>();
errorCustomAttribute.put("custome_message", "error");
errorCustomAttribute.put("custom_status_field", status.name());
return new ResponseEntity(errorCustomAttribute, status);
}
@Override
public String getErrorPath() {
return "/error";
}
}
错误消息现在将更改为如下所示
{
"custome_message": "UNAUTHORIZED",
"custom_status_field": "error"
}
Spring ResponseEntity 可用于此目的 -
return new ResponseEntity<>("Hello World!", HttpStatus.OK);
参考这个链接; https://www.baeldung.com/spring-response-entity
好吧,即使您不使用 spring,也有一些简单的做法,例如让您的所有响应类都从基础 class 扩展,就像这样,只是一个例子 -
public class StandardResponse{
private int httpStatus;
//getters and setters
}
public class ProductResponse extends StandardResponse{
// product specific data
}
您可以使用 @ControllerAdvice 和 application/problem+json ( zalando/problem是一个很好的 java 实现)
以与 gaetan224 建议的类似方式,您可以使用 @ControllerAdvice 添加 controller 以自定义方式处理异常:
@ControllerAdvice
@RequestMapping(produces = "application/json")
@ResponseBody
public class RestControllerAdvice {
@Autowired
Environment env;
@ExceptionHandler(NoHandlerFoundException.class)
public ResponseEntity<?> unhandledPath(final NoHandlerFoundException e) {
//This is for 405 METHOD NOT ALLOWED
//Here you may want to return a ResponseEntity with a custom POJO as body.
}
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseEntity<?> methodNotAllowed(final HttpRequestMethodNotSupportedException e) {
//This is for 404 NOT FOUND
//Here you may want to return a ResponseEntity with a custom POJO as body.
}
}
在 Spring Security 中处理 403 UNAUTHORIZED 时,情况会有所不同。 您必须编写一个实现 AccessDeniedHandler 接口的@Component。 像这样的东西:
@Component
public class AccessEntryPoint implements AccessDeniedHandler {
@Override
public void handle(HttpServletRequest req,
HttpServletResponse res,
AccessDeniedException accessDeniedException) throws IOException, ServletException {
ObjectMapper mapper = new ObjectMapper();
res.setContentType("application/json;charset=UTF-8");
res.setStatus(403);
res.getWriter().write( /*Your custom object may go here*/ );
}
}
但这还不够,您还必须使用以下方法在 WebSecurityConfigureAdapter 实现中设置自定义 AccessDeniedHandler 实现:
@Autowired
AccessEntryPoint accessDeniedHandler;
并将以下内容附加到您的配置方法调用链中:
.exceptionHandling().accessDeniedHandler(accessDeniedHandler).and()
编辑:我忘了添加,为了使 404 自定义处理程序工作,您必须在 application.properties 文件中添加这两行:
spring.resources.add-mappings=false
spring.mvc.throw-exception-if-no-handler-found=true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.