この単純な 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 コントローラーです。
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 ステータス コードは期待どおりではなく (400 ではなく 500)、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
これらはすべて、 、AbstractErrorController
およびなどのクラス/インターフェースを介して処理されますBasicErrorController
(すべて で設定されますErrorMvcAutoConfiguration
)。どうやら、元のリクエスト/および/またはレスポンスが別のものにラップされたURLへのリダイレクトがある/error
ようです。たとえば、リクエストを次のようにデバッグできます。
結果として得られる JSON はDefaultErrorAttributes
、キーの下のリクエストから HTTP ステータス コードを抽出するという Bean を介して生成されることがわかりました"javax.servlet.error.status_code"
。
そして、私はそこで読みました: https://github.com/spring-projects/spring-boot/issues/4694#issuecomment-163597864 (2015 年 12 月):
問題は実際には BasicErrorController にあり、HTML 応答に固有のものです。BasicErrorController.error は、ErrorPageFilter によって設定される javax.servlet.error.status_code 属性を使用して応答ステータスを設定しますが、BasicErrorController.errorHtml はそうしません。これにより、text/html エラー応答のステータスが 200 OK になります。
実際、私の場合、ErrorPageFilter
が呼び出されることはありません。
また、Spring Boot プロジェクトでこの他の問題が見つかりました: https://github.com/spring-projects/spring-boot/issues/20412これは私の問題にかなり関連していますが、まだ解決策は提供されていません。
コントローラーの設計方法に戻ります (これは非常に単純化された例であることを思い出してください): コード 400 を使用して HTTP 応答を取得し、応答としてこの JSON を取得するために、Spring Boot を「カスタマイズ」する方法は次のとおりです。
{
"timestamp": "2020-09-14T07:24:22.061+0000",
"status": 400,
"error": "Bad Request",
"message": "This is my custom 400 Bad Request message",
"path": "/"
}
ありがとう。