zoukankan      html  css  js  c++  java
  • 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/

    今天越懒,明天要做的事越多。
  • 相关阅读:
    使用C#直接修改表结构(添加列,删除列)【MS SQL SEVER】
    Nuget-ConsoleExtClass给控制台添加颜色
    Thread线程Join()的使用
    C#将List集合类转换成DataTable-帮助类
    C#动态拼接Linq
    C#使用AutoMapper
    go GOPROXY=http://goproxy.io 设置
    mysql5.6切到5.7(阿里云RDS换到自建库)
    vue学习之----如何在谷歌浏览器中使用vue调试工具
    vue学习之----兄弟组件之间通信方式
  • 原文地址:https://www.cnblogs.com/fanshuyao/p/15066188.html
Copyright © 2011-2022 走看看