Browse Source

增加业务异常和系统日志

git-svn-id: https://192.168.57.71/svn/jsgkj@1082 931142cf-59ea-a443-aa0e-51397b428577
ld_zhouk 8 năm trước cách đây
mục cha
commit
534eac17ac

+ 136 - 0
gkaqv2/trunk/modules/web/src/main/java/com/xt/js/gkaq/common/log/aspect/SysLogAspect.java

@@ -0,0 +1,136 @@
+package com.xt.js.gkaq.common.log.aspect;
+
+import java.lang.reflect.Method;
+
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import com.xt.js.gkaq.common.Constants;
+import com.xt.js.gkaq.common.ex.BusinessException;
+import com.xt.js.gkaq.common.log.annotation.SysLog;
+import com.xt.js.gkaq.frame.model.SysLogModel;
+import com.xt.js.gkaq.frame.service.SysLogService;
+
+/**
+ * 日志管理切点类
+ */
+@Aspect
+@Component
+public class SysLogAspect {
+    @Autowired
+    private SysLogService sysLogService;
+    // 日志对象
+    private static final Logger logger = LoggerFactory.getLogger(SysLogAspect.class);
+
+    // 日志切入点
+    @Pointcut("@annotation(com.xt.js.gkaq.common.log.annotation.SysLog)")
+    public void sysLogPointcut() {
+    }
+
+    /**
+     * 前置通知
+     * 
+     * @param joinPoint
+     */
+    @Before("sysLogPointcut()")
+    public void doBefore(JoinPoint joinPoint) {
+        genSysLog(joinPoint, null);
+    }
+
+    // /**
+    // * 后置通知
+    // * @param joinPoint
+    // */
+    // @AfterReturning(pointcut = "sysLogPointcut()")
+    // public void doAfter(JoinPoint joinPoint) {
+    // genSysLog(joinPoint, null);
+    // }
+
+    /**
+     * 异常通知
+     * 
+     * @param joinPoint
+     * @param e
+     */
+    @AfterThrowing(value = "sysLogPointcut()", throwing = "e")
+    public void doAfter(JoinPoint joinPoint, Exception e) {
+        genSysLog(joinPoint, e);
+    }
+
+    /**
+     * 生成系统日志
+     * 
+     * @param joinPoint
+     * @param ex
+     */
+    private void genSysLog(JoinPoint joinPoint, Exception ex) {
+        try {
+            // 获取方法名
+            String methodName = joinPoint.getSignature().getName();
+            // 获取目标类名
+            String targetName = joinPoint.getTarget().getClass().getName();
+            // 类路径
+            String classPath = targetName + "." + methodName + "()";
+            // 获取系统日志注解
+            SysLog sysLog = getSysLogAnnotation(joinPoint);
+            if (sysLog == null) {
+                logger.error("{}获取系统日志注解为空!", classPath);
+                return;
+            }
+
+            String description = sysLog.description();
+            String type = sysLog.type();
+            if (ex != null) {
+                if (ex instanceof BusinessException) {
+                    type = Constants.LOG_TYPE_2;
+                    BusinessException bex = (BusinessException) ex;
+                    description += "[发生业务异常,异常代码:" + bex.getErrorCode() + ",异常信息:" + bex.getErrorMsg() + "]";
+                } else {
+                    type = Constants.LOG_TYPE_1;
+                    description += "[发生异常:" + ex.getMessage() + "]";
+                }
+            }
+            logger.info("生成系统日志[日志类路径:{},日志类型:{},日志描述:{}]", classPath, type, description);
+
+            // 数据库日志
+            SysLogModel log = new SysLogModel();
+            log.setClassPath(classPath);
+            log.setType(type);
+            log.setMessage(description);
+            // 保存数据库
+            sysLogService.save(log);
+        } catch (Exception exp) {
+            logger.error("生成系统日志发生异常:", exp);
+        }
+    }
+
+    /**
+     * 获取系统日志注解
+     * 
+     * @param joinPoint
+     * @return
+     * @throws Exception
+     */
+    private static SysLog getSysLogAnnotation(JoinPoint joinPoint) throws Exception {
+
+        Signature signature = joinPoint.getSignature();
+        MethodSignature methodSignature = (MethodSignature) signature;
+        Method method = methodSignature.getMethod();
+
+        if (method != null) {
+            return method.getAnnotation(SysLog.class);
+        }
+
+        return null;
+    }
+
+}

