SpringMvc(异常处理)
1、内置异常处理解析器
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
2、统一异常处理
2.1、获得Java处理类的异常信息并输出
@Controller
public class ExceptionController {
@RequestMapping("/exception01")
public String exception01(@RequestParam("name") String name){
System.out.println("方法处理中01");
return "show";
}
@RequestMapping("/exception02")
public String exception02(@RequestParam("name") String name){
System.out.println("方法处理中02");
return "show";
}
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
//日志记录
System.out.println(ex.getMessage());
return modelAndView;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
出错了。<br/>
<%= ((Exception)request.getAttribute("ex")).getMessage() %>
</body>
</html>
2.2、Java异常栈信息输出
public static String getStackTrace(Throwable throwable){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
throwable.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception ex){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
//日志记录,获取到完整的堆栈信息
System.out.println(getStackTrace(ex));
return modelAndView;
}
public static String getStackTrace(Throwable throwable){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
throwable.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
2.3、处理全局异常
@ControllerAdvice注解标注在类上时,代表处理全局异常
@ControllerAdvice
public class GeneralExceptionHandler {
/**
* 全局异常处理
* @param ex
* @return
*/
@ExceptionHandler(Exception.class)
public ModelAndView handleException01(Exception ex){
System.out.println("全局异常处理。");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
//日志记录,获取到完整的堆栈信息
System.out.println(getStackTrace(ex));
return modelAndView;
}
@ExceptionHandler(MissingServletRequestParameterException.class)
public ModelAndView handleException02(Exception ex){
System.out.println("全局异常处理,参数找不到了。");
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
//日志记录,获取到完整的堆栈信息
System.out.println(getStackTrace(ex));
return modelAndView;
}
public static String getStackTrace(Throwable throwable){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
throwable.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
}
2.4、统一处理异常(json或页面)
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.10.3</version>
</dependency>
/* 1、根据用户请求的方法是否是一个需要返回json数据的方法
// 获得类上面的某个注解
RestController restController = handlerMethod.getClass().getAnnotation(RestController.class);
// 获得方法上的某个注解
ResponseBody responseBody = handlerMethod.getMethod().getAnnotation(ResponseBody.class);
// 如果当前请求是ajax就返回json
if(restController != null || responseBody != null){}*/package cool.ale.exception;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
/**
* @author dujlc
*
*
* 统一异常处理:同时返回普通请求和ajax请求
* 普通请求:返回视图,错误信息
* ajax:返回json
* {
* code
* message
* }
*
*/
@ControllerAdvice
public class GeneralExceptionHandler {
/**
* 全局异常处理
* @param ex
* @return
*/
@ExceptionHandler(Exception.class)
public ModelAndView handleException01(HttpServletRequest request,
HttpServletResponse response,
HandlerMethod handlerMethod,
Exception ex) throws IOException {
System.out.println("全局异常处理。");
/* 1、根据用户请求的方法是否是一个需要返回json数据的方法
// 获得类上面的某个注解
RestController restController = handlerMethod.getClass().getAnnotation(RestController.class);
// 获得方法上的某个注解
ResponseBody responseBody = handlerMethod.getMethod().getAnnotation(ResponseBody.class);
// 如果当前请求是ajax就返回json
if(restController != null || responseBody != null){}*/
// 2、如果请求头中的类型包含了 Content-Type 包含 application/json
if (!StringUtils.isEmpty(request.getHeader("Content-Type")) && request.getHeader("Content-Type").indexOf("application/json") > -1){
// 可直接依照下面的方式输出
//response.getWriter().write("sss");
// 但是我们一般是集成jackson,返回json
// ModelAndView既支持json返回、也支持视图返回
// ResponseBody的底层也是做了这个MappingJackson2JsonView
ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
// 通常会根据不同的异常返回不同的编码,这里为了简单,先随便写一种s
modelAndView.addObject("code", HttpStatus.INTERNAL_SERVER_ERROR.value());
modelAndView.addObject("message",ex.getMessage());
return modelAndView;
}
else{
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
modelAndView.addObject("ex",ex);
//日志记录,获取到完整的堆栈信息
System.out.println(getStackTrace(ex));
return modelAndView;
}
}
public static String getStackTrace(Throwable throwable){
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
try {
throwable.printStackTrace(pw);
return sw.toString();
} finally {
pw.close();
}
}
}
2.5、处理404页面
<mvc:resources mapping="/404.html" location="/"></mvc:resources>
<error-page>
<error-code>404</error-code>
<location>/404.html</location>
</error-page>