paulwong

#

在AJAX中将FORM里面的元素以JSON方式提交

$('#formID').on('submit',function () {
    $.ajax({
        url: 'submit.php',
        cache: false,
        type: 'POST',
        data : $('#formID').serialize(),
        success: function(json) {
            alert('all done');
        }
    });
});

posted @ 2014-08-22 09:38 paulwong 阅读(599) | 评论 (0)编辑 收藏

曾国藩语录(摘)

-----------------曾国藩箴言(一)----------------



●轻财足以聚人,律己足以服人,量宽足以得人,身先足以率人。

【译文】轻视财物可以召集人,律己可以让人敬服,气量宽广可以得人心,自己亲身先做事可以领导人。



●惟正己可以化人,惟尽己可以服人。

【译文】只有端正自己可以感化别人,只有开放自己的心才可以服人。



●遇诡诈人变幻百端,不可测度,吾一以至诚待之,彼术自穷。

【译文】遇到诡秘狡诈的人变化百端,不可以猜测度量,我都用至诚心对待他,他的方法就没用了。



●功不独居,过不推诿。

【译文】有功劳不自己一个人占有,有过错不推脱。



●不可轻率评讥古人。

【译文】不可以轻易评论讥讽古人。



●今日所说之话,明日勿因小利害而变。

【译文】今天讲的话,明天不要因为小的利害就改变。



●遇棘手之际,须从耐烦二字痛下功夫。

【译文】遇到棘手的时候,要从耐烦这两个字上下功夫。



●勿以小恶弃人大美,勿以小怨忘人大恩。

【译文】不要因为别人小的坏处而放弃他大的优点,不要因为与别人小的仇怨而忘记他的恩情。





-----------------曾国藩箴言(二)--------------------



●责过太直,使人惭恨,在我便是一过。

【译文】指责过错过于直接,让别人生惭愧而痛恨自己,对我来说就是一种过错。



●受挫受辱之时,务须咬牙励志,蓄其气而长其智。

【译文】受到挫败和侮辱时,一定要咬紧牙忍受来激励志向,继续志气,增长智慧。



●行事不可任心,说话不可任口。

【译文】做事不可以随心所欲,说话不可以随口胡说。



●百种弊病,皆从懒生。

【译文】很多的弊病都是从懒惰生出的。



●守笃实,戒机巧,守强毅,戒刚愎。

【译文】谨守笃定老实,不要投机取巧,尽收刚强坚毅,不要刚愎自用。



●凡人做一事,便须全副精神注在此一事,不可见异思迁。

【译文】凡是有人要做一件事,就须把全副精神贯注在这件事上,不可以见异思迁。





---------------曾国藩箴言(三)---------------



●寡言养气,寡视养神,寡欲养精。

【译文】少说话可以休养元气,少看可以休养心神,减少欲望可以休养精气。



●礼义廉耻,可以律己,不可以绳人。

【译文】礼义廉耻,可以用来要求自己,却不能用来要求别人。



●利可共而不可独,谋可寡而不可众。独利则败,众谋则泄。

【译文】利益可以共享不可以独享,谋划可以让少数人知道不可以让多数人知道,独享利益就会失败,谋划让多数人知道就会泄露。



●久利之事勿为,众争之地勿往。物极则反,害将及矣。

【译文】能一直产生利益的事不要做,众人争夺的好地方不要去。物极必反,祸害就要来了。



●知足则乐,务贪必忧。

【译文】知足就会快乐,执着贪心就会忧虑。



●处事宜决断。

【译文】处理事情应该坚决果断。



●事到手且莫急,便要缓缓想。想得时切莫缓,便要急急行。

【译文】事情分配到手上先别急,要慢慢想。想到时不要拖延,要赶快做。



●尖酸语称快一时,当之者终身怨恨。

【译文】尖酸刻薄的话让你一时痛快,可对方却终身怨恨你。



●凡权要人声势赫然时,我不可犯其锋,亦不可与之狎,敬而远之,全身全名之道也。

【译文】凡是掌握权力的重要人物声名、势力非常大的时候,我们不要去触犯他的锋芒,也不可以和他交好。对他敬而远之,是保全自己名声、生命的方法。



●行事常思退一步。

【译文】做事常常要想到退让一步。



