1. 程式人生 > 實用技巧 >spring boot freemarker 500異常跳轉自定義錯誤頁

spring boot freemarker 500異常跳轉自定義錯誤頁

專案環境

  使用idea + maven + springboot 搭建的專案。

需求

跳轉自定義錯誤頁。三方系統連結。

問題

  遇到問題是spring 定義的全域性異常捕捉不到 freemarker 模板渲染時候的異常。

1)嘗試AOP的異常通知進行 捕獲失敗( @ControllerAdvice+@ExceptionHandler(Exception.class)

2)嘗試繼承HandlerExceptionResolver 捕獲失敗

解決方案

一、使用web.xml的方式,配置error-page 節點

1)配置檔案增加自定義的freemarker 錯誤處理類

spring:
  freemarker:
    settings:
     template_exception_handler: xxx.web.exception.FreemarkerExceptionHandler

類定義如下:

class MyTemplateExceptionHandler implements TemplateExceptionHandler {  
     public void handleTemplateException(TemplateException te, Environment env, java.io.Writer out)  
    throws TemplateException {  
        try {  
            out.write("[ERROR: " + te.getMessage() + "]");  
        } 
catch (IOException e) { throw new TemplateException("Failed to print error message. Cause: " + e, env); } } }

2)然後再web.xml配置捕獲異常跳轉到對應的url,配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <error-page> <error-code>404</error-code> <location>/404.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/500.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/error.jsp</location> </error-page> <!-- 優先順序: 頁面中配置<%@page contentType="text/html; charset=UTF-8" errorPage="/2.jsp"%> > exception-type配置的頁面 > error-code配置的頁面 --> </web-app>

二、使用Spring Boot預設的對映處理

1)同 第一種處理方式,略

2)定義捕捉 /error 路徑的ErrorController

Spring Boot提供了一個預設的對映:/error,當處理中丟擲異常之後,會轉到該請求中處理,並且該請求有一個全域性的錯誤頁面用來展示異常內容。

import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping(value = "error")
public class CustomErrorController implements ErrorController {

    @Override
    public String getErrorPath() {
        return "error40x";//這是個我自己寫的404的頁面的fileName,在template根目錄下
    }
    
    @RequestMapping
    public String error() {
        return getErrorPath();
    }

}

或者

@Controller
@RequestMapping({"${server.error.path:${error.path:/error}}"})
public class BasicErrorController extends AbstractErrorController {

      /**
       * 錯誤的頁面響應 
       */
    @RequestMapping(produces = {"text/html"})
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = this.getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
          // 得到一個modelAndView物件
        ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
        return modelAndView != null ? modelAndView : new ModelAndView("error", model);
    }
        
  /**
   * 錯誤的json響應
   */
    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        HttpStatus status = this.getStatus(request);
        if (status == HttpStatus.NO_CONTENT) {
            return new ResponseEntity(status);
        } else {
            Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
            return new ResponseEntity(body, status);
        }
    }
}

三、模板引擎 預設有錯誤頁的配置

1)同 第一種處理方式,略

2)在templates建立/error資料夾並新增錯誤的狀態碼對應的.html檔案

專案中使用的了模板引擎,如:thymeleaf 、freemarker等做為頁面的渲染時。在templates建立/error資料夾並新增錯誤的狀態碼對應的.html檔案,如下圖:

3)檔案中做二次跳轉

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    window.location.href="//xxxx/xxx";
</script>
</body>
</html>

參考

https://juejin.im/post/6844904135259602952

https://www.codetd.com/article/3038444

https://juejin.im/post/6844904135259602952

https://blog.csdn.net/lh87270202/article/details/79925951