如何使用Spring Boot应用程序修改apache tomcat 9对错误请求的默认响应?

问题描述

我已经使用Spring Boot开发了rest API。 现在,我使用邮递员使用格式错误的网址(如ValueError: in user code: C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\engine\training.py:806 train_function * return step_function(self,iterator) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\engine\training.py:796 step_function ** outputs = model.distribute_strategy.run(run_step,args=(data,)) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:1211 run return self._extended.call_for_each_replica(fn,args=args,kwargs=kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2585 call_for_each_replica return self._call_for_each_replica(fn,args,kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\distribute\distribute_lib.py:2945 _call_for_each_replica return fn(*args,**kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\engine\training.py:789 run_step ** outputs = model.train_step(data) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\engine\training.py:748 train_step loss = self.compiled_loss( C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\engine\compile_utils.py:204 __call__ loss_value = loss_obj(y_t,y_p,sample_weight=sw) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\losses.py:149 __call__ losses = ag_call(y_true,y_pred) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\losses.py:253 call ** return ag_fn(y_true,y_pred,**self._fn_kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\util\dispatch.py:201 wrapper return target(*args,**kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\losses.py:1605 binary_crossentropy K.binary_crossentropy(y_true,from_logits=from_logits),axis=-1) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\util\dispatch.py:201 wrapper return target(*args,**kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\keras\backend.py:4823 binary_crossentropy return nn.sigmoid_cross_entropy_with_logits(labels=target,logits=output) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\util\dispatch.py:201 wrapper return target(*args,**kwargs) C:\anaconda3\envs\tensorflow\lib\site-packages\tensorflow\python\ops\nn_impl.py:173 sigmoid_cross_entropy_with_logits raise ValueError("logits and labels must have the same shape (%s vs %s)" % ValueError: logits and labels must have the same shape ((None,2) vs (None,1)) )发送请求。 我得到的回应是

http://localhost:8080/DD%/jhsj5/

我想修改响应,就像我为NohandlerfoundException修改的一样,如下所示

<!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>

但如果{ "status": 404,"message": "","error": "Invalid url Path" } . 上方的网址行格式错误,则在我的代码中不会引发任何异常。 那么如何处理呢?

解决方法

github issue 对此有异议,它包含 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) {
        }
    }
}