●慎言谨行,是修己第一事。

【译文】谨慎自己的言行,是修养自己德行的最重要的事。

posted @ 2014-08-20 11:06 paulwong 阅读(204) | 评论 (0)编辑 收藏

Logstash logo开源日志管理 Logstash

logstash日志处理采用队列ZMQ,压力会很好的被缓冲,针对高并发的大数据量的日志处理是没有问题的,日志利用ES存放,就是个基于lucene的全文检索数据库,也不存在数据量的问题。

logstash 是一个应用程序日志、事件的传输、处理、管理和搜索的平台。
你可以用它来统一对应用程序日志进行收集管理,提供 Web 接口用于查询和统计。

logstash screenshot

 

http://logstash.net/docs/1.4.2/tutorials/getting-started-with-logstash

posted @ 2014-08-20 09:22 paulwong 阅读(567) | 评论 (0)编辑 收藏

Spring对HttpSession的重新封闭

https://github.com/spring-projects/spring-session/tree/master/samples

posted @ 2014-08-19 09:13 paulwong 阅读(940) | 评论 (0)编辑 收藏

删除List中重复元素

方法一:循环元素删除
// 删除ArrayList中重复元素 
    public static void removeDuplicate(List list) {
        for (int i = 0; i < list.size() - 1; i++) {
            for (int j = list.size() - 1; j > i; j--) {
                if (list.get(j).equals(list.get(i))) {
                    list.remove(j);
                }
            }
        }
        System.out.println(list);
    }


方法二:通过HashSet剔除
// 删除ArrayList中重复元素 
    public static void removeDuplicate(List list) {
        Set set = new HashSet(list);
        list.clear();
        list.addAll(set);
        System.out.println(list);
    }


方法三: 删除ArrayList中重复元素,保持顺序
// 删除ArrayList中重复元素,保持顺序 
    public static void removeDuplicateWithOrder(List list) {
        Set set = new HashSet();
        List newList = new ArrayList();
        for (Iterator iter = list.iterator(); iter.hasNext();) {
            Object element = iter.next();
            if (set.add(element))
                newList.add(element);
        }
        list.clear();
        list.addAll(newList);
        System.out.println(" remove duplicate " + list);
    }

posted @ 2014-08-18 12:09 paulwong 阅读(1868) | 评论 (0)编辑 收藏

RESTful 最佳实践

     摘要: 除了传统对于远程调用的需求,近来移动开发对于api的规范化需要,restful作为一个流行的接口调用方式,值得深入了解。声明 本文属于转载:原文此文为实践总结,是自己在实践过程中积累的经验和"哲学"。部分内容参考相关资料,参考内容请看尾页。建议对RESTful有一定了解者阅读!"哲学"不要为了RESTful而RESTful在能表达清楚的情况下,简单就是美接口路径设计接口设计原则URI指向...  阅读全文

posted @ 2014-08-18 08:47 paulwong 阅读(6472) | 评论 (0)编辑 收藏

UML类图中的六大关系:泛化、实现、依赖、关联、聚合、组合关系

UML定义的关系主要有:泛化、实现、依赖、关联、聚合、组合,这六种关系紧密程度依次加强,分别看一下

1、泛化

概念:泛化是一种一般与特殊一般与具体之间关系的描述,具体描述建立在一般描述的基础之上,并对其进行了扩展。在程序中是通过继承类实现的。比如狗是对动物的具体描述,在面向对象设计的时候一般把狗设计为动物的子类。

表示方法:空心三角形箭头的实线,子类指向父类

image

2、实现

概念:实现是一种类与接口的关系,表示类是接口所有特征和行为的实现,在程序中一般通过类实现接口来描述

表示方法:空心三角形箭头的虚线,实现类指向接口

image

3、依赖

概念:是一种使用的关系,即一个类的实现需要另一个类的协助,所以要尽量不使用双向的互相依赖,在程序中一般表现为类A中的方法需要类B的实例作为其参数或者变量,而类A本身并不需要引用类B的实例作为其成员变量。

表示方法:虚线箭头,类A指向类B。

image

4、关联

