/**
* pengweikang 20170220 用户登陆
*
* @param cgbUser
* 用户信息
* @param session
* @return
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
public @ResponseBody String userLogin(HttpServletRequest request) {
try {
..... //Service方法调用
} catch (Exception e) {
..... //异常处理
}
return null;
}
该方法的缺点是代码冗余,不利于维护,一看就不想是一个专业的软件工程师应该写的,优化办法如下:
其实SpringMVC给我们提供了一个控制器增强标签,名称为@ControllerAdvice,通过这个标签就可以统一实现异常处理,代码如下:
创建统一的异常处理类CGBExceptionHandler.java
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
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.servlet.config.annotation.EnableWebMvc;
import ch.qos.logback.classic.Level;
import net.sf.json.JSONObject;
/**
*@author create by pengweikang
*@date 2018年6月27日--下午12:49:23
*@problem
*@answer
*@action
*/
@ControllerAdvice
public class CGBExceptionHandler {
ch.qos.logback.classic.Logger loggerback = (ch.qos.logback.classic.Logger)LoggerFactory.getLogger("error");
{
loggerback.setLevel(Level.ERROR);
}
@ExceptionHandler(Exception.class)
@ResponseBody
public Object handleException(Exception e,HttpServletRequest rquest) {
loggerback.error("错误日志记录");
Map dataMap = rquest.getParameterMap();
Set keySet = dataMap.keySet();
for(String key : keySet) {
String [] datas = (String[])dataMap.get(key);
String value = new String();
for(String data : datas) {
value +=data+",";
}
loggerback.error("Param:"+key+" = "+ value.substring(0, value.length() - 1));//将请求参数保存在日志中
}
loggerback.error(ExceptionUtils.getFullStackTrace(e)); // 记录错误信息
String msg = e.getMessage();
if (msg == null || msg.equals("")) {
msg = "服务器出错";
}
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", msg);
jsonObject.put("state", 0);
return jsonObject.toString();
}
}
这个时候你的Controller就不用在添加try-catch异常捕获了, 一但方法出了异常就会跳转到CGBExceptionHandler.java这个类的handleException方法。
2.logback日志管理
在这个方法中我们将方法调用的的错误消息都记录在日志中,并且将方法调用的参数也报错在错误日志中,logback配置内容如下:
ERROR
ACCEPT
DENY
[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
ERROR
ACCEPT
DENY
${ROOT}%d/error.%i.log
${MAXHISTORY}
${FILESIZE}
[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
WARN
ACCEPT
DENY
${ROOT}%d/warn.%i.log
${MAXHISTORY}
${FILESIZE}
[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
INFO
ACCEPT
DENY
${ROOT}%d/info.%i.log
${MAXHISTORY}
${FILESIZE}
[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
DEBUG
ACCEPT
DENY
${ROOT}%d/debug.%i.log
${MAXHISTORY}
${FILESIZE}
[%-5level] %d{${DATETIME}} [%thread] %logger{36} - %m%n
TRACE
ACCEPT
DENY
${ROOT}%d/trace.%i.log
${MAXHISTORY}
${FILESIZE}
该配置文件内容为将不同类型的日志按不同文件进行报错,并且每天记录不同的日志,文件夹按日期进行命名,儿控制台只打印错误日志。
3.测试
测试代码如下:
@Controller
@RequestMapping(value="/test")
public class TestController {
@RequestMapping(value="/exception")
public @ResponseBody String throwexcep(int data) throws Exception {
int a = data/0;// 一定会抛出 java.lang.ArithmeticException: / by zero
return null;
}
}
请求 http://localhost:8080/logSystem/test/exception?data=100
首先看tomcat的log文件夹如下图所示:
error.0.log日志记录如下:
[ERROR] 2018-07-06 15:05:39 [http-bio-8080-exec-3] error - 错误日志记录
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - 错误日志记录
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - Param:data = 100
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - ParameterMap:org.apache.catalina.util.ParameterMap@c7832d1
[ERROR] 2018-07-06 15:09:30 [http-bio-8080-exec-2] error - java.lang.ArithmeticException: / by zero
at com.goldenbridge.recognizesystem.controller.ActivitiController.throwexcep(ActivitiController.java:137)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:222)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:814)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:737)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:969)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:860)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:845)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.alibaba.druid.support.http.WebStatFilter.doFilter(WebStatFilter.java:123)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:383)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.goldenbridge.recognizesystem.utils.SimpleCORSFilter.doFilter(SimpleCORSFilter.java:34)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:506)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:962)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:445)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1115)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
到此系统日志管理配置完成!