gpt4 book ai didi

spring - 如何强制 Spring Boot 将正确的 HTTP 状态代码设置为错误响应?

转载 作者:行者123 更新时间:2023-12-03 08:09:03 25 4
gpt4 key购买 nike

我制作了这个简单的 Spring Boot 应用示例来展示我在 Spring Boot 默认处理错误的方式方面的问题:

package com.pany.app;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class MyApplication {

public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}

}
这是 Spring Security 配置:
package com.pany.app;

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").anonymous();
}

}
这是 REST Controller :
package com.pany.app;

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.HttpClientErrorException;

@RestController
public class MyController {

@GetMapping(path = "/", produces = { "application/json" })
public void home() {
throw new HttpClientErrorException(HttpStatus.BAD_REQUEST, "This is my custom 400 Bad Request message");
}

}
现在,使用 Spring Boot 2.1.8.RELEASE , 调用 URL http://localhost:8080/ 时我收到带有 500 代码的 HTTP 响应和以下 JSON 响应:
{
"timestamp": "2020-09-14T07:24:22.061+0000",
"status": 500,
"error": "Internal Server Error",
"message": "400 This is my custom 400 Bad Request message",
"path": "/"
}
然而,HTTP 状态代码与预期不同(500 而不是 400),以及 JSON 中的各种字段(“状态”、“错误”、“消息”,前面有意外的“代码”)。
我还用 Spring Boot 2.3.3.RELEASE 对此进行了测试...现在它甚至不再像以前那样工作了!!
{
"timestamp": "2020-09-14T07:34:23.154+00:00",
"status": 500,
"error": "Internal Server Error",
"message": "",
"path": "/"
}
所有这些都是通过 ErrorController 等类/接口(interface)处理的。 , AbstractErrorControllerBasicErrorController (全部设置在 ErrorMvcAutoConfiguration 中)。显然有一个重定向到 URL /error将原始请求/和/或响应包装到其他内容中,例如我可以像这样调试我的请求:
SecurityContextHolderAwareRequestWrapper[FirewalledRequest[org.apache.catalina.core.ApplicationHttpRequest@3751bea4]]
我发现我得到的 JSON 是通过一个名为 DefaultErrorAttributes 的 bean 生成的。它从关键字 "javax.servlet.error.status_code" 下的请求中提取 HTTP 状态代码.
我在那里读到: https://github.com/spring-projects/spring-boot/issues/4694#issuecomment-163597864 (2015 年 12 月):

The problem's actually in BasicErrorController and is specific to HTML responses. BasicErrorController.error sets the response status using the javax.servlet.error.status_code attribute that's set by ErrorPageFilter, but BasicErrorController.errorHtml does not. This results in text/html error responses have a status of 200 OK.


事实上,就我而言, ErrorPageFilter永远不会被调用。
在 Spring Boot 项目中还发现了另一个问题: https://github.com/spring-projects/spring-boot/issues/20412这与我的问题非常相关,但仍然没有提供解决方案。
回到我的 Controller 的设计方式(记住这只是一个极其简化的示例):如何“自定义”Spring Boot 以获得带有代码 400 的 HTTP 响应和此 JSON 作为响应:
{
"timestamp": "2020-09-14T07:24:22.061+0000",
"status": 400,
"error": "Bad Request",
"message": "This is my custom 400 Bad Request message",
"path": "/"
}
谢谢。

最佳答案

@Controlleradvice 的简单替代方案有如下自定义异常

@Slf4j
@ResponseStatus(HttpStatus.NOT_FOUND)
public class NotFoundException extends RuntimeException{

public NotFoundException(String message) {
super(message);
log.warn(message);
}

}
将所需的 Http 代码与 @ResponseStatus 一起使用注解。
并在需要时抛出此异常
throw new NotFoundException("Your message for not found goes here");

关于spring - 如何强制 Spring Boot 将正确的 HTTP 状态代码设置为错误响应?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63880627/

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