概念:表示类与类之间的联接,它使一个类知道另一个类的属性和方法,这种关系比依赖更强、不存在依赖关系的偶然性、关系也不是临时性的,一般是长期性的,在程序中被关联类B以类属性的形式出现在关联类A中,也可能是关联类A引用了一个类型为被关联类B的全局变量

表示方法:实线箭头,类A指向类B

image

5、聚合

概念:聚合关联关系的一种特例,是强的关联关系。聚合是整体和个体之间的关系,即has-a的关系,整体与个体可以具有各自的生命周期,部分可以属于多个整体对象,也可以为多个整体对象共享。程序中聚合和关联关系是一致的,只能从语义级别来区分;

表示方法:尾部为空心菱形的实线箭头(也可以没箭头),类A指向类B

image

 

6、组合

概念:组合也是关联关系的一种特例。组合是一种整体与部分的关系,即contains-a的关系,比聚合更强。部分与整体的生命周期一致,整体的生命周期结束也就意味着部分的生命周期结束,组合关系不能共享。程序中组合和关联关系是一致的,只能从语义级别来区分。

表示方法:尾部为实心菱形的实现箭头(也可以没箭头),类A指向类B

image

posted @ 2014-08-08 08:18 paulwong 阅读(398) | 评论 (0)编辑 收藏

架构师的职责

    近来看到CSDN上有个CTO俱乐部,里面聊得是不亦乐乎。我怀着无比崇敬的态度,拜读了一下牛人们的发言。

里面有个哥们发起一个话题:

“CTO, 你多久没有写程序了?”。
有人回答:“不写代码的CTO,属于......这公司问题大了!”。

看到这里,我就赶紧撤了,怕忍不住反驳几句,反而遭到牛人们的群殴。试想,一个上点规模的IT公司,还得靠CTO来写程序的话,那是不是才叫问题大了呢。当然,我没有做过CTO,所以我有我的不同看法,而且还愿意表达出来,无知者无畏。我情愿相信:我所理解的CTO跟这位CTO所理解的是两回事。所以我想,如果有人能把CTO的职责给标准化了,也许就不会有这么多的争论了。

    同样的道理,关于架构师的定义,大家也有着不同的理解。什么是架构师?架构师有哪些职责?我觉得有必要提前明确一下,要不然大家沟通起来也会产生类似问题,子说子理,卯说卯理,但是压根说得不是一码子事。
 
0.1 什么是架构师

曾经有这么个段子:
甲:我已经应聘到一家中型软件公司了,今天上班的时候,全公司的人都来欢迎我。
乙:羡慕ing,都什么人来了?
甲:CEO、COO、CTO、All of 程序员,还有会计、司机都来了。
乙:哇,他们太重视你了,人才啊,这么多人迎接你!
甲:没有啊,就一个人!
乙:靠,#%¥$%...

    很多的创业公司,一人身兼数职的情形还是很常见的。至少,我是经历过的,一个人包办了所有的开发过程,连测试我都做了,绝对的一条龙,但是经常踩钢丝、骑独轮车总会有失足的时候,结果有一次,从我手里发出去的光盘母盘,含有病毒僵尸,以至于被迫收回已经推上市场的2万张光盘,从那之后,我的心脏就开始变得无比坚强,现在就是整个后台服务都瘫痪了,我也只是微微一笑。其实,一个人身兼架构师和程序员,甚至多种角色,没什么不妥,后面还会讲这个话题,这种现象不是中国特色,跟国外是完全接轨的。我曾经跟米国的一个工程师在msn中聊过类似的话题,发现他们的路子跟咱们没什么不同,在IT这个行业,我们跟世界的差距只有1天,他们刚弄出来的新东西,我们这里第2天保准见得到。

    架构师这个称呼不是拍脑袋想出来的,是有国际标准(ISO/IEC 42010)可查的。架构师是软件开发活动中的众多角色之一,它可能是一个人、一个小组,也可能是一个团队。微软对架构师有一个分类参考,我们参考一下,他们把架构师分为4种:企业架构师EA(Enterprise Architect)、基础结构架构师IA(Infrastructure Architect)、特定技术架构TSA(Technology-Specific Architect)和解决方案架构师SA (Solution Architect)。微软的这个分类是按照架构师专注的领域不同而划分的。

    EA的职责是决定整个公司的技术路线和技术发展方向。盖茨给自己的Title就是首席软件架构师,网易丁磊也喜欢这么称呼自己,实际上就是EA角色;IA的工作就是提炼和优化技术方面积累和沉淀形成的基础性的、公共的、可复用的框架和组件,这些都是一个技术型公司传承下来的最宝贵的财富之一;特定技术架构师TSA,他们主要从事类似安全架构、存储架构等专项技术的规划和设计工作;SA的工作则专于解决方案的规划和设计,“解决方案”这个词在中国已经到了严重泛滥的程度,大忽悠们最喜欢把它挂在嘴边。所谓解决方案,就是把产品、技术或理论,不断地进行组合,来创造出满足用户需求的选择。售前工程师一般都是带着它到客户那里去发挥的。

    大公司会把各种类型的架构师分得很清楚,小公司一般就不那么讲究了,架构师多数是是IA+TSA+SA,一人包打天下,所以说大公司出专才,小公司出全才。

    实际工作中,我们也经常会见到另一种比较简单的分类方式,把架构师分为软件架构师和系统架构师。软件架构师基本上是TSA+IA,这也是程序员最容易突破,最可能走上的一条道路,比如JAVA架构师、DotNet架构师、LAPM架构师等等,我后面所讲的内容都是与软件架构师的相关的话题。系统架构师实际上是SA+TSA,更着力于综合运用已有的产品和技术,来实现客户期望的需求。系统架构师要求通晓软、硬件两方面的知识,所以它的知识体系相对庞杂。关于系统架构师的话题,我们可以稍后再作讨论。
 
