springboot(九)--统一异常处理(500)、错误页处理(404)
程序员文章站
2022-07-08 23:28:50
...
如题,本篇我们介绍下springboot中统一异常500处理,以及错误页404处理。
一、统一异常处理(500)
主要针对于服务器出现500异常的情况,返回自定义的500页面到用户浏览器,或者输出错误json数据到用户浏览器。
如果ex是业务层抛出的自定义异常则或取自定义异常的自定义状态码和自定义消息+错误堆栈信息;如果ex不是自定义异常,则获取ex的错误堆栈信息。
MvcExceptionResolver.java
package com.tingcream.springWeb.mvc;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.tingcream.springWeb.exception.ServiceCustomException;
import com.tingcream.springWeb.util.AjaxUtil;
/**
* mvc异常处理器
* @author jelly
*
*/
@Component
public class MvcExceptionResolver implements HandlerExceptionResolver{
private Logger logger = Logger.getLogger(MvcExceptionResolver.class);
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex) {
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
try {
String errorMsg="";
boolean isAjax= "1".equals(request.getParameter("isAjax"));
//ex 为业务层抛出的自定义异常
if(ex instanceof ServiceCustomException){
ServiceCustomException customEx= (ServiceCustomException)ex;
errorMsg ="customStatus:"+customEx.getCustomStatus() +",customMessage:"+customEx.getCustomMessage()
+"\r\n"+ ExceptionUtils.getStackTrace(customEx);
logger.error(errorMsg);
}else{
//ex为非自定义异常,则
errorMsg=ExceptionUtils.getStackTrace(ex);
logger.error(errorMsg);
}
if(isAjax){
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write(JSON.toJSONString(AjaxUtil.messageMap(500, errorMsg)));
return new ModelAndView();
}else{
//否则, 输出错误信息到自定义的500.jsp页面
ModelAndView mv = new ModelAndView("/error/500.jsp");
mv.addObject("errorMsg", errorMsg);
return mv ;
}
} catch (IOException e) {
logger.error(ExceptionUtils.getStackTrace(e));
}
return new ModelAndView();
}
}
ServiceCustomException.java
package com.tingcream.springWeb.exception;
/**
* 业务自定义异常
* @author jelly
*
*/
public class ServiceCustomException extends RuntimeException{
private Integer customStatus;
private String customMessage;
private static final long serialVersionUID = 1L;
public ServiceCustomException() {
super();
}
public ServiceCustomException(Integer customStatus ,String customMessage) {
this.customStatus=customStatus;
this.customMessage=customMessage;
}
public ServiceCustomException(Integer customStatus ,String customMessage,Throwable cause) {
super(cause);
this.customStatus=customStatus;
this.customMessage=customMessage;
}
public Integer getCustomStatus() {
return customStatus;
}
public void setCustomStatus(Integer customStatus) {
this.customStatus = customStatus;
}
public String getCustomMessage() {
return customMessage;
}
public void setCustomMessage(String customMessage) {
this.customMessage = customMessage;
}
}
500.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title>500</title>
</head>
<body>
<h3>糟糕! 服务器出错啦~~(>_<)~~</h3>
<div>
异常信息如下:<br/>
${errorMsg }
</div>
</body>
</html>
我们在controller方法中模拟抛出一个异常
@RequestMapping("/")
public String home(HttpServletRequest request, HttpServletRequest response){
int a =3/0;//不能被0除异常
request.setAttribute("message", "早上好,朋友们!");
return "/home.jsp";
}
AjaxUtil.java
package com.tingcream.springWeb.util;
import java.util.HashMap;
import java.util.Map;
public class AjaxUtil {
//得到一个map
public static Map<String,Object> getMap(){
return new HashMap<String,Object>();
}
//返回json数据 状态
public static Map<String,Object> messageMap(int status){
Map<String,Object> map=new HashMap<String,Object>();
map.put("status", status);
return map;
}
//返回json数据 状态、消息
public static Map<String,Object> messageMap(int status,String message){
Map<String,Object> map=new HashMap<String,Object>();
map.put("status", status);
map.put("message", message);
return map;
}
//返回json数据 状态、消息 和一个参数
public static Map<String,Object> messageMap(int status,String message,
String paramName,Object paramValue){
Map<String,Object> map=new HashMap<String,Object>();
map.put("status", status);
map.put("message", message);
map.put(paramName, paramValue);
return map;
}
//返回json数据 状态、消息 和多个参数
public static Map<String,Object> messageMap(int status,String message,
String[] paramNames,Object[] paramValues){
Map<String,Object> map=new HashMap<String,Object>();
map.put("status", status);
map.put("message", message);
if(paramNames!=null&¶mNames.length>0){
for(int i=0;i<paramNames.length;i++){
map.put(paramNames[i], paramValues[i]);
}
}
return map;
}
}
用浏览器访问首页,发现报错了,进入了500.jsp页面 。
ok,说明500异常处理配置成功 !!
二、错误页处理(404)
主要针对404请求的情况,如用户在浏览器中随意地输入了一个不存在的路径。
ErrorPageController.java
package com.tingcream.springWeb.mvc;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 错误页(404) 处理
* @author jelly
*
*/
@Controller
public class ErrorPageController implements ErrorController {
private static final String ERROR_PATH = "/error";
@RequestMapping(ERROR_PATH)
public String error(){
return "/error/404.jsp";
}
@Override
public String getErrorPath() {
return ERROR_PATH;
}
}
404.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html >
<html>
<head>
<base href="<%=basePath%>">
<title>404</title>
</head>
<body>
<h2>404</h2>
<h3>抱歉,您访问的页面好像被火星汪叼走了!</h3>
</body>
</html>
启动服务器,随便访问一个不存在的路径。。
ok,说明错误页(404) 配置成功 !!