要放假过端午呢在剩下的点时间里写点东西
之前有一篇文档
http://pengbaowei0311.iteye.com/blog/2302882
(comet4j 消息推送) 我接着从哪里说吧
comet4j 做为消息推送 但必须的有数据来源,数据来源我们直接在当前的接口服务类方法里封装吗?接口太多了,会累死人的,而且接口类还是别人写的,我不想改别人的东西,要不出现问题还以为是我搞的呢,哈哈,说笑呢,主要是怕动业务代码。
所以用aop最好呢,在不影响主业务的前提下还能实现记录日志的功能,接下来就开始做做吧
做一个功能我能首先要理清业务,接下来考虑技术,技术实现方式挺多,选择一种适合自己的。
AOP 就挺好,
找aop的工作包我用的maven 我直接写配置文件了 pom.xml
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.7.2</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.7.0</version> </dependency>
这里请注意下版本
准备工作做完之后,我们就得看看项目了,在结合自己的需求,看你到底需要记录那些信息,找出一个合 理的切面
切面:记得我学习AOP 时,对这概念挺模糊,说个切面不知道指什么,但项目中也经常出现,也就有自己 的理解了,面,平面,平面里有点,比如你要记录 ,增 ,删,改,查 你看到这些方法在哪个类里,你就可以拿这个类当切面,所以有时供你选择的切面就很多,比如在,控制层,在service ,dao层,也可以是个个工具类【可以匹配多个类】,但是你要记录的方法不能为静态方法,否则就切不进去。
切面的选择:选择方法参数与你要记录的数据有关的,尽量别有静态方法,静态方法的你抓不到。
找到切面后,我要就要写自己要记录的业务逻辑了。
新建一个类
@Component @Aspect public class AspectAdvice { @Autowired private SysLogServiceImpl sysLogServiceImpl; @Pointcut("execution(* org.hrwms.hwms.util.HwmsDrugManageHouse.*(..))") public void hwmsMethod() { } @Before(value = "hwmsMethod()") public void doBefore(JoinPoint jp) { System.out.println("qian zhi tong zhi "); /*获取到参数的集合*/ Object[] args = jp.getArgs(); for (int i = 0; i < args.length; i++) { Object object = args[0]; object.getClass(); } } // 异常通知 @AfterThrowing(value = "hwmsMethod()", throwing = "e") public void doThrow(JoinPoint jp, Throwable e) { SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); try { String format = formatter.format(new Date()); SysLogEntity sysLogEntity=new SysLogEntity(); sysLogEntity.setTransferTime(format); String name = jp.getSignature().getName(); sysLogEntity.setMethodName(name); sysLogEntity.setSourceName("1"); Object[] args = jp.getArgs(); if(args.length>0){ for (int i = 0; i < args.length; i++) { if(i==0){ String str =(String) args[0]; String replaceAll = str.replaceAll("<", "<").replaceAll(">", ">"); sysLogEntity.setIntXml(replaceAll); }else if(i==1){ HisInfoEntity object = (HisInfoEntity)args[1]; sysLogEntity.setFileUrl(object.getAddress()); }else if(i==3){ String code = (Integer)args[3]+""; sysLogEntity.setCode(code); if(name.equals("sendDrugStoreHouse")){ if(code.equals("101")){ sysLogEntity.setIntefaceName("药库入库"); }else if(code.equals("102")){ sysLogEntity.setIntefaceName("药库出库"); }else if(code.equals("103")){ sysLogEntity.setIntefaceName("药库退厂"); }else if(code.equals("104")){ sysLogEntity.setIntefaceName("药库退库"); }else if(code.equals("1101")){ sysLogEntity.setIntefaceName("门诊药房药品派送"); }else if(code.equals("1102")){ sysLogEntity.setIntefaceName("包药机药品派送"); } }else if(name.equals("sendDrugStoreHouse")){ if(code.equals("101")){ sysLogEntity.setIntefaceName("科室基本信息"); }else if(code.equals("102")){ sysLogEntity.setIntefaceName("职员基本信息"); }else if(code.equals("103")){ sysLogEntity.setIntefaceName("药典信息"); }else if(code.equals("104")){ sysLogEntity.setIntefaceName("药品供应商信息"); }else if(code.equals("105")||code.equals("106")){ sysLogEntity.setIntefaceName("药品请领单"); }else if(code.equals("1051")){ sysLogEntity.setIntefaceName("HIS请领(同步库存)"); }else if(code.equals("1052")){ sysLogEntity.setIntefaceName("门诊药房请领"); }else if(code.equals("1053")){ sysLogEntity.setIntefaceName("包药机请领"); }else if(code.equals("23")){ sysLogEntity.setIntefaceName("药库确认药房退库"); } } } } } sysLogEntity.setErrMsg(e.getMessage()); sysLogEntity.setFlag("0"); sysLogServiceImpl.insertSysLog(sysLogEntity); /*List<SysLogEntity> list = sysLogServiceImpl.findSysLog();*/ List<SysLogEntity> list=new ArrayList<SysLogEntity>(); list.add(sysLogEntity); JSONObject js=new JSONObject(); js.put("rows", list); js.put("total", list.size()); String string = JSONObject.fromObject(js).toString(); System.out.println(string); Comet4jUtil.sendMsgToClient(string); } catch (Exception e2) { } } }
加注解后就能找到这个类是切面编程要执行的类
@Component @Aspect
定义了一个切面 里边是个表达式,我这里只匹配到 HwmsDrugManageHouse 这个类的所有方法,也可以 限制方法,还可以加“||”在加一个表达式 hwmsMenthod 这可以自己定,下边应用时对应上就可以
@Pointcut("execution(* org.hrwms.hwms.util.HwmsDrugManageHouse.*(..))") public void hwmsMethod() { }
前置通知 value 值和上边对应上,也可以直接写表达式。
@Before(value = "hwmsMethod()")
异常通知 value 同上,多一个 e 也就是抛出的异常
@AfterThrowing(value = "hwmsMethod()", throwing = "e")
获取拦截方法的 参数值(这里就有你需要的数据了)
Object[] args = jp.getArgs();
后边的我就不说了,挺简单的
看看配置文件
spring.xml
我用的切面都是工具类,所以我把工具类都注入bean里边,有的时候直接从bean取出来,也可通过new 创建对象掉用方法
开启aop
<aop:aspectj-autoproxy proxy-target-class="true"/>
如果你用的不是springMvc 要将 你定义的类通过扫描假如到spring里
<!-- <context:component-scan base-package="org.hrwms.syslog.aop" /> -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>日志信息</title> <style type="text/css"> .progressBar { background: #FAFAFA url(../images/progressBar_m.gif) no-repeat center; } </style> <script src="<%=request.getContextPath() %>/js/comet4j.js"></script> //引入js以及css <script type="text/javascript"> function dataHandling(data,flag){ var datas = $.parseJSON(data); /* var datas = eval('(' + data + ')'); */ var olddata=datas.rows; var jsonArray=new Array(); var hospital = document.getElementsByName("hospital"); var values=""; for(var i=0; i<hospital.length; i++){ if(test[i].checked){ values=values+hospital[i].value+","; } } if(values.length>0){ values=values.substring(0, values.length-1); var arr=new Array(); arr=values.split(","); if(flag==2){ var jsonData=document.getElementById("jsonData"); var json= jsonData.value; var jsons = $.parseJSON(json); if(jsons!=null){ var oldJsons= jsons.rows; for(var i=0; i<oldJsons.length; i++){ olddata.push(oldJsons[i]); } } datas.rows=olddata; if(olddata.length>20){ jsonData.value=""; alert("当前错误已经超过20条,请尽快处理!"); } jsonData.value=JSON.stringify(datas); } for(var i=0; i<arr.length; i++){ for(var j=0; j<olddata.length; j++){ if(arr[i]==olddata[j].sourceName){ jsonArray.push(olddata[j]); } } } if(jsonArray.length>=100){ $.ajax({ type:"POST", url:"<%=request.getContextPath() %>/log.wms?clearData", success:function(data,state){ alert("数据库错误信息超过100条,系统自动清空!"); }, }); } datas.rows=jsonArray; $('#sysLog').datagrid('loadData', datas); } } </script> </head> <body> <div style="height: 100%;width: 100%"> <input id="yk" name="hospital" type="checkbox" value="1" />药库       <input id="mz"name="hospital" type="checkbox" value="2" />门诊       <input id="zy" name="hospital" type="checkbox" value="3" />住院       <input id="jsonData" type="hidden"> <div class="easyui-panel" title="出现错误" data-options ="iconCls:'icon-save',closable:true, collapsible:true,minimizable:true,maximizable:true,height:100px" style="height: 300px;"> <table id="sysLog" style=" height:100px" ></table> </div> <div class="easyui-panel" title="错误详情" style="height:250px" data-options="iconCls:'icon-save',collapsible:true,minimizable:true,maximizable:true"> <div id="errMsgs" style="margin-left: 10px;"></div> </div> </div> <script type="text/javascript"> $(function() { var toolbar = [{ iconCls:'icon-search', text:'查询详情', handler:function(){ var row = $('#sysLog').datagrid('getSelected'); if(row!=null){ var intXml=row.intXml; var errMsg=row.errMsg; var errMsgs = document.getElementById('errMsgs'); errMsgs.innerHTML="<b style='color: red'>进入数据:</b><code>"+intXml+"</code><br><hr>"+"<b style='color: red'>错误信息:</b>"+errMsg+"<hr>"; }else{ alert("请选择!"); } } },{ iconCls:'icon-remove', text:'清空数据', handler:function(){ var r=confirm("确认清空吗?"); if( r==true){ $.ajax({ type:"POST", url:"<%=request.getContextPath() %>/log.wms?clearData", success:function(data,state){ var jsonData=document.getElementById("jsonData"); jsonData.value=""; var json='{"total":0,"rows":[]}'; var datas = $.parseJSON(json); $('#sysLog').datagrid('loadData',datas); }, }); } } }]; $.ajax({ type:"POST", url:"<%=request.getContextPath() %>/log.wms?findSysLog", success:function(data,state){ dataHandling(data,1); }, error:function(e) { alert("出错:"+e); } }); $('#sysLog').datagrid({ iconCls:"icon-edit", singleSelect:true, fit:true, /* pagination:true, */ toolbar:toolbar, checkOnSelect:false, selectOnCheck:false, columns:[[ {field:'code',title:'编号(如:101)',align:'center',width:140}, {field:'intefaceName',title:'接口名称',align:'center',width:172}, {field:'transferTime',title:'传输时间',align:'center',width:142,sortable:"true"}, {field:'errMsg',title:'报错信息',align:'center',width:300}, {field:'fileUrl',title:'文件保存路径',align:'center',width:300}, {field:'intXml',title:'进入数据',align:'center',hidden:true,width:200,hidden:true}, {field:'methodName',title:'方法名',align:'center',width:200} ]] }); JS.Engine.on('hello', function(text){ dataHandling(text,2); }); JS.Engine.start('conn'); }); </script> </body> </html>
看看这个页面存在一个弊端,如果用缓存的话相对会好点,以后有时间再搞吧,有什么好的方案告诉下我哦。
补充:过了很长时间了,今天过来补充一点,对于上边页面的问题,在后边工作中我又遇到了,所以有想到了一种方法,就是将数据都保存在表格了边,用的时候再从表格里边拿出了接着用用完之后在将新数据保存到表格里,这样挺方便的。