During the Java web development process, there will inevitably be some system exceptions or artificial exceptions. How to handle it elegantly in a RESTful springboot project?
Analysis: In the RESTful-style springboot project, the returned body objects are all body objects, so it is more appropriate to define a result base class that contains status, message, data (return result of the request method).
It will be more troublesome if you define multiple exception classes for processing. For example, StudentNotExistsException and StudentExistsException. . . etc., and the error code cannot be specified, which is inconvenient for the front-end to process according to the error code.
Note: The general spring mvc model processing flow is as follows
General controller layer->Service layer->Dao layer.
1. Controller layer, accept requests, perform paging, and encapsulate DTO object.
2. Service layer, execution logic, control concurrency, and transactions.
3.Dao layer, interact with the database.
Use a student table to describe the processing:
1. Define common error enum StudentExceptionEnum
public enum StudentExceptionEnum { STUDENT_NOT_EXIST(1004,"Student does not exist, please confirm before checking"), STUDENT_EXIST(1005,"Student already exists"); private Integer status; private String comment; StudentExceptionEnum(Integer status, String comment) { this.status = status; this.comment = comment; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; }}2 Define a basic processing result class RequestResult
@Datapublic class RequestResult { private String message; private Integer status; private Object data; public RequestResult(String message, Integer status, Object data) { this.message = message; this.status = status; this.data = data; } public RequestResult(String message, Integer status) { this.message = message; this.status = status; } public RequestResult(String message, Integer status) { this.message = message; this.status = status; } public RequestResult(String message, StudentExceptionEnum requestExceptionEnum) { this.message = message; this.status = requestExceptionEnum.getStatus(); } public RequestResult() { status = 200; message = "ok"; } public static RequestResult OK(Object data) { RequestResult result = new RequestResult(); result.setData(data); return result; } public static RequestResult EXCEPTION(String message, Integer status) { return new RequestResult(message, status); } public static RequestResult EXCEPTION(String message, StudentExceptionEnum requestExceptionEnum) { return new RequestResult(message, requestExceptionEnum); }}3 Entity Student
@Datapublic class Student implements Serializable{ private String id; private String nickname; private String name; private int age; private String sex; private String address; @Override public String toString() { return ToStringBuilder.reflectionToString(this); }}4 Process the request, add the student, nickname required. Only Service snippet codes are displayed here
@Override public RequestResult addStudent(Student student) { if (studentDao.queryIdByNickname(student.getNickname()) == null) { studentDao.addStudent(student); System.out.println("Add successful"); student = studentDao.queryByNickname(student.getNickname()); return RequestResult.OK(student); } else { return RequestResult.EXCEPTION("User" + student.getNickname() + "already exist", StudentExceptionEnum.STUDENT_EXIST); } }5 At this time, the basic processing situation has been completed. The basic test is performed below
5.1 Add a new classmate information
5.2 Add again to make it abnormal test
2. At this point, it is basically done, but it will be unfriendly to return it directly to the front-end without handling the basic runtime exception. Therefore, you need to define a global RuntimeException exception handling class.
The key annotation that needs to be used here: @ExceptionHandler
There are two usages 1) Add @ExceptionHandler to the controller that handles the request. At this time, this method will only handle the exception thrown by the controller.
2) Use it in the global exception handling class. The global exception handling class needs to be marked with @RestControllerAdvice or @ControllerAdvice
We need to handle the global RuntimeException, so we use the second method. Of course, this is handled for customer-friendly. We still have to deal with this error. What should we do? It is necessary to record the wrong information for future analysis and processing. Logging is performed here using logger. The code is as follows
@RestControllerAdvicepublic class BaseExceptionHandler { private static Logger logger = LoggerFactory.getLogger(BaseExceptionHandler.class); @ExceptionHandler(value = RuntimeException.class) public RequestResult exceptionHandler(HttpServletRequest request,Exception e) { logError(request,e); return RequestResult.EXCEPTION("Exception is handled internally, the engineer is working on emergency repairs, please come back later...",500); } public static void logError(HttpServletRequest request, Exception e) { logger.error("Request address: " + request.getRequestURL()); logger.error("Request method: " + request.getMethod()); logger.error("Request IP: " + getRemoteIp(request)); logger.error("Error details: "); StackTraceElement[] error = e.getStackTrace(); for (StackTraceElement stackTraceElement: error) { logger.error(stackTraceElement.toString()); } } public static String getRemoteIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); 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(); } } else if (ip.length() > 15) { String[] ips = ip.split(","); for (int index = 0; index < ips.length; index++) { String strIp = (String) ips[index]; if (!("unknown".equalsIgnoreCase(strIp))) { ip = strIp; break; } } } return ip; }}Test to see if it takes effect:
Modify and add student information code as follows:
public RequestResult addStudent(Student student) { int a = 1/0; if (studentDao.queryIdByNickname(student.getNickname()) == null) { studentDao.addStudent(student); System.out.println("Add successful"); student = studentDao.queryByNickname(student.getNickname()); return RequestResult.OK(student); } else { return RequestResult.EXCEPTION("User'" + student.getNickname() + "'Already existed", StudentExceptionEnum.STUDENT_EXIST); } }Perform a test
Printing error message on the background
2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : Request address: http://localhost:8080/demo1/student2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : Request method: POST2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : Request IP: 0:0:0:0:0:0:0:0:0:0:0:12018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : Error details: 2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : com.huitong.demo.service.StudentService.addStudent(StudentService.java:71)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : com.huitong.demo.controller.StudentController.addStudent(StudentController.java:38)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: java.lang.reflect.Method.invoke(Method.java:498)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:870)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:776)2018-03-26 17:01:19.125 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)2018-03-26 17:01:19.129 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)2018-03-26 17:01:19.129 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)2018-03-26 17:01:19.129 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)2018-03-26 17:01:19.129 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881)2018-03-26 17:01:19.129 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: javax.servlet.http.HttpServlet.service(HttpServlet.java:661)2018-03-26 17:01:19.129 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: javax.servlet.http.HttpServlet.service(HttpServlet.java:742)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)2018-03-26 17:01:19.130 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler : org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)2018-03-26 17:01:19.131 ERROR 9136 --- [nio-8080-exec-2] chdcontroller.BaseExceptionHandler: java.lang.Thread.run(Thread.java:745)2018-03-26 17:01:19.133 WARN 9136 --- [nio-8080-exec-2] .mmaExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: java.lang.ArithmeticException: / by zero
Summarize
The above is the springboot error handling summary introduced by the editor. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support to Wulin.com website!