+ 9 - 1
gkaqv2/trunk/modules/web/src/main/java/com/xt/js/gkaq/web/ctl/UserCtl.java

@@ -15,6 +15,8 @@ import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.xt.js.gkaq.common.BaseCtl;
 import com.xt.js.gkaq.common.GlobalData;
+import com.xt.js.gkaq.common.ex.BusinessException;
+import com.xt.js.gkaq.common.log.annotation.SysLog;
 import com.xt.js.gkaq.frame.model.UserGroupModel;
 import com.xt.js.gkaq.frame.model.UserInfoModel;
 import com.xt.js.gkaq.frame.model.UserModel;
@@ -50,6 +52,7 @@ public class UserCtl extends BaseCtl {
 	 */
     @RequestMapping("list")
     @ResponseBody
+    @SysLog(description="用户列表查询")
 	public PageInfo<UserModel> getPageInfo(UserVo vo) throws UnsupportedEncodingException {
 		// 初始化参数
 		if (null == vo.getPage() || vo.getPage() < 1) {
@@ -76,7 +79,10 @@ public class UserCtl extends BaseCtl {
 
     @RequestMapping("add")
     @ResponseBody
-    public WebJsonResult add(UserVo vo) {
+    @SysLog(description="添加用户数据")
+    public WebJsonResult add(UserVo vo) throws Exception {
+        if (StringUtils.isEmpty(vo.getLoginName()) || StringUtils.isEmpty(vo.getRealName()))
+            throw new BusinessException("101", "用户名不能为空!");
         UserModel user = new UserModel();
         user.setLoginName(vo.getLoginName());
         user.setRealName(vo.getRealName());
@@ -92,6 +98,7 @@ public class UserCtl extends BaseCtl {
     @RequestMapping("save")
     @ResponseBody
     @Transactional
+    @SysLog(description="保存用户数据")
     public WebJsonResult save(UserVo vo) {
         // 新增
         if(StringUtils.isEmpty(vo.getId())) {
@@ -152,6 +159,7 @@ public class UserCtl extends BaseCtl {
     @RequestMapping("del")
     @ResponseBody
     @Transactional
+    @SysLog(description="删除用户数据")
     public int del(String ids) {
     	int cnt = 0;
 		if (StringUtils.isNotEmpty(ids)) {

+ 10 - 3
gkaqv2/trunk/modules/web/src/main/java/com/xt/js/gkaq/web/system/ExceptionResolver.java

@@ -7,6 +7,8 @@ import java.util.Properties;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.web.multipart.MaxUploadSizeExceededException;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
@@ -25,6 +27,9 @@ import com.yuanxd.tools.utils.WebJsonResult;
  */
 public class ExceptionResolver extends SimpleMappingExceptionResolver {
 
+    // 日志对象
+    private static final Logger logger = LoggerFactory.getLogger(ExceptionResolver.class);
+
     @Override
     public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
             Exception ex) {
@@ -35,9 +40,11 @@ public class ExceptionResolver extends SimpleMappingExceptionResolver {
     @Override
     protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
             Exception ex) {
+
         if (null != ex) {
-            ex.printStackTrace();
+            logger.error("异常信息:", ex);
         }
+
         if(ex instanceof MaxUploadSizeExceededException ){
             WebJsonResult res = new WebJsonResult();
             res.setSuccess(false);
@@ -50,7 +57,7 @@ public class ExceptionResolver extends SimpleMappingExceptionResolver {
                 response.getWriter().write(mapper.writeValueAsString(res));
             }
             catch (IOException e) {
-                e.printStackTrace();
+                logger.error("解析MaxUploadSizeExceededException异常信息出错:", e);
             }
             return new ModelAndView();
         }
@@ -77,7 +84,7 @@ public class ExceptionResolver extends SimpleMappingExceptionResolver {
                     response.getWriter().write(mapper.writeValueAsString(res));
                 }
                 catch (IOException e) {
-                    e.printStackTrace();
+                    logger.error("解析异常信息出错:", e);
                 }
                 return new ModelAndView();
             }

+ 4 - 1
gkaqv2/trunk/modules/web/src/main/resources/spring/mvc.xml

@@ -9,6 +9,8 @@
         http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
 		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
 
+    <!--启动对@AspectJ注解的支持 , proxy-target-class设置为true表示通知spring使用cglib而不是jdk的来生成代理方法,这样AOP可以拦截到Controller --> 
+    <aop:aspectj-autoproxy proxy-target-class="true" />
 	<!-- Enable annotation configuration -->
 	<context:annotation-config />
 	<!-- 自动扫描且只扫描@Controller -->
@@ -57,7 +59,8 @@
         <property name="exceptionMappings">
             <props>
                 <prop key="org.apache.shiro.authz.UnauthorizedException">error/403</prop>
-                <prop key="java.lang.Exception">error/error</prop>
+                <prop key="com.xt.js.gkaq.common.ex.BusinessException">error/error</prop>
+                <prop key="java.lang.Exception">error/500</prop>
             </props>
         </property>
     </bean>

+ 1 - 0
gkaqv2/trunk/modules/web/src/main/resources/spring/spring.xml

@@ -24,6 +24,7 @@
 		ignore-resource-not-found="true" location="classpath*:spring/application.properties" />
 	<!-- 开启注解配置 -->
 	<!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入. @Controller的Bean注入在spring-mvc.xml中自动注册 -->
+	<context:component-scan base-package="com.xt.js.gkaq.common.log.aspect"/>
 	<context:component-scan base-package="com.xt.js.gkaq.web" />
 	<context:component-scan base-package="com.xt.js.gkaq.frame" />
 	<context:component-scan base-package="com.xt.js.gkaq.dwxx" />

+ 16 - 27
gkaqv2/trunk/modules/web/src/main/webapp/WEB-INF/view/error/403.jsp

@@ -1,39 +1,28 @@
 <%@page contentType="text/html;charset=UTF-8" isErrorPage="true"%>
 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 <c:set var="ctx" value="${pageContext.request.contextPath}" />
+<%
+    response.setStatus(200);
+%>
 <!DOCTYPE html>
-<html lang="en">
 <head>
-<title>404-页面无法访问</title>
+<title>403-没有操作权限</title>
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta http-equiv="Cache-Control" content="no-store" />
 <meta http-equiv="Pragma" content="no-cache" />
 <meta http-equiv="Expires" content="0" />
-<link rel="stylesheet" type="text/css" href="${ctx}/static/xt/css/style.css"/>
 </head>
-<%
-    response.setStatus(200);
-%>
-<script type="text/javascript">
-    function toMain() {
-        window.top.location = "${ctx}/main";
-    }
-</script>
-<style type="text/css">
-</style>
-<body BGCOLOR=#CFE1FF>
-    <div style="top: 50%; position: absolute; left: 50%; margin: -123px 0 0 -225px;">
-        <IMG SRC="${ctx}/static/xt/images/error/403.png" ALT="">
-    </div>
-    <div style="top: 50%; position: absolute; left: 50%; margin: -123px 0 0 -45px;">
-        <span style="font-family: ''微软雅黑'';">您没有此功能的操作权限!</span>
-    </div>
-    <div class="btn_left_2" style="top: 50%; position: absolute; left: 50%; margin: 20px 0 0 -90px;" >
-        <input type="button"  value="返回首页" onclick="toMain()" class="btn_blue"/>
-    </div>
-    <div class="btn_left_2" style="top: 50%; position: absolute; left: 50%; margin: 20px 0 0 40px;" >
-        <input type="button"  value="刷新"  onclick="refresh()" class="btn_blue"/>
+
+<body>
+    <div style="overflow: auto">
+        <div>
+            <input type="button" value="返回" onclick="window.history.back()"/>
+            <input type="button" value="刷新" onclick="window.location.reload()"/>
+            <input type="button" value="首页" onclick="window.location.assign('${ctx}/index')"/>
+        </div>
+        <h2>403 - 没有操作权限</h2>
+        <br />
+        <div>您没有此功能的操作权限,请联系系统管理员!</div>
     </div>
-       
 </body>
-</html>
+</html>

+ 15 - 26
gkaqv2/trunk/modules/web/src/main/webapp/WEB-INF/view/error/404.jsp

@@ -1,39 +1,28 @@
 <%@page contentType="text/html;charset=UTF-8" isErrorPage="true"%>
 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 <c:set var="ctx" value="${pageContext.request.contextPath}" />
+<%
+    response.setStatus(200);
+%>
 <!DOCTYPE html>
-<html lang="en">
 <head>
 <title>404-页面无法访问</title>
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta http-equiv="Cache-Control" content="no-store" />
 <meta http-equiv="Pragma" content="no-cache" />
 <meta http-equiv="Expires" content="0" />
-<link rel="stylesheet" type="text/css" href="${ctx}/static/xt/css/style.css"/>
 </head>
-<%
-    response.setStatus(200);
-%>
-<script type="text/javascript">
-    function toMain() {
-        window.top.location = "${ctx}/main";
-    }
-</script>
-<style type="text/css">
-</style>
-<body BGCOLOR=#CFE1FF>
-    <div style="top: 50%; position: absolute; left: 50%; margin: -123px 0 0 -225px;">
-        <IMG SRC="${ctx}/static/xt/images/error/404.png" ALT="">
-    </div>
-    <div style="top: 50%; position: absolute; left: 50%; margin: -123px 0 0 -45px;">
-        <span style="font-family: ''微软雅黑'';">您访问的页面不存在!</span>
-    </div>
-    <div class="btn_left_2" style="top: 50%; position: absolute; left: 50%; margin: 20px 0 0 -90px;" >
-        <input type="button"  value="返回首页" onclick="toMain()" class="btn_blue"/>
-    </div>
-    <div class="btn_left_2" style="top: 50%; position: absolute; left: 50%; margin: 20px 0 0 40px;" >
-        <input type="button"  value="刷新"  onclick="refresh()" class="btn_blue"/>
+
+<body>
+    <div style="overflow: auto">
+        <div>
+            <input type="button" value="返回" onclick="window.history.back()"/>
+            <input type="button" value="刷新" onclick="window.location.reload()"/>
+            <input type="button" value="首页" onclick="window.location.assign('${ctx}/index')"/>
+        </div>
+        <h2>404 - 页面无法访问</h2>
+        <br />
+        <div>您访问的页面不存在!</div>
     </div>
-       
 </body>
-</html>
+</html>

+ 25 - 28
gkaqv2/trunk/modules/web/src/main/webapp/WEB-INF/view/error/500.jsp

@@ -1,39 +1,36 @@
 <%@page contentType="text/html;charset=UTF-8" isErrorPage="true"%>
 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
 <c:set var="ctx" value="${pageContext.request.contextPath}" />
+<%
+	response.setStatus(200);
+	Throwable ex = null;
+	if (exception != null)
+		ex = exception;
+	if (request.getAttribute("javax.servlet.error.exception") != null)
+		ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
+%>
 <!DOCTYPE html>
-<html lang="en">
 <head>
-<title>404-页面无法访问</title>
+<title>500-系统内部错误</title>
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta http-equiv="Cache-Control" content="no-store" />
 <meta http-equiv="Pragma" content="no-cache" />
 <meta http-equiv="Expires" content="0" />
-<link rel="stylesheet" type="text/css" href="${ctx}/static/xt/css/style.css"/>
 </head>
-<%
-    response.setStatus(200);
-%>
-<script type="text/javascript">
-    function toMain() {
-        window.top.location = "${ctx}/main";
-    }
-</script>
-<style type="text/css">
-</style>
-<body BGCOLOR=#CFE1FF>
-    <div style="top: 50%; position: absolute; left: 50%; margin: -123px 0 0 -225px;">
-        <IMG SRC="${ctx}/static/xt/images/error/500.png" ALT="">
-    </div>
-    <div style="top: 50%; position: absolute; left: 50%; margin: -123px 0 0 -45px;">
-        <span style="font-family: ''微软雅黑'';">服务器异常!</span>
-    </div>
-    <div class="btn_left_2" style="top: 50%; position: absolute; left: 50%; margin: 20px 0 0 -90px;" >
-        <input type="button"  value="返回首页" onclick="toMain()" class="btn_blue"/>
-    </div>
-    <div class="btn_left_2" style="top: 50%; position: absolute; left: 50%; margin: 20px 0 0 40px;" >
-        <input type="button"  value="刷新"  onclick="refresh()" class="btn_blue"/>
-    </div>
-       
+
+<body>
+	<div style="overflow: auto">
+        <div>
+            <input type="button" value="返回" onclick="window.history.back()"/>
+            <input type="button" value="刷新" onclick="window.location.reload()"/>
+            <input type="button" value="首页" onclick="window.location.assign('${ctx}/index')"/>
+        </div>
+		<h2>500 - 系统发生内部错误</h2>
+		<br>
+		<div>错误详细信息:</div>
+		<div>
+			<%=ex.getMessage()%><br />
+		</div>
+	</div>
 </body>
-</html>
+</html>

+ 15 - 15
gkaqv2/trunk/modules/web/src/main/webapp/WEB-INF/view/error/error.jsp

@@ -1,24 +1,21 @@
 <%@page contentType="text/html;charset=UTF-8" isErrorPage="true"%>
 <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
-<%@page import="org.slf4j.Logger,org.slf4j.LoggerFactory"%>
-<%@page import="java.io.*"%>
+<%@page import="com.xt.js.gkaq.common.ex.BusinessException"%>
 <c:set var="ctx" value="${pageContext.request.contextPath}" />
 <%
 	response.setStatus(200);
+    BusinessException bex = null;
 	Throwable ex = null;
 	if (exception != null)
 		ex = exception;
 	if (request.getAttribute("javax.servlet.error.exception") != null)
 		ex = (Throwable) request.getAttribute("javax.servlet.error.exception");
-
-	//记录日志
-	Logger logger = LoggerFactory.getLogger("500.jsp");
-	logger.error(ex.getMessage(), ex);
+	if (ex instanceof BusinessException)
+	    bex = (BusinessException) ex;
 %>
 <!DOCTYPE html>
-<html lang="en">
 <head>
-<title>系统内部错误</title>
+<title>系统业务错误</title>
 <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
 <meta http-equiv="Cache-Control" content="no-store" />
 <meta http-equiv="Pragma" content="no-cache" />
@@ -27,12 +24,15 @@
 
 <body>
 	<div style="overflow: auto">
-		<h2>500 - 系统发生内部错误</h2>
-		<br />
-		<div>错误详细信息:</div>
-		<div class="alert-error">
-			<%=ex.getMessage()%><br />
-		</div>
+        <div>
+            <input type="button" value="返回" onclick="window.history.back()"/>
+            <input type="button" value="刷新" onclick="window.location.reload()"/>
+            <input type="button" value="首页" onclick="window.location.assign('${ctx}/index')"/>
+        </div>
+		<h2>系统发生业务错误</h2>
+		<br>
+		<div>错误代码:<%=bex.getErrorCode()%></div>
+		<div>错误信息:<%=bex.getErrorMsg()%></div>
 	</div>
 </body>
-</html>
+</html>

+ 23 - 0
gkaqv2/trunk/modules/web/src/main/webapp/WEB-INF/web.xml

@@ -85,4 +85,27 @@
 		<servlet-class>com.xt.js.gkaq.web.system.FrameInitServlet</servlet-class>
 		<load-on-startup>99</load-on-startup>
 	</servlet>
+
+	<!-- session过期时间 -->
+	<session-config>
+		<session-timeout>120</session-timeout>
+	</session-config>
+
+	<!-- 错误页面设置 -->
+	<error-page>
+		<exception-type>java.lang.Throwable</exception-type>
+		<location>/WEB-INF/view/error/500.jsp</location>
+	</error-page>
+	<error-page>
+		<error-code>500</error-code>
+		<location>/WEB-INF/view/error/500.jsp</location>
+	</error-page>
+	<error-page>
+		<error-code>404</error-code>
+		<location>/WEB-INF/view/error/404.jsp</location>
+	</error-page>
+	<error-page>
+		<error-code>403</error-code>
+		<location>/WEB-INF/view/error/403.jsp</location>
+	</error-page>
 </web-app>

+ 4 - 4
gkaqv2/trunk/modules/web/src/main/webapp/static/js/frame/org.js

@@ -158,14 +158,14 @@ function initGrid() {
                     hidden : true,
                     sortable : false
                 }, {
-                    name : 'name',
-                    index : 'name',
-                    sortable : false
-                }, {
                     name : 'code',
                     index : 'code',
                     sortable : false
                 }, {
+                    name : 'name',
+                    index : 'name',
+                    sortable : false
+                }, {
                     name : 'pid',
                     index : 'pid',
                     hidden : true,