SpringBoot 2.3.0.RELEASE版本后自定义404页面,SpringBoot 404错误兼容Ajax请求

SpringBoot 2.3.0.RELEASE版本后自定义404页面,

SpringBoot 404错误兼容Ajax请求

ErrorController接口无getErrorPath方法

================================

©Copyright 蕃薯耀 2021-07-27

https://www.cnblogs.com/fanshuyao/

一、问题描述

在spring-boot-starter-parent 2.3.0.RELEASE版本后,org.springframework.boot.web.servlet.error.ErrorController接口已经不建议采用getErrorPath方法,在2.5.3版本后,ErrorController接口已经无getErrorPath方法(直接删除)。

查看子类,发现有org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController这个类,默认是:

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

那么就可以通过server.error.path进行配置的覆盖或者通过error.path进行配置覆盖,如果都不配置,就默认是:/error

建议配置成:error.path=/deprecated/error,这样自己就能定义/error的路径

配置error.path能同时覆盖处理页面和Ajax(Rest)请求,配置server.error.path只能覆盖处理页面跳转的请求,不能处理Ajax(Rest)请求,因为ErrorProperties默认是/error,需要通过error.path修改

二、SpringBoot 2.3.0.RELEASE版本后自定义404错误页面

1、创建GlobalErrorController全局错误处理类

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.lqy.common.bean.Result;
 
/**
 *     全局异常处理
 *     在spring-boot-starter-parent 2.3.0.RELEASE版本后,需要在application.properties增加配置:error.path=/deprecated/error,覆盖默认的全局异常处理。
 * <p>2.5.3后,ErrorController接口已经无getErrorPath方法。</p>
 * <p>查看子类,发现有org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController这个类,默认是:</p>
 * <p>@RequestMapping("${server.error.path:${error.path:/error}}")</p>
 * <p>那么就可以通过server.error.path进行配置的覆盖或者通过error.path进行配置覆盖,如果都不配置,就默认是:/error</p>
 * <p>建议配置成:error.path=/deprecated/error,这样自己就能定义/error的路径</p>
 * <p>配置error.path能同时覆盖处理页面和Ajax(Rest)请求,配置server.error.path只能覆盖处理页面跳转的请求,不能处理Ajax(Rest)请求,因为ErrorProperties默认是/error,需要通过error.path修改</p>
 * 
 * <p>在application.properties文件配置error.path=/deprecated/error</p>
 * 
 * @see org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController
 * @see org.springframework.boot.web.servlet.error.ErrorController
 * 
 *
 */
@Controller
@RequestMapping
public class GlobalErrorController {


    public final static String STATUS_CODE = "javax.servlet.error.status_code";
    
    
    /**
     *     获取HTTP请求状态码
     * @param request
     * @return
     */
    public HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        if (statusCode == null) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
        try {
            return HttpStatus.valueOf(statusCode);
        }
        catch (Exception ex) {
            return HttpStatus.INTERNAL_SERVER_ERROR;
        }
    }
    
    
    
    /**
     *     处理html页面请求的错误
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping(value="/error", produces = MediaType.TEXT_HTML_VALUE)
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        Integer statusCode = (Integer) request.getAttribute(STATUS_CODE);
        
        ModelAndView mav = new ModelAndView();
        
        if(statusCode == 401) {
            mav.addObject("statusCode", 401);
            mav.setViewName("error/4xx");
            
        }else if(statusCode == 403) {
            mav.addObject("statusCode", 403);
            mav.setViewName("error/4xx");
            
        }else if(statusCode == 404) {
            mav.addObject("statusCode", 404);
            mav.setViewName("error/404");
            
        }else {
            mav.addObject("statusCode", 500);
            mav.setViewName("error/500");
        }
        
        return mav;
        
    }
    
    
    /**
     *     处理Ajax请求的错误
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping(value="/error")
    @ResponseBody
    public Result error(HttpServletRequest request, HttpServletResponse response) throws IOException {
        
        Integer statusCode = (Integer) request.getAttribute(STATUS_CODE);
        
            
        return Result.failCode(statusCode);
        
    }
    
 
}

2、覆盖默认的错误请求处理

在application.properties文件配置error.path=/deprecated/error

#覆盖默认的全局异常处理路径,配合com.lqy.common.exception.controller.GlobalErrorController使用
error.path=/deprecated/error

三、spring-boot-starter-parent 2.3.0.RELEASE版本之前的自定义异常页面

SpringBoot 自定义异常页面,SpringBoot 自定义404页面和500页面,SpringBoot 错误兼容Ajax请求,见:

https://www.cnblogs.com/fanshuyao/p/14716703.html

(时间宝贵,分享不易,捐赠回馈,^_^)

================================

©Copyright 蕃薯耀 2021-07-27

https://www.cnblogs.com/fanshuyao/

今天越懒,明天要做的事越多。
原文地址:https://www.cnblogs.com/fanshuyao/p/15066188.html