springboot 错误处理小结
在javaweb开发过程中,难免会有一些系统异常或人为产生一些异常。在RESTfulspringboot项目中如何优雅的处理?
分析:在RESTful风格的springboot项目中,返回的都是body对象,所以定义一个结果基类,其中包含status,message,data(请求方法的返回结果),是比较合适的。
如果定义多个异常类进行处理,会比较麻烦。比如StudentNotExistsException、StudentExistsException。。。等,并且不能指定错误码,不方便前端根据错误码进行处理。
说明:一般的springmvc模型处理流程如下
一般controller层->Service层->Dao层。
1.controller层,接受请求,进行分页,DTO对象封装操作。
2.service层,执行逻辑,控制并发,事务。
3.Dao层,与数据库交互。
使用一个学生表的处理进行说明:
1、定义常见的错误枚举StudentExceptionEnum
publicenumStudentExceptionEnum{
STUDENT_NOT_EXIST(1004,"学生不存在,请确认后再查"),
STUDENT_EXIST(1005,"学生已存在");
privateIntegerstatus;
privateStringcomment;
StudentExceptionEnum(Integerstatus,Stringcomment){
this.status=status;
this.comment=comment;
}
publicIntegergetStatus(){
returnstatus;
}
publicvoidsetStatus(Integerstatus){
this.status=status;
}
publicStringgetComment(){
returncomment;
}
publicvoidsetComment(Stringcomment){
this.comment=comment;
}
}
2定义一个基本的处理结果类RequestResult
@Data
publicclassRequestResult{
privateStringmessage;
privateIntegerstatus;
privateObjectdata;
publicRequestResult(Stringmessage,Integerstatus,Objectdata){
this.message=message;
this.status=status;
this.data=data;
}
publicRequestResult(Stringmessage,Integerstatus){
this.message=message;
this.status=status;
}
publicRequestResult(Stringmessage,StudentExceptionEnumrequestExceptionEnum){
this.message=message;
this.status=requestExceptionEnum.getStatus();
}
publicRequestResult(){
status=200;
message="ok";
}
publicstaticRequestResultOK(Objectdata){
RequestResultresult=newRequestResult();
result.setData(data);
returnresult;
}
publicstaticRequestResultEXCEPTION(Stringmessage,Integerstatus){
returnnewRequestResult(message,status);
}
publicstaticRequestResultEXCEPTION(Stringmessage,StudentExceptionEnumrequestExceptionEnum){
returnnewRequestResult(message,requestExceptionEnum);
}
}
3实体类Student
@Data
publicclassStudentimplementsSerializable{
privateStringid;
privateStringnickname;
privateStringname;
privateintage;
privateStringsex;
privateStringaddress;
@Override
publicStringtoString(){
returnToStringBuilder.reflectionToString(this);
}
}
4处理请求,添加学生,nickname必填项。此处只显示Service片段代码
@Override
publicRequestResultaddStudent(Studentstudent){
if(studentDao.queryIdByNickname(student.getNickname())==null){
studentDao.addStudent(student);
System.out.println("添加成功");
student=studentDao.queryByNickname(student.getNickname());
returnRequestResult.OK(student);
}else{
returnRequestResult.EXCEPTION("用户"+student.getNickname()+"已存在",StudentExceptionEnum.STUDENT_EXIST);
}
}
5此时,已经完成了基本的处理情况。下面就进行基本的测试了
5.1添加一个新同学信息
5.2再次添加让其出现异常测试
二、到此基本已大功告成,但是,对于基本的运行时异常没有处理,直接返回给前端会很不友好。所以要定义一个全局的RuntimeException异常处理类。
此处需要使用的关键标注:@ExceptionHandler
用法有两种1)在处理请求的Controller中添加@ExceptionHandler,此时该方法只会处理该Controller抛出的异常。
2)将其用在全局的异常处理类中,全局异常处理类需要使用 @RestControllerAdvice或@ControllerAdvice标记
我们需要处理全局的RuntimeException,所以我们使用第二种方法。当然,这样处理是为了客户友好型,我们还是要处理这种错误,怎么办?就需要将错误的信息记录下来,方便以后分析处理。此处使用logger进行记录。代码如下
@RestControllerAdvice
publicclassBaseExceptionHandler{
privatestaticLoggerlogger=LoggerFactory.getLogger(BaseExceptionHandler.class);
@ExceptionHandler(value=RuntimeException.class)
publicRequestResultexceptionHandler(HttpServletRequestrequest,Exceptione){
logError(request,e);
returnRequestResult.EXCEPTION("内部处理异常,工程师正在抓紧抢修,请稍后再来...",500);
}
publicstaticvoidlogError(HttpServletRequestrequest,Exceptione){
logger.error("请求地址:"+request.getRequestURL());
logger.error("请求方法:"+request.getMethod());
logger.error("请求IP:"+getRemoteIp(request));
logger.error("错误详情:");
StackTraceElement[]error=e.getStackTrace();
for(StackTraceElementstackTraceElement:error){
logger.error(stackTraceElement.toString());
}
}
publicstaticStringgetRemoteIp(HttpServletRequestrequest){
Stringip=request.getHeader("X-Forwarded-For");
if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip=request.getHeader("Proxy-Client-IP");
}
if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip=request.getHeader("WL-Proxy-Client-IP");
}
if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip=request.getHeader("HTTP_CLIENT_IP");
}
if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip=request.getHeader("HTTP_X_FORWARDED_FOR");
}
if(ip==null||ip.length()==0||"unknown".equalsIgnoreCase(ip)){
ip=request.getRemoteAddr();
}
}elseif(ip.length()>15){
String[]ips=ip.split(",");
for(intindex=0;index
进行测试看是否生效:
修改添加学生信息代码如下:
publicRequestResultaddStudent(Studentstudent){
inta=1/0;
if(studentDao.queryIdByNickname(student.getNickname())==null){
studentDao.addStudent(student);
System.out.println("添加成功");
student=studentDao.queryByNickname(student.getNickname());
returnRequestResult.OK(student);
}else{
returnRequestResult.EXCEPTION("用户'"+student.getNickname()+"'已存在",StudentExceptionEnum.STUDENT_EXIST);
}
}
进行测试
后台打印错误信息
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:请求地址:http://localhost:8080/demo1/student
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:请求方法:POST
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:请求IP:0:0:0:0:0:0:0:1
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:错误详情:
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:com.huitong.demo.service.StudentService.addStudent(StudentService.java:71)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:com.huitong.demo.controller.StudentController.addStudent(StudentController.java:38)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethod)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:java.lang.reflect.Method.invoke(Method.java:498)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776)
2018-03-2617:01:19.125ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
2018-03-2617:01:19.129ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
2018-03-2617:01:19.129ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
2018-03-2617:01:19.129ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
2018-03-2617:01:19.129ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881)
2018-03-2617:01:19.129ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:javax.servlet.http.HttpServlet.service(HttpServlet.java:661)
2018-03-2617:01:19.129ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:javax.servlet.http.HttpServlet.service(HttpServlet.java:742)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
2018-03-2617:01:19.130ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
2018-03-2617:01:19.131ERROR9136---[nio-8080-exec-2]c.h.d.controller.BaseExceptionHandler:java.lang.Thread.run(Thread.java:745)
2018-03-2617:01:19.133WARN9136---[nio-8080-exec-2].m.m.a.ExceptionHandlerExceptionResolver:ResolvedexceptioncausedbyHandlerexecution:java.lang.ArithmeticException:/byzero
总结
以上所述是小编给大家介绍的springboot错误处理小结,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!