0.2 架构师的职责

      架构师需要参与项目开发的全部过程,包括需求分析、架构设计、系统实现、集成、测试和部署各个阶段,负责在整个项目中对技术活动和技术说明进行指导和协调。 
架构师主要职责有4条: 

1、确认需求
    在项目开发过程中,架构师是在需求规格说明书完成后介入的,需求规格说明书必须得到架构师的认可。架构师需要和分析人员反复交流,以保证自己完整并准确地理解用户需求。

2、系统分解


    依据用户需求,架构师将系统整体分解为更小的子系统和组件,从而形成不同的逻辑层或服务。随后,架构师会确定各层的接口,层与层相互之间的关系。架构师不仅要对整个系统分层,进行“纵向”分解,还要对同一逻辑层分块,进行“横向”分解。
    软件架构师的功力基本体现于此,这是一项相对复杂的工作。

3、技术选型


    架构师通过对系统的一系列的分解,最终形成了软件的整体架构。技术选择主要取决于软件架构。
Web Server运行在Windows上还是Linux上?数据库采用MSSql、Oracle还是Mysql?需要不需要采用MVC或者Spring等轻量级的框架?前端采用富客户端还是瘦客户端方式?类似的工作,都需要在这个阶段提出,并进行评估。

架构师对产品和技术的选型仅仅限于评估,没有决定权,最终的决定权归项目经理。架构师提出的技术方案为项目经理提供了重要的参考信息,项目经理会从项目预算、人力资源、时间进度等实际情况进行权衡,最终进行确认。

4、制定技术规格说明
   
    架构师在项目开发过程中,是技术权威。他需要协调所有的开发人员,与开发人员一直保持沟通,始终保证开发者依照它的架构意图去实现各项功能。
   
    架构师与开发者沟通的最重要的形式是技术规格说明书,它可以是UML视图、Word文档,Visio文件等各种表现形式。通过架构师提供的技术规格说明书,保证开发者可以从不同角度去观察、理解各自承担的子系统或者模块。
架构师不仅要保持与开发者的沟通,也需要与项目经理、需求分析员,甚至与最终用户保持沟通。所以,对于架构师来讲,不仅有技术方面的要求,还有人际交流方面的要求。


0.3 架构师的误区

1、架构师就是项目经理


    架构师不是项目经理。项目经理侧重于预算控制、时间进度控制、人员管理、与外部联系和协调等等工作,具备管理职能。一般小型项目中,常见项目经理兼架构师。

2、架构师负责需求分析


    架构师不是需求分析员。需求分析人员的工作是收集需求和分析需求,并与最终用户、产品经理保持联系。架构师只对最终的需求审核和确认,提出需求不清和不完整的部分,他会跟需求分析员时刻保持联系。架构师是技术专家,不是业务专家。

