SpringBoot下MVC整合后统一错误Html页面(404/500)

2021-08-07 741点热度 1人点赞 0条评论

需求

之前的文章有介绍如何在SpringBoot下MVC整合(包含JSP页面以及JSTL),详见:https://blog.terrynow.com/2021/07/07/springboot-mvc-jsp-and-jstl-implment/

我们还需要为它设计统一的错误页面

实现

  • 首先,修改application.properties
# SpringBoot自带一个简易的错误页面,我们将它禁用
server.error.whitelabel.enabled=false
spring.mvc.throw-exception-if-no-handler-found=true
spring.resources.add-mappings=false
  • 新建GlobalExceptionHandler.java,全局错误处理逻辑
@RestControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {

    private static final Log log = LogFactory.getLog(GlobalExceptionHandler.class);


//    @Override
//    protected ResponseEntity<Object> handleNoHandlerFoundException(NoHandlerFoundException ex, HttpHeaders headers,
//                                                                   HttpStatus status, WebRequest request) {
////        response.setStatus(httpStatus.value());
//        log.warn("request no handler found for: " + request.getDescription(true));
//        Map<String, Object> responseBody = new HashMap<>();
//        responseBody.put("result", false);
//        responseBody.put("path", request.getDescription(true));
//        responseBody.put("time", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
//        responseBody.put("message", "The URL you have reached is not in service at this time (404).");
//        return new ResponseEntity<>(responseBody, HttpStatus.NOT_FOUND);
//    }

    @ExceptionHandler(Throwable.class)
    public ModelAndView exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) {
        //If exception has a ResponseStatus annotation then use its response code
        ResponseStatus responseStatusAnnotation = AnnotationUtils.findAnnotation(ex.getClass(), ResponseStatus.class);

        return buildModelAndViewErrorPage(request, response, ex, responseStatusAnnotation != null ?
                responseStatusAnnotation.value() : HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @RequestMapping("*")
    public ModelAndView fallbackHandler(HttpServletRequest request, HttpServletResponse response) throws Exception {
        return buildModelAndViewErrorPage(request, response, null, HttpStatus.NOT_FOUND);
    }

    private ModelAndView buildModelAndViewErrorPage(HttpServletRequest request, HttpServletResponse response,
                                                    Exception ex, HttpStatus httpStatus) {
        log.error("request handle error for: " + request.getRequestURI() + ", ip: " + Utils.getIpAddr(request) +
                ", status: " + httpStatus.value(), ex);
        String exMessage = ex.getMessage();
        if (ex != null && exMessage.startsWith("410 ")) {
            try {
                response.sendError(410, ex.getMessage());
            } catch (IOException ignored) {
            }
        }else{
            try {
                response.sendError(500, ex.getMessage());
            } catch (IOException ignored) {
            }
        }

        ModelAndView mav = new ModelAndView("error");
        mav.addObject("exception", ex);
        mav.addObject("content", request.getRequestURL());
        return mav;
    }

}
  • 设计自己需要的错误页面error.jsp

以下是示例,可以根据自己的需求修改

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>

<html>
<head>
    <meta charset="utf-8">
    <title>错误</title>
    <link rel="stylesheet" type="text/css" href="assets/css/iview.css">
    <link rel="stylesheet" type="text/css" href="assets/css/index.css">
    <script type="text/javascript" src="assets/js/vue.min.js"></script>
    <script type="text/javascript" src="/assets/js/iview.min.js"></script>
    <style type="text/css">

    </style>
</head>

<body>
<div id="app">
    <layout class="m-layout">
        <jsp:include page="header.jsp" />
        <layout class="m-content">
            <jsp:include page="menu.jsp" />
            <layout class="right-content">
                <row class="top-bc">
                    <i-col span="12">
                        <h2>
                            错误
                        </h2>
                    </i-col>
                    <i-col span="12" style="text-align: right;">
                        <breadcrumb>
                            <breadcrumb-item><a href="${base}"><icon type="md-home" :size="18"></icon> 首页</a></breadcrumb-item>
                            <breadcrumb-item>错误</breadcrumb-item>
                        </breadcrumb>
                    </i-col>
                </row>
                <i-content class="main-content">
                    <alert type="error" show-icon>
                        错误 <c:out value="${requestScope['javax.servlet.error.status_code']}" />
                        <span slot="desc">
                            <c:if test="${content !=null}">
                                <p>${content}</p>
                            </c:if>

                                <c:if test="${exception.message !=null}">
                                    ${exception.message}
                                </c:if>
                                <c:if test="${exception.message ==null}">
                                    错误了!
                                </c:if>
                                <a href="" class="">返回首页</a>
                            </span>
                    </alert>
                    <!--
                Failed URL: ${url}
                Exception:  ${exception.message}
                    <c:forEach items="${exception.stackTrace}" var="ste">    ${ste}
                </c:forEach>
            -->
                </i-content>
                <jsp:include page="footer.jsp" />
            </layout>
        </layout>
    </layout>

</div>

<script>
    new Vue({
        el: '#app',
        data: {},
        created: function () {
        },
        methods: {}
    })
</script>
</body>

</html>

 

admin

这个人很懒,什么都没留下

文章评论

您需要 登录 之后才可以评论