как изменить ответ по умолчанию, выдаваемый apache tomcat 9 на неверный запрос, используя приложение spring boot?

#spring-boot #error-handling #tomcat9 #bad-request

#spring-boot #обработка ошибок #tomcat9 #неверный запрос

Вопрос:

Я разработал rest API с использованием spring boot. Теперь я отправляю запрос, используя неверно сформированный URL, например http://localhost:8080/DD%/jhsj5/ , от postman. Я получаю ответ как

 <!doctype html>
<html lang="en"><head><title>HTTP Status 400 – Bad Request</title>
<style type="text/css">
    body {font-family:Tahoma,Arial,sans-serif;} 
    h1, h2, h3, b {color:white;background-color:#525D76;} 
    h1 {font-size:22px;} 
    h2 {font-size:16px;} 
    h3 {font-size:14px;} 
    p {font-size:12px;} 
    a {color:black;} 
    .line {height:1px;background-color:#525D76;border:none;}
</style>
</head>
<body>
    <h1>HTTP Status 400 – Bad Request</h1>
</body>
</html>
  

Я хочу изменить ответ, подобный тому, который я изменил для NohandlerfoundException, как показано ниже

 {
    "status": 404,
    "message": "",
    "error": "Invalid url Path"
} .
  

но в случае неправильно сформированной строки URL выше http://localhost:8080/DD%/jhsj5/ , в моем коде не возникает исключения.
итак, как с этим справиться?

Ответ №1:

Для этого была создана проблема с github, и она содержит следующую работу, опубликованную sc-moonlight :

  @Bean
public TomcatWebSocketServletWebServerCustomizer errorValveCustomizer() {
    return new TomcatWebSocketServletWebServerCustomizer() {
        @Override
        public void customize(TomcatServletWebServerFactory factory) {
            factory.addContextCustomizers((context) -> {
                Container parent = context.getParent();
                if ( parent instanceof StandardHost) {
                    ((StandardHost) parent).setErrorReportValveClass("aaa.bbb.ccc.configuration.CustomTomcatErrorValve");
                }
            });
        }
        @Override
        public int getOrder() {
            return 100; // needs to be AFTER the one configured with TomcatWebServerFactoryCustomizer
        }
    };
}
  

и

 package aaa.bbb.ccc;

public class CustomTomcatErrorValve extends ErrorReportValve{
    private static final Logger LOGGER = LoggerFactory.getLogger(CustomTomcatErrorValve.class);
    protected void report(Request request, Response response, Throwable throwable) {
        if  (!response.setErrorReported())
            return;
        LOGGER.warn("{} Fatal error before getting to Spring. {} ", response.getStatus(), errorCode, throwable);
        try {
            Writer writer = response.getReporter();
            writer.write(Integer.toString(response.getStatus()));
            writer.write(" Fatal error.  Could not process request.");
            response.finishResponse();
        } catch (IOException e) {
        }
    }
}