3、架构师从来不写代码

    这是一个尚存争论的问题。目前有两种观点:
观点1:架构师不写代码,写代码纯体力活,架构师写代码大材小用。架构师把UML的各种视图交给开发人员,如果有不明确的地方,可以与架构师随时沟通。
观点2:架构师本来自于程序员,只是比程序员站的层面更高,比程序员唯一多的是经验和知识,所以架构师也免不了写代码。

    我个人觉得这两种说法是与架构师的出身和所处的环境有关。

    架构师首先是一个技术角色,所以一定是来自于技术人员这个群体,比如系统架构师,多是来自于运维人员,可能本身代码写得并不多,或者说写不出来很漂亮的代码。软件架构师多是来自于程序员,有着程序员的血统和情怀,所以在项目开发过程中,可能会写一些核心代码。我们的理想是架构师不用写代码,但事实上有时候过于理想。架构师写不写代码,可能取决于公司的规模、文化、开发人员的素质等现实情况。另外,架构师也不是跟程序员界限分得那么清楚,按照能力也有高中低之分,写不写代码不是区分两者的根本标准。

0.4 架构师的基本素质

周星驰有个片子《喜剧之王》,剧中的尹天仇整天揣着本《演员的自我修养》,一个好演员不仅需要天赋,也需要一定的理论指导,无师自通的人毕竟是少数。架构师的成长过程也是这样。从普通程序员到高级程序员,再到架构师,是一个经验积累和思想升华的过程。经验积累是一个方面,素质培养是另一个方面,两者相辅相成,所以我觉得有必要把架构师的所要具备的素质罗列一下,作为程序员努力的方向。

1、沟通能力

    为了提高效率,架构师必须赢得团队成员、项目经理、客户或用户认同,这就需要架构师具有较强的沟通能力。沟通能力是人类最普遍性的素质要求,技术人员好像容易忽略,想成为架构师就不能忽略。千万不要抱着这样的观念:怀才跟怀孕似的,时间久了总会被人发现的。还是天桥上卖大力丸的哥们说得对:光说不练假把式,光练不说傻把式。看看你周围的头头脑脑们,哪一个不是此中高手,我们千万不要鄙视,认为这是阿谀奉承、投机钻营,凡事都要看到积极的一面,“沟通”的确是一种能力。我认为自己是一个略内向的人,因为我是农村出来的孩子,普通话都说不好,以前或多或少带有点自卑感,幻想着是金子总会发光,所以在职业生涯中吃了不少亏。现在,我深深懂得了沟通的重要性,我会很主动地跟同事们,跟老大们不定时地沟通,感觉工作起来顺畅多了。

    这一条我认为最为重要,所以排在首位。我甚至认为下面几条都可以忽略,唯一这一条得牢记,而且要常常提醒自己。

2、领导能力

    架构师能够推动整个团队的技术进展,能在压力下作出关键性的决策,并将其贯彻到底。架构师如何来保证这种执行力?这就需要架构师具有领导能力。

    架构师的领导能力的取得跟项目经理不太一样。项目经理主要负责解决行政管理,这种能力与技术关系不大,他有人权和财权,再扯上一张“领导”的虎皮,采用“胡萝卜加大棒”的方式,基本上可以保证执行力。架构师在项目里面可能更多地使用非正式的领导力,也就是我们常说的影响力,里面包括个人魅力、技术能力、知识传递等等。

3、抽象思维和分析能力

    架构师必须具备抽象思维和分析的能力,这是你进行系统分析和系统分解的基本素质。只有具备这样的能力,架构师才能看清系统的整体,掌控全局,这也是架构师大局观的形成基础。你如何具备这种能力呢?一是来自于经验,二是来自于学习。架构师不仅要具备在问题领域上的经验,也需要具备在软件工程领域内的经验。也就是说,架构师必须能够准确得理解需求,然后用软件工程的思想,把需求转化和分解成可用计算机语言实现的程度。经验的积累是需要一个时间过程的,这个过程谁也帮不了你,是需要你去经历的。但是,如果你有意识地去培养,不断吸取前人的经验的话,还是可以缩短这个周期的。这也是我写作此系列的始动力之一。

