springboot自定义异常
自定义异常类,继承RuntimeException
/**
* 自定制异常类
*
*/
@Getter
public class CustomException extends RuntimeException {
private int code;
private String message;
public CustomException(int code, String message) {
this.code = code;
this.message = message;
}
public CustomException(ResultStatusEnum resultStatusEnum) {
this.code = resultStatusEnum.getCode();
this.message = resultStatusEnum.getMessage();
}
}
全局异常处理
/**
* 全局异常处理
*
*/
@ControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ExceptionHandler(CustomException.class)
public Map<String, Object> handleCustomException(CustomException customException) {
Map<String, Object> errorResultMap = new HashMap<>(16);
errorResultMap.put("code", customException.getCode());
errorResultMap.put("message", customException.getMessage());
return errorResultMap;
}
}
响应结果枚举类
/**
* 响应结果状态枚举类
*
*/
@NoArgsConstructor
@AllArgsConstructor
public enum ResultStatusEnum {
/**
* 请求成功
*/
SUCCESS(200, "请求成功!"),
/**
* 密码错误
*/
PASSWORD_NOT_MATCHING(400, "密码错误");
@Getter
@Setter
private int code;
@Getter
@Setter
private String message;
}
测试自定义异常处理
@GetMapping("/test/{id:\\d+}")
public UserDTO testError(@PathVariable("id") String userId) {
throw new CustomException(ResultStatusEnum.PASSWORD_NOT_MATCHING);
}
@GetMapping("/test2/{id:\\d+}")
public UserDTO testError2(@PathVariable("id") String userId) {
throw new CustomException(400, "这是400错误");
}
springmvc自定义异常
写代码过程中,经常需要再代码里写try catch,比较麻烦。可以单独抽取出来。
先看效果
1普通调整异常页面
2ajax异常返回
直接上代码了
1.再spring-mvc.xml中配置自定义异常类
<!-- 异常处理类 -->
<bean id="exceptionHandler"
class="com.ncme.common.exception.GlobalExceptionResolver" />
2、异常类写法
package com.ncme.common.exception;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import com.ncme.common.dto.AjaxResult;
import com.ncme.common.util.JSONHelper;
/**
* spring mvc 全局处理异常捕获 根据请求区分ajax和普通请求,分别进行响应.
* 第一、异常信息输出到日志中。
* 第二、截取异常详细信息的前50个字符,写入日志表中t_s_log。
*/
@Component
public class GlobalExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
boolean isajax = isAjax(request,response);
Throwable deepestException = deepestException(ex);
return processException(request, response, handler, deepestException, isajax);
}
/**
* 判断当前请求是否为异步请求.
*/
private boolean isAjax(HttpServletRequest request, HttpServletResponse response){
return isNotEmpty(request.getHeader("X-Requested-With"));
}
public static boolean isNotEmpty(Object object) {
if (object != null && !object.equals("") && !object.equals("null")) {
return (true);
}
return (false);
}
/**
* 获取最原始的异常出处,即最初抛出异常的地方
*/
private Throwable deepestException(Throwable e){
Throwable tmp = e;
int breakPoint = 0;
while(tmp.getCause()!=null){
if(tmp.equals(tmp.getCause())){
break;
}
tmp=tmp.getCause();
breakPoint++;
if(breakPoint>1000){
break;
}
}
return tmp;
}
/**
* 处理异常.
* @param request
* @param response
* @param handler
* @param deepestException
* @param isajax
* @return
*/
private ModelAndView processException(HttpServletRequest request,
HttpServletResponse response, Object handler,
Throwable ex, boolean isajax) {
//步骤一、异常信息记录到日志文件中.
// log.error("全局处理异常捕获:", ex);
//步骤二、异常信息记录截取前50字符写入数据库中.
// logDb(ex);
//步骤三、分普通请求和ajax请求分别处理.
if(isajax){
return processAjax(request,response,handler,ex);
}else{
return processNotAjax(request,response,handler,ex);
}
}
/**
* 异常信息记录截取前50字符写入数据库中
* @param ex
*/
/* private void logDb(Throwable ex) {
//String exceptionMessage = getThrowableMessage(ex);
String exceptionMessage = "错误异常: "+ex.getClass().getSimpleName()+",错误描述:"+ex.getMessage();
if(oConvertUtils.isNotEmpty(exceptionMessage)){
if(exceptionMessage.length() > WIRTE_DB_MAX_LENGTH){
exceptionMessage = exceptionMessage.substring(0,WIRTE_DB_MAX_LENGTH);
}
}
systemService.addLog(exceptionMessage, LOG_OPT,LOG_LEVEL);
}*/
/**
* ajax异常处理并返回.
* @param request
* @param response
* @param handler
* @param deepestException
* @return
*/
private ModelAndView processAjax(HttpServletRequest request,
HttpServletResponse response, Object handler,
Throwable deepestException){
ModelAndView empty = new ModelAndView();
response.setContentType("application/json;charset=UTF-8");
// response.setContentType("text/plain;charset=UTF-8");
response.setHeader("Cache-Control", "no-store");
AjaxResult ajaxResult=new AjaxResult();
ajaxResult.setSuccess(false);
ajaxResult.setMsg(deepestException.getMessage());
PrintWriter pw = null;
try {
pw=response.getWriter();
pw.write(JSONHelper.bean2json(ajaxResult));
pw.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
pw.close();
} catch (Exception e2) {
}
}
empty.clear();
return empty;
}
/**
* 普通页面异常处理并返回.
* @param request
* @param response
* @param handler
* @param deepestException
* @return
*/
private ModelAndView processNotAjax(HttpServletRequest request,
HttpServletResponse response, Object handler, Throwable ex) {
String exceptionMessage = getThrowableMessage(ex);
Map<String, Object> model = new HashMap<String, Object>();
model.put("ErrorMsg", ex);
model.put("stack", exceptionMessage);
return new ModelAndView("failure", model);
}
/**
* 返回错误信息字符串
*
* @param ex
* Exception
* @return 错误信息字符串
*/
public String getThrowableMessage(Throwable ex) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
ex.printStackTrace(pw);
return sw.toString();
}
}
3.定义异常跳转错误页面failure.jsp
<%@ page contentType="text/html;charset=utf-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>Failure</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript">
function forback()
{
if(window.history.length==0)
{
window.close();
}
else
{
window.history.back();
}
}
</script>
<style type="text/css">
#Error {
COLOR: #B22222;
FONT-SIZE: 14px;
}
</style>
</head>
<body leftmargin="0" topmargin="0" class="body1">
<center>
<TABLE width="100%" height="600" border="0" cellPadding="0"
cellSpacing="0">
<tr>
<td align="center">
<table width="70%" border="0" cellpadding="1" cellspacing="0"
bordercolor="#BDC7D6" bgcolor="#BDC7D6">
<tr>
<td>
<table width="100%" border="0" cellpadding="0" cellspacing="0"
bordercolor="#BDC7D6" bgcolor="#FFFFFF" class="lankuang1">
<tr>
<td height="25" align="left" valign="middle"
bgcolor="#EFF3F7" class="lanbottom">
<strong style="color: #5F9EA0">报错提醒:${ErrorMsg }</strong>
</td>
</tr>
<tr>
<td height="120" align="center">
<table width="90%" border="0" cellspacing="0"
cellpadding="0">
<tr>
<td width="73%" align="left" valign="middle">
<span onclick="showError()" style="cursor:pointer">出错了,请联系管理员!</span>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="button" name="forward" value="返回 "
class="but2" onClick="forback();">
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</TABLE>
</center>
<div style="display:none" id="errorcode">
<span id="Error">信息:${ErrorMsg }</span>
<br/>
---------------------------------
堆栈:
${stack }
-----------
</div>
</body>
<script type="text/javascript">
function showError(){
document.getElementById("errorcode").style.display="block";
}
</script>
</html>