4、技术深度和广度

   架构师最好精通1-2个技术,具备这种技术能力可以更加深入的理解有关架构的工作原理,也可以拉近和开发人员的距离,并形成团队中的影响力。

   架构师的技术知识广度也很重要,需要了解尽可能多的技术,所谓见多识广,只有这样,才可能综合各种技术,选择更加适合项目的解决方案。有的人说,架构师技术广度的要求高于技术深度的要求,这是很有道理的。

总而言之,一句话:架构师是项目团队中的技术权威。

posted @ 2014-08-05 18:35 paulwong 阅读(385) | 评论 (0)编辑 收藏

自定义注释与操作行为记录

自定义注释就是一个标记,一个信息收集器,如果配合SPRING的AOP使用,可以记录用户的操作行为。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 新增的用法:@Audit(behaviour="新增了专题", 
 *            value="#{args[0].colSubject}")
 *
 * 修改的用法:@Audit(behaviour="修改了专题", id="#{args[0].colSubject.id}", 
 *            className="com.paul.program.colsubject.valueobject.ColSubject",
 *            value="#{args[0].colSubject}")
 *
 * 删除的用法:@Audit(behaviour="删除了专题", id="#{args[0].colSubject.id}"
 *             className="com.paul.program.colsubject.valueobject.ColSubject")
 *             
 * 
@author PAUL
 *
 
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Audit {
    
    String id() default "";
    String className() default "";
    String collectionName() default "";
    String value() default "";
    String behaviour();

}


值对象
AuditData.java
package com.paul.common.audit;

import java.io.Serializable;
import java.util.Date;

import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import com.paul.common.util.jackson.CustomJsonDateSerializer;

@Document(collection = "auditdata")
public class AuditData implements Serializable{

    private static final long serialVersionUID = -4011585863836336249L;
    
    @Id
    private String id;
    
    @CreatedBy
    @Field("userid")
    @JsonProperty("userid")
    private String userId;
    
    @CreatedDate
    @Field("createdate")
    @JsonProperty("createdate")
    @JsonSerialize(using = CustomJsonDateSerializer.class)
    private Date createDate;
    
    private String behaviour;
    
    @Field("newvalue")
    @JsonProperty("newvalue")
    private String newValue;
    
    @Field("oldvalue")
    @JsonProperty("oldvalue")
    private String oldValue;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public String getBehaviour() {
        return behaviour;
    }

    public void setBehaviour(String behaviour) {
        this.behaviour = behaviour;
    }


    public String getNewValue() {
        return newValue;
    }

    public void setNewValue(String newValue) {
        this.newValue = newValue;
    }

    public String getOldValue() {
        return oldValue;
    }

    public void setOldValue(String oldValue) {
        this.oldValue = oldValue;
    }

    public String toString() {
        return "AuditData [id=" + id + ", userId=" + userId + ", createDate="
                + createDate + ", behaviour=" + behaviour + ", newValue="
                + newValue + ", oldValue=" + oldValue + "]";
    }
    

}


RootObject.java
package com.paul.common.audit;

public class RootObject {

    private final Object[] args;

    private final Object invokedObject;

    private final Object returned;

    private final Throwable throwned;

    public RootObject(Object invokedObject, Object[] args, Object returned, Throwable throwned) {
        super();
        this.invokedObject = invokedObject;
        this.args = args;
        this.returned = returned;
        this.throwned = throwned;
    }

    public Object[] getArgs() {
        return args;
    }

    public Object getInvokedObject() {
        return invokedObject;
    }

    public Object getReturned() {
        return returned;
    }

    public Throwable getThrowned() {
        return throwned;
    }

}


TemplateParserContext.java
package com.paul.common.audit;

import org.springframework.expression.ParserContext;

public class TemplateParserContext implements ParserContext {

    public String getExpressionPrefix() {
        return "#{";
    }

    public String getExpressionSuffix() {
        return "}";
    }

    public boolean isTemplate() {
        return true;
    }
}


获取用户ID
package com.paul.common.audit.aware;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.AuditorAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import com.paul.common.constant.Constants;
import com.paul.program.account.valueobject.Account;

@Component
public class MyAppAuditor implements AuditorAware<String> {
    
    private static Logger logger = LoggerFactory.getLogger(MyAppAuditor.class);

    // get your user name here
    public String getCurrentAuditor() {
        
        String result = "N/A";
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                    .getRequestAttributes()).getRequest();
            Account account = (Account)request.getSession().getAttribute(Constants.USER_INFO);
            result = account.getLoginName();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }
}


切面
package com.paul.common.audit.interceptor;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParseException;
import org.springframework.expression.ParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.stereotype.Component;

import com.paul.common.audit.AuditData;
import com.paul.common.audit.AuditDataRequest;
import com.paul.common.audit.RootObject;
import com.paul.common.audit.TemplateParserContext;
import com.paul.common.audit.annotation.Audit;
import com.paul.common.audit.service.AuditDataService;
import com.paul.common.util.StringUtils;

@Component
@Aspect
public class AuditAspect {
    
    private static Logger logger = LoggerFactory.getLogger(AuditAspect.class);
    
    @Autowired
    private AuditDataService auditDataService;
    
    @Autowired
    private MongoTemplate mongoTemplate;
    
    private SimpleDateFormat dateFormatPrototype = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private Map<String, Expression> expressionCache = new ConcurrentHashMap<String, Expression>();

    private ExpressionParser expressionParser = new SpelExpressionParser();

    private ParserContext parserContext = new TemplateParserContext();
    

    protected static void appendThrowableCauses(Throwable throwable, String separator, StringBuilder toAppendTo) {
        List<Throwable> alreadyAppendedThrowables = new ArrayList<Throwable>();

        while (throwable != null) {
            // append
            toAppendTo.append(throwable.toString());
            alreadyAppendedThrowables.add(throwable);

            // cause
            Throwable cause = throwable.getCause();
            if (cause == null || alreadyAppendedThrowables.contains(cause)) {
                break;
            } else {
                throwable = cause;
                toAppendTo.append(separator);
            }
        }
    }
    
    private String getValueByEl(String template, Object invokedObject, Object[] args, Object returned, Throwable throwned)
    {
        String result = "N/A";
        if(StringUtils.isBlank(template))
            return result;
        try {
            Expression expression = expressionCache.get(template);
            if (expression == null) {
                expression = expressionParser.parseExpression(template, parserContext);
                expressionCache.put(template, expression);
            }

            Object evaluatedMessage = expression.getValue(new RootObject(invokedObject, args, returned, throwned), Object.class);
            result = evaluatedMessage.toString();
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        } catch (EvaluationException e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }


    protected AuditData buildAuditData(Audit auditAnnotation, Object invokedObject, Object[] args, Object returned, Throwable throwned, long durationInNanos) {
        
        AuditData auditData = new AuditData();
        auditData.setBehaviour(auditAnnotation.behaviour());
        String id = this.getValueByEl(auditAnnotation.id(), invokedObject, args, returned, throwned);
        auditData.setOldValue(this.getOldValueToString(id, auditAnnotation.className()));
        try {
            String newValue = this.getValueByEl(auditAnnotation.value(), invokedObject, args, returned, throwned);
            auditData.setNewValue(newValue);

            StringBuilder msg = new StringBuilder();

            SimpleDateFormat simpleDateFormat = (SimpleDateFormat) dateFormatPrototype.clone();
            msg.append(simpleDateFormat.format(new Date()));
//            auditData.setCreateDate(simpleDateFormat.format(new Date()));

            msg.append(" ").append(newValue);

            if (throwned != null) {
                msg.append(" threw '");
                appendThrowableCauses(throwned, ", ", msg);
                msg.append("'");
            }
            msg.append(" by ");
            String user = this.getUser();
            if (user == null) {
                user = "anonymous";
            } 
            msg.append(" in ") .append(TimeUnit.MILLISECONDS.convert(durationInNanos, TimeUnit.NANOSECONDS)).append(" ms");
            return auditData;
        } catch (Exception e) {
            /*StringBuilder msg = new StringBuilder("Exception evaluating template '" + template + "': ");
            appendThrowableCauses(e, ", ", msg);
*/
            return auditData;
        }
    }
    
    private String getOldValueToString(/*ProceedingJoinPoint proceedingJoinPoint,*/ String id, String className) 
    {
        String result = "N/A";
        /*String id = "5385be613d2a47eec07c53d4";
        try {
            MethodSignature methodSig = (MethodSignature) proceedingJoinPoint.getSignature();
            Object target = proceedingJoinPoint.getTarget();
            Object newValue = proceedingJoinPoint.getArgs()[0];
            String findMethodName = "findOne";
            Object oldValue=null;
            Method findMethod = target.getClass().getDeclaredMethod(findMethodName, (Class<?>[])null);
            oldValue = findMethod.invoke(target, (Object[]) null);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
*/
        if(StringUtils.isBlank(id) || StringUtils.isBlank(className))
            return result;
        
        try {
            Object object = mongoTemplate.findById(id, Class.forName(className));
            result = ToStringBuilder.reflectionToString(object,  ToStringStyle.SHORT_PREFIX_STYLE); 
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return result;
    }
    
//    @Around("execution(* com.paul..**.repository..*(..))")
    @Around("@annotation(auditAnnotation)")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint, Audit auditAnnotation) throws Throwable {
        
        boolean ok = false;
        Object o = null;
        AuditData auditData = null;
        try 
        {
            auditData = buildAuditData(auditAnnotation, proceedingJoinPoint.getThis(), 
                    proceedingJoinPoint.getArgs(), 
                    o, null, 10);
            o = proceedingJoinPoint.proceed();
            ok = true;
            return o;
        } 
        finally 
        {
            if (ok)
            {
//                String value = (MessageFormat.format(auditAnnotation.value(), proceedingJoinPoint.getArgs()));
                try 
                {
                    AuditDataRequest auditDataRequest = new AuditDataRequest();
                    auditDataRequest.setAuditData(auditData);
                    auditDataService.addAuditData(auditDataRequest);
                    logger.info(auditData + "");
                } 
                catch (Exception e) 
                {
                    logger.error(e.getMessage(), e);
                }
            }    
        }
    }
    
    private String getUser()
    {
        return "Paul";
    }
    

}


保存至数据库
package com.paul.common.audit.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import com.paul.common.audit.AuditData;
import com.paul.common.audit.AuditDataRequest;
import com.paul.common.audit.annotation.Audit;
import com.paul.common.audit.repository.AuditDataRepository;
import com.paul.program.colsubject.valueobject.ColSubjectRequest;

@Service
public class AuditDataService {
    
    @Autowired
    private AuditDataRepository auditDataRepository;
    
//    @Audited(message = "save(#{args[0].name}, #{args[0].email}): #{returned?.id}")
    @Audit(behaviour="修改了审计", id="#{args[0].colSubject.id}", 
            className="com.paul.program.colsubject.valueobject.ColSubject",
            value="#{args[0].colSubject}")
    public void saveObject(ColSubjectRequest colSubjectRequest)
    {
        
    }
    
    @Audit(behaviour="删除了专题", id="#{args[0]}",
             className="com.paul.program.subject.valueobject.Subject")
    public void delete(String id) {
    }
    
    @Audit(behaviour="新增了专题", value="#{args[0].colSubject}")
    public void add(ColSubjectRequest colSubjectRequest) {
    }
    
    public AuditData addAuditData(AuditDataRequest auditDataRequest)
    {
        return auditDataRepository.save(auditDataRequest.getAuditData());
    }
    
    public Page<AuditData> findAll(AuditDataRequest auditDataRequest)
    {
        Page<AuditData> page = auditDataRepository.findAll(auditDataRequest.getPageable());
        return page;
    }

}


DAO
package com.paul.common.audit.repository;

import org.springframework.data.repository.PagingAndSortingRepository;

import com.paul.common.audit.AuditData;

/**
 * 审计
 * 
 
*/
public interface AuditDataRepository extends PagingAndSortingRepository<AuditData, String>{
    
}

posted @ 2014-07-25 14:56 paulwong 阅读(1365) | 评论 (0)编辑 收藏

推荐系统开源软件列表

收集和整理了目前互联网上能找到的和推荐系统相关的开源项目

posted @ 2014-07-23 20:51 paulwong 阅读(346) | 评论 (0)编辑 收藏

仅列出标题
共112页: First 上一页 43 44 45 46 47 48 49 50 51 下一页 Last