- 浏览: 1277045 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
最后的攻城狮:
这也太乱了
mybatis与spring事物处理日志 -
leo_soul:
现在不能跨1级域名了吧?比如www.aaa.com,www.b ...
Cookie跨域操作 -
zy976133:
怎么解决的
jaxws不支持SOAPBinding.Use.ENCODED -
cuiyaoqiang:
你好 开发一个http接口给fs调用 ,这个http接口是自己 ...
freeswitch 动态加载号码 -
Jackromer:
请问楼主知道如何通过主控方来删除与其有关的中间表记录? 谢谢, ...
hibernate 多对多只删除中间表数据
项目刚刚换了web层框架,放弃了struts2改用spring3mvc
当初还框架的时候目的比较单纯---springmvc支持rest,小生对restful url由衷的喜欢
不用不知道 一用就发现开发效率确实比struts2高
我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置
spring3 mvc可以认为已经100%零配置了(除了配置springmvc-servlet.xml外)
比较了一下strus2与spring3 mvc的差别
============================================
struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入
struts2实际上是通过setter getter方法与request打交道的
struts2中,一个Action对象对应一个request上下文
spring3 mvc不同,spring3mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去
在spring3mvc中,一个方法对应一个request上下文
好了 我们来整理一下
struts2是类级别的拦截, 一个类对应一个request上下文,
springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应
所以说从架构本身上 spring3 mvc就容易实现restful url
而struts2的架构实现起来要费劲
因为struts2 action的一个方法可以对应一个url
而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了
===================================
spring3mvc的方法之间基本上独立的,独享request response数据
请求数据通过参数获取,处理结果通过ModelMap交回给框架
方法之间不共享变量
而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的
这不会影响程序运行,却给我们编码 读程序时带来麻烦
====================================
spring3 mvc的验证也是一个亮点,支持JSR303
处理ajax的请求更是方便 只需一个注解@ResponseBody ,然后直接返回响应文本即可
附上一段代码
楼上,从很早以前开始,除非是连接池这种每次创建代价很大的少数pool,对象池模式早就不再需要了。
我不否认,struts2看起来更加OO, 并且可以从中获得很多好处,比如拦截器中直接操作实例变量,实例变量上可以直接添加scope可读性更好。但是用是不是OO来决定一个框架是否优秀还是显得片面。
Spring MVC对于请求-相应模式更直接点,参数输入,处理,ModelMap输出,每个方法之间不互相干扰。这样很多方法可以放一起,比如一个CustomerController就可以解决所有customer相关请求,这里的customerController不是一个业务上的概念,可以看成是Customer的EndPoint,用于提供基于url请求的服务。
反之,用struts2改写这个类就会出现过多实例变量,所以,就必须合理的设计struts2的action。所以,个人认为struts2的使用上更为复杂些。我并不是想搬到Struts2, 但是我想通过这些讨论,找出Struts2,Spring MVC2者设计理念的差别以及最佳实践和适用范围。讨论的过程也是学习的过程,当然你没有耐心赐教,我也没办法。
现在明白你为什么那么急冻,那么贬低springmvc了
如果仅仅因为springmvc不够OO而武断的主观的说它不好是不可取的
springmvc采取的是动态绑定参数的方式,而struts2是静态的方式
这也就决定了springmvc无法做到OO,但正是这种动态提高了开发效率,受很多开发者的欢迎
struts2确实很OO, 但也带来了前面讨论的那些问题
我个人认为web层框架的趋势是springmvc或者说动态绑定参数型框架
淡定
一共5行代码,有2行和你关注的内容无关,你认为这两行代码有存在的必要吗?这就和你在Service层去显示调用transaction.begin()或者transaction.commit()有什么分别?
有必要的,我确实关注需要输出那些,不要输出什么内容。动不动输出整个Action的实例变量给View调用,让我在写View的时候很迷茫。
在Action中使用属性,使得一个Action更像一个JavaBean,可以使得测试更加容易。同时,这才是真正的面向对象的编程,一个拥有属性和方法的类,而不是只有方法。如果我们关注一下Spring的主要编程思想,Spring中的所有的Bean,其实都是在往具备丰富属性加方法的趋势发展的。Struts2的Action天然就是一个JavaBean,你居然能够说出这两个属性很恶心的话来,我不能理解你的想法。
。。。
Struts2有很多插件,官方网站上你可以查找一下。
同意你对struts的action更oo的说法,确实是这么回事,spring mvc和struts1的action就是过程式的处理。所以我说spring mvc和struts2是2个方向,我不觉得spring mvc的做法更糟糕。
一共5行代码,有2行和你关注的内容无关,你认为这两行代码有存在的必要吗?这就和你在Service层去显示调用transaction.begin()或者transaction.commit()有什么分别?
在Action中使用属性,使得一个Action更像一个JavaBean,可以使得测试更加容易。同时,这才是真正的面向对象的编程,一个拥有属性和方法的类,而不是只有方法。如果我们关注一下Spring的主要编程思想,Spring中的所有的Bean,其实都是在往具备丰富属性加方法的趋势发展的。Struts2的Action天然就是一个JavaBean,你居然能够说出这两个属性很恶心的话来,我不能理解你的想法。
拦截器做什么事情?我用拦截器做的事情太多了。拦截器的一个很大的作用就是精简与业务逻辑调用无关的恶心代码。至于你说的是否简洁、配置是否一致、是否符合直觉,我更加不能理解了,从任何角度来说,Struts2都能满足你的这3点。
Struts2有很多插件,官方网站上你可以查找一下。
你所谓的省掉两行代码,只不过是把那两个值付给了action的属性而已,而且它们也不是“不需要关注的内容”,它们恰恰是这里的业务逻辑,
transaction.begin()和commit()显然不属于业务逻辑,区别非常的大,一黑一白。
如果面向对象让我的日子难过,我会毫不犹豫的丢掉面向对象。我们还是少搞一些宗教,多一些务实的好。
我当然知道拦截器做什么,但我看不出有什么拦截器需要做的工作会由于只能拦截参数、返回值而变得不能做了,所以,还是请你列举出典型场景。
前面也说了,那两行代码属于业务逻辑,跟拦截器没什么关系,也不需要劳驾拦截器去精简,并且ww那个做法也没有精简。
我说的“是否简洁、配置是否一致、是否符合直觉 ”指的是ww/struts2把局部变量搞成实例变量这种做法。
我倒觉得# Account account;
# List<Group> groupList;
这两个属性很恶心。
确实恶心,都不知道用来输入,还是输出的,也不知道在哪个方法里面调用。
当你把多个功能写到一个action里面的时候,实例变量带来的只是混乱。
一共5行代码,有2行和你关注的内容无关,你认为这两行代码有存在的必要吗?这就和你在Service层去显示调用transaction.begin()或者transaction.commit()有什么分别?
在Action中使用属性,使得一个Action更像一个JavaBean,可以使得测试更加容易。同时,这才是真正的面向对象的编程,一个拥有属性和方法的类,而不是只有方法。如果我们关注一下Spring的主要编程思想,Spring中的所有的Bean,其实都是在往具备丰富属性加方法的趋势发展的。Struts2的Action天然就是一个JavaBean,你居然能够说出这两个属性很恶心的话来,我不能理解你的想法。
拦截器做什么事情?我用拦截器做的事情太多了。拦截器的一个很大的作用就是精简与业务逻辑调用无关的恶心代码。至于你说的是否简洁、配置是否一致、是否符合直觉,我更加不能理解了,从任何角度来说,Struts2都能满足你的这3点。
Struts2有很多插件,官方网站上你可以查找一下。
第一,没看出来spring的aop拦截限制了什么应用了,我的输入输出都在参数和返回值上,为什么还需要其他拦截,你能拿出什么实际的例子让spring mvc做起来很难受的么?另外,说起spring aop天然支持aop有什么错,spring aop的后面是aspectj,对于领域对象的注入和拦截也是可以靠aspectJ搞定的。
第二,难道Spring MVC执行层次不多,定制化不强?可插入url的解析,多种view的支持,Spring Webflow,Security集成被你无视了。
第三,不认为Struts2在技术上完胜,struts2走了和Spring MVC不同的路,这个才是关键,而我觉得它现在是个半成品。论优雅,可以去学习JSF.
拦截器拦截的内容仅仅限制于参数和返回值是一件令人头疼的事情,这就意味着你的拦截器代码不可避免的要和这些内容去打交道。也就是说,一旦我要在里面加一些特殊的逻辑,比如根据参数或者返回值中的某个字段进行逻辑判断,就会使得你的拦截器依赖于特定的切面而变得毫无意义。
在这其中我们可以看到:
这两句话纯粹就是多余的。一共5行code,有2行在为返回输出做准备。你还能厚着脸皮说SpringMVC解放了你的生产力?
在Struts2中,代码就会变成这样:
你所需要关注的,只是你的业务逻辑调用,而无需关心返回到底是什么名称,更不用提什么显示调用map.put这种恶心的代码了。
再问,你能用你所谓Spring的AOP把map.put这两行code给省略了嘛?所有的返回的内容都是局部变量,你去拦截啊?无能为力了吧。
至于说到什么url解析,多view的支持,SpringMVC的支持也仅仅限于支持而已,这些所谓的支持,成熟的Web层框架全部都有。所谓的Annotation带来的配置简化,本身就是一个伪命题。@RequestMapping(value="/whitelist/{whiteListId}/del")这种看上去优雅的实现,其实带来的问题却是致命的。这一点我很早就已经指出过。你可以翻看我以前的帖子。
SpringMVC充其量也就是一个简单的Web层的Mapping工具,要谈到综合性的Web层解决方案,它还差得很远。Struts2本身的设计思想和实现是所有MVC框架中最先进的。它也有很多问题,但是至今为止我还没有找到足够的证据来说明它的问题。所以希望大家在抱怨的同时,仔细想想你的观点是否真的站得住脚。
Struts2有一个Scope插件,可以轻松实现wizard:https://cwiki.apache.org/S2PLUGINS/scope-plugin.html
如果连扩展点都不值得炫耀,那么真的没什么可以炫耀的了。
继续做web吧,其他方向未必好。
当初还框架的时候目的比较单纯---springmvc支持rest,小生对restful url由衷的喜欢
不用不知道 一用就发现开发效率确实比struts2高
我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置
spring3 mvc可以认为已经100%零配置了(除了配置springmvc-servlet.xml外)
比较了一下strus2与spring3 mvc的差别
============================================
struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入
struts2实际上是通过setter getter方法与request打交道的
struts2中,一个Action对象对应一个request上下文
spring3 mvc不同,spring3mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去
在spring3mvc中,一个方法对应一个request上下文
好了 我们来整理一下
struts2是类级别的拦截, 一个类对应一个request上下文,
springmvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应
所以说从架构本身上 spring3 mvc就容易实现restful url
而struts2的架构实现起来要费劲
因为struts2 action的一个方法可以对应一个url
而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了
===================================
spring3mvc的方法之间基本上独立的,独享request response数据
请求数据通过参数获取,处理结果通过ModelMap交回给框架
方法之间不共享变量
而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的
这不会影响程序运行,却给我们编码 读程序时带来麻烦
====================================
spring3 mvc的验证也是一个亮点,支持JSR303
处理ajax的请求更是方便 只需一个注解@ResponseBody ,然后直接返回响应文本即可
附上一段代码
@RequestMapping(value="/whitelists") public String index(ModelMap map){ Account account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId()) ; List<Group> groupList = groupManager.findAllGroup(account.getId()) ; map.put("account", account); map.put("groupList", groupList); return "/group/group-index" ; } //@ResponseBody ajax响应 @RequestMapping(value="/whitelist/{whiteListId}/del") @ResponseBody public String delete(@PathVariable Integer whiteListId){ whiteListManager.deleteWhiteList(whiteListId) ; return "success" ; }
评论
126 楼
bonny
2010-06-29
哦,S2的确可以更OO。但是,JSP是太不OO了,不如JSF的好,极端点的说法,JSF比S2好。
OO真的得是程序开发的万金油么?或者说,在WEB开发上他就很合适?处处用此来衡量呢?
我不觉得用OO来开发页面是好主意,我也不觉得OO来描述流程是好主意。我觉得OO的核心优势就是消息和关系。应该用在合适的地方。
action?不是。
OO真的得是程序开发的万金油么?或者说,在WEB开发上他就很合适?处处用此来衡量呢?
我不觉得用OO来开发页面是好主意,我也不觉得OO来描述流程是好主意。我觉得OO的核心优势就是消息和关系。应该用在合适的地方。
action?不是。
125 楼
icewubin
2010-06-27
C_J 写道
**自己不是很了解WEB框架,但看大家讨论来讨论去,是不是可以简单归结为“用局部变量,还是成员变量?以及方法和类的引申好处” 或者归结为“过程式,还是面向OO式?”
**关于效率,Struts2如果对Action对象做了对象池的话,我感觉也不会慢到哪里去吧,和SpringMVC的“方法级拦截”应该相当吧。
**不知道S2有没有做action的对象池呢? 如果没有,又出于什么考虑呢?哪位知道的话能否讲解下?
个人的一些理解,欢迎指正:)
**关于效率,Struts2如果对Action对象做了对象池的话,我感觉也不会慢到哪里去吧,和SpringMVC的“方法级拦截”应该相当吧。
**不知道S2有没有做action的对象池呢? 如果没有,又出于什么考虑呢?哪位知道的话能否讲解下?
个人的一些理解,欢迎指正:)
楼上,从很早以前开始,除非是连接池这种每次创建代价很大的少数pool,对象池模式早就不再需要了。
124 楼
C_J
2010-06-27
**自己不是很了解WEB框架,但看大家讨论来讨论去,是不是可以简单归结为“用局部变量,还是成员变量?以及方法和类的引申好处” 或者归结为“过程式,还是面向OO式?”
**关于效率,Struts2如果对Action对象做了对象池的话,我感觉也不会慢到哪里去吧,和SpringMVC的“方法级拦截”应该相当吧。
**不知道S2有没有做action的对象池呢? 如果没有,又出于什么考虑呢?哪位知道的话能否讲解下?
个人的一些理解,欢迎指正:)
**关于效率,Struts2如果对Action对象做了对象池的话,我感觉也不会慢到哪里去吧,和SpringMVC的“方法级拦截”应该相当吧。
**不知道S2有没有做action的对象池呢? 如果没有,又出于什么考虑呢?哪位知道的话能否讲解下?
个人的一些理解,欢迎指正:)
123 楼
slaser
2010-06-26
downpour 写道
楼上的这位同学,讨论中止,我认为你的水平还不足以和我讨论。希望你首先明白什么才是OO,什么才是优雅。我不乐意和一个毫无是非观念的人讨论下去,这毫无意义。
我不否认,struts2看起来更加OO, 并且可以从中获得很多好处,比如拦截器中直接操作实例变量,实例变量上可以直接添加scope可读性更好。但是用是不是OO来决定一个框架是否优秀还是显得片面。
Spring MVC对于请求-相应模式更直接点,参数输入,处理,ModelMap输出,每个方法之间不互相干扰。这样很多方法可以放一起,比如一个CustomerController就可以解决所有customer相关请求,这里的customerController不是一个业务上的概念,可以看成是Customer的EndPoint,用于提供基于url请求的服务。
反之,用struts2改写这个类就会出现过多实例变量,所以,就必须合理的设计struts2的action。所以,个人认为struts2的使用上更为复杂些。我并不是想搬到Struts2, 但是我想通过这些讨论,找出Struts2,Spring MVC2者设计理念的差别以及最佳实践和适用范围。讨论的过程也是学习的过程,当然你没有耐心赐教,我也没办法。
122 楼
xly_971223
2010-06-26
引用
对于楼上两位的论调,我感觉非常遗憾。Java发展到现在,还有人可以堂而皇之的告诉我,显示调用map.put,是业务逻辑的一部分,为了分清楚所谓的输入输出,宁可放弃OO。
现在明白你为什么那么急冻,那么贬低springmvc了
如果仅仅因为springmvc不够OO而武断的主观的说它不好是不可取的
springmvc采取的是动态绑定参数的方式,而struts2是静态的方式
这也就决定了springmvc无法做到OO,但正是这种动态提高了开发效率,受很多开发者的欢迎
struts2确实很OO, 但也带来了前面讨论的那些问题
我个人认为web层框架的趋势是springmvc或者说动态绑定参数型框架
downpour 写道
楼上的这位同学,讨论中止,我认为你的水平还不足以和我讨论。希望你首先明白什么才是OO,什么才是优雅。我不乐意和一个毫无是非观念的人讨论下去,这毫无意义。
淡定
121 楼
daquan198163
2010-06-25
楼上请注意看上下文,我没说要用全局map
我没说框架本身是固化的,但它是对知识和经验的固化
就像软件是对人类思维的固化,软件本身不是固化的
哎
我没说框架本身是固化的,但它是对知识和经验的固化
就像软件是对人类思维的固化,软件本身不是固化的
哎
120 楼
llade
2010-06-25
貌似用Map级别更容易犯"容易犯的错误",put/get一不小心"最终一定会变成泛滥的错误",我们的团队除非万不得已,不要用Map这东西来存放业务逻辑数据,因为吃过好多亏啊。
似乎哪个框架都在出2,3版本,远未固化。
貌似只有死了的东西才会固化。
最后,存属路过。
引用
框架就是固化了的最佳实践
似乎哪个框架都在出2,3版本,远未固化。
貌似只有死了的东西才会固化。
最后,存属路过。
119 楼
daquan198163
2010-06-25
那您就耐心赐教一下呗,毕竟都一起打过球的
118 楼
downpour
2010-06-25
楼上的这位同学,讨论中止,我认为你的水平还不足以和我讨论。希望你首先明白什么才是OO,什么才是优雅。我不乐意和一个毫无是非观念的人讨论下去,这毫无意义。
117 楼
daquan198163
2010-06-25
对于楼上两位的论调,我感觉非常遗憾。Java发展到现在,还有人可以堂而皇之的告诉我,显示调用map.put,是业务逻辑的一部分,为了分清楚所谓的输入输出,宁可放弃OO。
既然是基于请求的框架,那么把输入输出分清楚是一个最最基本的要求,这都不行的话还搞啥球的OO
到底是使用类的实例变量还是局部变量,你可以从Spring的设计思想中得出结论。你们说来说去无非是说实例变量让你们分不清输入还是输出。这样的伪问题真是不知道令人如何回答。我曾经见过有人是这样用Struts2的Action的:在一个Action中,放一个Map专门来做输入,再专门放一个Map来做输出。我不知道这样是否能解决两位的问题。但是我想告诉你,无论从哪个角度来说,使用类似SpringMVC中的ModelMap来进行返回输出,都是很多年前的思路(这与Struts1中的FormBean是一个概念)。你仔细想想,你是否真的要知道输入和输出?这对你意义真的有那么大嘛?
这样当然不行,换成map也还是实例级别的变量,多个方法的变量还是参合在一起,换汤不换药。
spring的设计思想说明不了什么问题,因为spring是个透明的中间层框架,而Struts2是不透明的MVC框架。
还是那句话,既然是基于请求的框架,那么把输入输出分清楚是一个基本要求。
你们所谓的类的实例变量的泛滥,更加是一个伪命题。这纯粹是你们在项目中没有正确规划Action与URL的mapping关系造成的。这就取决于你们团队的水平问题了,至少在我们的团队中,还从来没有人向我抱怨过这样的问题。
是呀,只要足够的聪明和小心,我们可以驾驭任何难用的框架。但是容易犯的错误最终一定会变成泛滥的错误。
你们团队没人抱怨只能说明你们NB,但不代表Struts2的这个设计不SB
拦截器能做什么?你认为丰富的执行层次没什么了不起。我可以告诉你,在我们的团队中,丰富的执行层次给我们带来了极大的扩展空间。我来给你举个简单的场景。
丰富的执行层次当然重要,但拦截器链实在不是一个聪明的实现,最大的问题就是阶段含义和分工不明确,跟把所有变量都堆在实例级别是一样的错误。
像SpringMVC这样,通过TemplateMethod模式,提供各个阶段的生命周期回调才对路
在一个典型的具备多条件查询的页面中,我们尝试这样来构建我们的JSP:
看到这样的input名称了嘛?我们只要使用一个拦截器,就可以很轻松的根据这些name/value的值,动态构建一个SearchComponent到Struts2的Action中,并将这个SearchComponent作为参数传到后台,调用通用的DAO方法就可以完成查询,而省略了所有的null值判断,动态拼接SQL的工作。
当这样的多条件查询的页面在一个系统里面有几十个甚至是上百个的时候,你就会发现Struts2拦截器的作用,是能够极大的解放我们的生产力的。
这个可以有啊,无非是 参数填充、criterial、通用DAO、validation,不妨拿出来分享一下吧,我帮你弄个springmvc版的
这些可以说只是冰山的一角,我们甚至使用Struts2的拦截器来做一切与Http传递参数相关的事情。比如说,一个导入功能,通过http上传csv文件来实现。通过使用Struts2的拦截器,在Struts2的Action中你甚至看不到File的影子,被我们写的拦截器拦截后,通过csv模板的解析,将csv文件的内容转化为对象传递到Action中去了。
呵呵,我觉得这种变魔术的实现方式是自作聪明,我在action里调用helper解析csv多直接啊,免得不熟悉的人到action里找不到file,把简单事情搞复杂很过瘾么?
这样的业务场景太多,没必要一一列举了。
我想有关这类讨论应该告一个段落,我也不打算说服大家说Struts2有多好,因为实际上每个应用的使用场景都不同,只希望大家在Web层框架选择时,多多思考一些与应用相关的事情,而不是去讨论框架本身,框架是死的,使用框架的人是活的,希望大家在应用层面多总结一些最佳实践,而不是报怨框架的好坏。
框架就是固化了的最佳实践
既然是基于请求的框架,那么把输入输出分清楚是一个最最基本的要求,这都不行的话还搞啥球的OO
到底是使用类的实例变量还是局部变量,你可以从Spring的设计思想中得出结论。你们说来说去无非是说实例变量让你们分不清输入还是输出。这样的伪问题真是不知道令人如何回答。我曾经见过有人是这样用Struts2的Action的:在一个Action中,放一个Map专门来做输入,再专门放一个Map来做输出。我不知道这样是否能解决两位的问题。但是我想告诉你,无论从哪个角度来说,使用类似SpringMVC中的ModelMap来进行返回输出,都是很多年前的思路(这与Struts1中的FormBean是一个概念)。你仔细想想,你是否真的要知道输入和输出?这对你意义真的有那么大嘛?
这样当然不行,换成map也还是实例级别的变量,多个方法的变量还是参合在一起,换汤不换药。
spring的设计思想说明不了什么问题,因为spring是个透明的中间层框架,而Struts2是不透明的MVC框架。
还是那句话,既然是基于请求的框架,那么把输入输出分清楚是一个基本要求。
你们所谓的类的实例变量的泛滥,更加是一个伪命题。这纯粹是你们在项目中没有正确规划Action与URL的mapping关系造成的。这就取决于你们团队的水平问题了,至少在我们的团队中,还从来没有人向我抱怨过这样的问题。
是呀,只要足够的聪明和小心,我们可以驾驭任何难用的框架。但是容易犯的错误最终一定会变成泛滥的错误。
你们团队没人抱怨只能说明你们NB,但不代表Struts2的这个设计不SB
拦截器能做什么?你认为丰富的执行层次没什么了不起。我可以告诉你,在我们的团队中,丰富的执行层次给我们带来了极大的扩展空间。我来给你举个简单的场景。
丰富的执行层次当然重要,但拦截器链实在不是一个聪明的实现,最大的问题就是阶段含义和分工不明确,跟把所有变量都堆在实例级别是一样的错误。
像SpringMVC这样,通过TemplateMethod模式,提供各个阶段的生命周期回调才对路
在一个典型的具备多条件查询的页面中,我们尝试这样来构建我们的JSP:
<input type="text" name="eq.user.code" /> <input type="text" name="gt.user.birthday" /> <input type="text" name="lt.user.birthday" />
看到这样的input名称了嘛?我们只要使用一个拦截器,就可以很轻松的根据这些name/value的值,动态构建一个SearchComponent到Struts2的Action中,并将这个SearchComponent作为参数传到后台,调用通用的DAO方法就可以完成查询,而省略了所有的null值判断,动态拼接SQL的工作。
当这样的多条件查询的页面在一个系统里面有几十个甚至是上百个的时候,你就会发现Struts2拦截器的作用,是能够极大的解放我们的生产力的。
这个可以有啊,无非是 参数填充、criterial、通用DAO、validation,不妨拿出来分享一下吧,我帮你弄个springmvc版的
这些可以说只是冰山的一角,我们甚至使用Struts2的拦截器来做一切与Http传递参数相关的事情。比如说,一个导入功能,通过http上传csv文件来实现。通过使用Struts2的拦截器,在Struts2的Action中你甚至看不到File的影子,被我们写的拦截器拦截后,通过csv模板的解析,将csv文件的内容转化为对象传递到Action中去了。
呵呵,我觉得这种变魔术的实现方式是自作聪明,我在action里调用helper解析csv多直接啊,免得不熟悉的人到action里找不到file,把简单事情搞复杂很过瘾么?
这样的业务场景太多,没必要一一列举了。
我想有关这类讨论应该告一个段落,我也不打算说服大家说Struts2有多好,因为实际上每个应用的使用场景都不同,只希望大家在Web层框架选择时,多多思考一些与应用相关的事情,而不是去讨论框架本身,框架是死的,使用框架的人是活的,希望大家在应用层面多总结一些最佳实践,而不是报怨框架的好坏。
框架就是固化了的最佳实践
116 楼
downpour
2010-06-25
对于楼上两位的论调,我感觉非常遗憾。Java发展到现在,还有人可以堂而皇之的告诉我,显示调用map.put,是业务逻辑的一部分,为了分清楚所谓的输入输出,宁可放弃OO。
到底是使用类的实例变量还是局部变量,你可以从Spring的设计思想中得出结论。你们说来说去无非是说实例变量让你们分不清输入还是输出。这样的伪问题真是不知道令人如何回答。我曾经见过有人是这样用Struts2的Action的:在一个Action中,放一个Map专门来做输入,再专门放一个Map来做输出。我不知道这样是否能解决两位的问题。但是我想告诉你,无论从哪个角度来说,使用类似SpringMVC中的ModelMap来进行返回输出,都是很多年前的思路(这与Struts1中的FormBean是一个概念)。你仔细想想,你是否真的要知道输入和输出?这对你意义真的有那么大嘛?
你们所谓的类的实例变量的泛滥,更加是一个伪命题。这纯粹是你们在项目中没有正确规划Action与URL的mapping关系造成的。这就取决于你们团队的水平问题了,至少在我们的团队中,还从来没有人向我抱怨过这样的问题。
拦截器能做什么?你认为丰富的执行层次没什么了不起。我可以告诉你,在我们的团队中,丰富的执行层次给我们带来了极大的扩展空间。我来给你举个简单的场景。
在一个典型的具备多条件查询的页面中,我们尝试这样来构建我们的JSP:
看到这样的input名称了嘛?我们只要使用一个拦截器,就可以很轻松的根据这些name/value的值,动态构建一个SearchComponent到Struts2的Action中,并将这个SearchComponent作为参数传到后台,调用通用的DAO方法就可以完成查询,而省略了所有的null值判断,动态拼接SQL的工作。
当这样的多条件查询的页面在一个系统里面有几十个甚至是上百个的时候,你就会发现Struts2拦截器的作用,是能够极大的解放我们的生产力的。
这些可以说只是冰山的一角,我们甚至使用Struts2的拦截器来做一切与Http传递参数相关的事情。比如说,一个导入功能,通过http上传csv文件来实现。通过使用Struts2的拦截器,在Struts2的Action中你甚至看不到File的影子,被我们写的拦截器拦截后,通过csv模板的解析,将csv文件的内容转化为对象传递到Action中去了。
这样的业务场景太多,没必要一一列举了。
我想有关这类讨论应该告一个段落,我也不打算说服大家说Struts2有多好,因为实际上每个应用的使用场景都不同,只希望大家在Web层框架选择时,多多思考一些与应用相关的事情,而不是去讨论框架本身,框架是死的,使用框架的人是活的,希望大家在应用层面多总结一些最佳实践,而不是报怨框架的好坏。
到底是使用类的实例变量还是局部变量,你可以从Spring的设计思想中得出结论。你们说来说去无非是说实例变量让你们分不清输入还是输出。这样的伪问题真是不知道令人如何回答。我曾经见过有人是这样用Struts2的Action的:在一个Action中,放一个Map专门来做输入,再专门放一个Map来做输出。我不知道这样是否能解决两位的问题。但是我想告诉你,无论从哪个角度来说,使用类似SpringMVC中的ModelMap来进行返回输出,都是很多年前的思路(这与Struts1中的FormBean是一个概念)。你仔细想想,你是否真的要知道输入和输出?这对你意义真的有那么大嘛?
你们所谓的类的实例变量的泛滥,更加是一个伪命题。这纯粹是你们在项目中没有正确规划Action与URL的mapping关系造成的。这就取决于你们团队的水平问题了,至少在我们的团队中,还从来没有人向我抱怨过这样的问题。
拦截器能做什么?你认为丰富的执行层次没什么了不起。我可以告诉你,在我们的团队中,丰富的执行层次给我们带来了极大的扩展空间。我来给你举个简单的场景。
在一个典型的具备多条件查询的页面中,我们尝试这样来构建我们的JSP:
<input type="text" name="eq.user.code" /> <input type="text" name="gt.user.birthday" /> <input type="text" name="lt.user.birthday" />
看到这样的input名称了嘛?我们只要使用一个拦截器,就可以很轻松的根据这些name/value的值,动态构建一个SearchComponent到Struts2的Action中,并将这个SearchComponent作为参数传到后台,调用通用的DAO方法就可以完成查询,而省略了所有的null值判断,动态拼接SQL的工作。
当这样的多条件查询的页面在一个系统里面有几十个甚至是上百个的时候,你就会发现Struts2拦截器的作用,是能够极大的解放我们的生产力的。
这些可以说只是冰山的一角,我们甚至使用Struts2的拦截器来做一切与Http传递参数相关的事情。比如说,一个导入功能,通过http上传csv文件来实现。通过使用Struts2的拦截器,在Struts2的Action中你甚至看不到File的影子,被我们写的拦截器拦截后,通过csv模板的解析,将csv文件的内容转化为对象传递到Action中去了。
这样的业务场景太多,没必要一一列举了。
我想有关这类讨论应该告一个段落,我也不打算说服大家说Struts2有多好,因为实际上每个应用的使用场景都不同,只希望大家在Web层框架选择时,多多思考一些与应用相关的事情,而不是去讨论框架本身,框架是死的,使用框架的人是活的,希望大家在应用层面多总结一些最佳实践,而不是报怨框架的好坏。
115 楼
slaser
2010-06-25
downpour 写道
一共5行代码,有2行和你关注的内容无关,你认为这两行代码有存在的必要吗?这就和你在Service层去显示调用transaction.begin()或者transaction.commit()有什么分别?
有必要的,我确实关注需要输出那些,不要输出什么内容。动不动输出整个Action的实例变量给View调用,让我在写View的时候很迷茫。
downpour 写道
在Action中使用属性,使得一个Action更像一个JavaBean,可以使得测试更加容易。同时,这才是真正的面向对象的编程,一个拥有属性和方法的类,而不是只有方法。如果我们关注一下Spring的主要编程思想,Spring中的所有的Bean,其实都是在往具备丰富属性加方法的趋势发展的。Struts2的Action天然就是一个JavaBean,你居然能够说出这两个属性很恶心的话来,我不能理解你的想法。
。。。
Struts2有很多插件,官方网站上你可以查找一下。
同意你对struts的action更oo的说法,确实是这么回事,spring mvc和struts1的action就是过程式的处理。所以我说spring mvc和struts2是2个方向,我不觉得spring mvc的做法更糟糕。
114 楼
daquan198163
2010-06-25
downpour 写道
一共5行代码,有2行和你关注的内容无关,你认为这两行代码有存在的必要吗?这就和你在Service层去显示调用transaction.begin()或者transaction.commit()有什么分别?
在Action中使用属性,使得一个Action更像一个JavaBean,可以使得测试更加容易。同时,这才是真正的面向对象的编程,一个拥有属性和方法的类,而不是只有方法。如果我们关注一下Spring的主要编程思想,Spring中的所有的Bean,其实都是在往具备丰富属性加方法的趋势发展的。Struts2的Action天然就是一个JavaBean,你居然能够说出这两个属性很恶心的话来,我不能理解你的想法。
拦截器做什么事情?我用拦截器做的事情太多了。拦截器的一个很大的作用就是精简与业务逻辑调用无关的恶心代码。至于你说的是否简洁、配置是否一致、是否符合直觉,我更加不能理解了,从任何角度来说,Struts2都能满足你的这3点。
Struts2有很多插件,官方网站上你可以查找一下。
你所谓的省掉两行代码,只不过是把那两个值付给了action的属性而已,而且它们也不是“不需要关注的内容”,它们恰恰是这里的业务逻辑,
transaction.begin()和commit()显然不属于业务逻辑,区别非常的大,一黑一白。
如果面向对象让我的日子难过,我会毫不犹豫的丢掉面向对象。我们还是少搞一些宗教,多一些务实的好。
我当然知道拦截器做什么,但我看不出有什么拦截器需要做的工作会由于只能拦截参数、返回值而变得不能做了,所以,还是请你列举出典型场景。
前面也说了,那两行代码属于业务逻辑,跟拦截器没什么关系,也不需要劳驾拦截器去精简,并且ww那个做法也没有精简。
我说的“是否简洁、配置是否一致、是否符合直觉 ”指的是ww/struts2把局部变量搞成实例变量这种做法。
113 楼
slaser
2010-06-25
daquan198163 写道
我倒觉得# Account account;
# List<Group> groupList;
这两个属性很恶心。
确实恶心,都不知道用来输入,还是输出的,也不知道在哪个方法里面调用。
当你把多个功能写到一个action里面的时候,实例变量带来的只是混乱。
112 楼
downpour
2010-06-25
daquan198163 写道
我倒觉得# Account account;
# List<Group> groupList;
这两个属性很恶心。
为什么要用AOP来省掉那两行代码呢?
你通常用拦截器做什么事情? 不太明白你的意思。
扩展点多确实没什么好炫耀的,足够、实用就好了。
评价一个框架好坏主要还是看开发效率、是否简洁、配置是否一致、符合直觉。
Struts2有webflow类似的插件么?
# List<Group> groupList;
这两个属性很恶心。
为什么要用AOP来省掉那两行代码呢?
你通常用拦截器做什么事情? 不太明白你的意思。
扩展点多确实没什么好炫耀的,足够、实用就好了。
评价一个框架好坏主要还是看开发效率、是否简洁、配置是否一致、符合直觉。
Struts2有webflow类似的插件么?
一共5行代码,有2行和你关注的内容无关,你认为这两行代码有存在的必要吗?这就和你在Service层去显示调用transaction.begin()或者transaction.commit()有什么分别?
在Action中使用属性,使得一个Action更像一个JavaBean,可以使得测试更加容易。同时,这才是真正的面向对象的编程,一个拥有属性和方法的类,而不是只有方法。如果我们关注一下Spring的主要编程思想,Spring中的所有的Bean,其实都是在往具备丰富属性加方法的趋势发展的。Struts2的Action天然就是一个JavaBean,你居然能够说出这两个属性很恶心的话来,我不能理解你的想法。
拦截器做什么事情?我用拦截器做的事情太多了。拦截器的一个很大的作用就是精简与业务逻辑调用无关的恶心代码。至于你说的是否简洁、配置是否一致、是否符合直觉,我更加不能理解了,从任何角度来说,Struts2都能满足你的这3点。
Struts2有很多插件,官方网站上你可以查找一下。
111 楼
daquan198163
2010-06-25
我倒觉得# Account account;
# List<Group> groupList;
这两个属性很恶心。
为什么要用AOP来省掉那两行代码呢?
你通常用拦截器做什么事情? 不太明白你的意思。
扩展点多确实没什么好炫耀的,足够、实用就好了。
评价一个框架好坏主要还是看开发效率、是否简洁、配置是否一致、符合直觉。
Struts2有webflow类似的插件么?
# List<Group> groupList;
这两个属性很恶心。
为什么要用AOP来省掉那两行代码呢?
你通常用拦截器做什么事情? 不太明白你的意思。
扩展点多确实没什么好炫耀的,足够、实用就好了。
评价一个框架好坏主要还是看开发效率、是否简洁、配置是否一致、符合直觉。
Struts2有webflow类似的插件么?
110 楼
downpour
2010-06-25
slaser 写道
第一,没看出来spring的aop拦截限制了什么应用了,我的输入输出都在参数和返回值上,为什么还需要其他拦截,你能拿出什么实际的例子让spring mvc做起来很难受的么?另外,说起spring aop天然支持aop有什么错,spring aop的后面是aspectj,对于领域对象的注入和拦截也是可以靠aspectJ搞定的。
第二,难道Spring MVC执行层次不多,定制化不强?可插入url的解析,多种view的支持,Spring Webflow,Security集成被你无视了。
第三,不认为Struts2在技术上完胜,struts2走了和Spring MVC不同的路,这个才是关键,而我觉得它现在是个半成品。论优雅,可以去学习JSF.
拦截器拦截的内容仅仅限制于参数和返回值是一件令人头疼的事情,这就意味着你的拦截器代码不可避免的要和这些内容去打交道。也就是说,一旦我要在里面加一些特殊的逻辑,比如根据参数或者返回值中的某个字段进行逻辑判断,就会使得你的拦截器依赖于特定的切面而变得毫无意义。
@RequestMapping(value="/whitelists") public String index(ModelMap map){ Account account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId()) ; List<Group> groupList = groupManager.findAllGroup(account.getId()) ; map.put("account", account); map.put("groupList", groupList); return "/group/group-index" ; } //@ResponseBody ajax响应 @RequestMapping(value="/whitelist/{whiteListId}/del") @ResponseBody public String delete(@PathVariable Integer whiteListId){ whiteListManager.deleteWhiteList(whiteListId) ; return "success" ; }
在这其中我们可以看到:
map.put("account", account); map.put("groupList", groupList);
这两句话纯粹就是多余的。一共5行code,有2行在为返回输出做准备。你还能厚着脸皮说SpringMVC解放了你的生产力?
在Struts2中,代码就会变成这样:
Account account; List<Group> groupList; public String index(){ account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId()) ; groupList = groupManager.findAllGroup(account.getId()) ; return "/group/group-index" ; }
你所需要关注的,只是你的业务逻辑调用,而无需关心返回到底是什么名称,更不用提什么显示调用map.put这种恶心的代码了。
再问,你能用你所谓Spring的AOP把map.put这两行code给省略了嘛?所有的返回的内容都是局部变量,你去拦截啊?无能为力了吧。
至于说到什么url解析,多view的支持,SpringMVC的支持也仅仅限于支持而已,这些所谓的支持,成熟的Web层框架全部都有。所谓的Annotation带来的配置简化,本身就是一个伪命题。@RequestMapping(value="/whitelist/{whiteListId}/del")这种看上去优雅的实现,其实带来的问题却是致命的。这一点我很早就已经指出过。你可以翻看我以前的帖子。
SpringMVC充其量也就是一个简单的Web层的Mapping工具,要谈到综合性的Web层解决方案,它还差得很远。Struts2本身的设计思想和实现是所有MVC框架中最先进的。它也有很多问题,但是至今为止我还没有找到足够的证据来说明它的问题。所以希望大家在抱怨的同时,仔细想想你的观点是否真的站得住脚。
109 楼
downpour
2010-06-25
daquan198163 写道
struts2能实现wizard和webflow吗?
我觉得拦截器机制和大量的扩展点真没什么好炫耀的,够用就行了,95分和100分的区别而已。
我觉得拦截器机制和大量的扩展点真没什么好炫耀的,够用就行了,95分和100分的区别而已。
Struts2有一个Scope插件,可以轻松实现wizard:https://cwiki.apache.org/S2PLUGINS/scope-plugin.html
如果连扩展点都不值得炫耀,那么真的没什么可以炫耀的了。
108 楼
sogo1986
2010-06-25
springmvc3暂时没用过,以前用2.5身受其害配置文件太多太大
数据绑定上basicform虽然可以binding,其它controller的方法内部还是免不了写些获取参数的代码
新增的注解驱动和全面的REST支持的确令人眼前一亮
struts2的核心还是拦截器和扩展性强的resultType
springmvc拦截器基于原生的aop,优势是本身就作为bean和ioc容器无缝集成
另外和struts1一样提供非常丰富的标签库
编程模型上2者相当
数据绑定上basicform虽然可以binding,其它controller的方法内部还是免不了写些获取参数的代码
新增的注解驱动和全面的REST支持的确令人眼前一亮
struts2的核心还是拦截器和扩展性强的resultType
springmvc拦截器基于原生的aop,优势是本身就作为bean和ioc容器无缝集成
另外和struts1一样提供非常丰富的标签库
编程模型上2者相当
107 楼
slaser
2010-06-25
wen66 写道
在借位置问一下各位开发同仁, 现在不想做java web开发了, 想转去做java的其它方面开发, 大家有没有什么好的建议. 先谢谢了.
继续做web吧,其他方向未必好。
发表评论
-
利用last modified头节省服务器资源和网络带宽
2011-09-19 17:27 1479last-modified 和 if-modified-sin ... -
系统架构中数据库的设计
2010-11-08 16:27 1821架构师往往是有前瞻性的 这个前瞻性是在很多项目经验的基础上总结 ... -
用telnet操作memcached
2010-07-16 14:14 1872telnet localhost 11211 流量统计 st ... -
spring的@Transactional为什么不能指定TransactionManager?
2010-06-10 16:44 7138用过spring的人应该都使用过@Transactional注 ... -
(转)Memcached的stats命令
2010-04-18 11:57 1849命令行查看Memcached运行状态 很多时候需要监控服务器 ... -
tomcat io 与 nio性能比较
2010-04-10 21:30 10788tomcat连接器(conncector)可以配置成NIO方式 ... -
nginx+tomcat配置
2010-04-07 15:16 4151一直听说nginx很厉害 今天装了一个 没有做任何配置直接ab ... -
浏览器缓存总结
2010-03-27 10:20 3086浏览器缓存主要有两类 ... -
理解linux下sendfile()系统调用
2010-03-21 11:29 3079服务器响应一个http静态资源请求的步骤如下: 1 把磁盘文件 ... -
freemarker生成静态jsp碎片乱码
2010-03-19 14:56 3146用freemarker定时生成jsp文件 然后通过jsp:i ... -
用apache ab做压力测试
2010-03-14 16:04 1881测试静态html资源 文件大小44byte,总请求数10000 ... -
apache ab命令详解(转)
2010-03-14 11:58 2637原文地址:http://blog.csdn.net/zhong ... -
压力测试关心的几个指标
2010-03-13 20:58 4752并发用户数 这个不是多说了,可简单理解为并发线程数 总请求次数 ... -
利用squid refresh_pattern缓存图片
2010-03-03 15:22 2964用浏览器请求一张图片1.gif的过程如下 1 发送http到s ... -
如何理解Squid refresh_pattern
2010-03-03 14:25 1649refresh_pattern的作用: 用于确定一个页面进入c ... -
关于Cache-Contro缓存
2010-03-03 10:01 1884浏览器缓存一直是web开发人员比较重视的优化点 这要有这个几个 ...
相关推荐
spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 ...
spring-webmvc-struts.jar对Struts和Spring整合时需要用到的包
**Struts2与Spring MVC比较:** 1. **灵活性**:Spring MVC允许更多的自定义,如自定义拦截器、视图解析器,而Struts2的扩展性相对弱些。 2. **依赖注入**:Spring MVC是Spring框架的一部分,天然支持DI,而Struts2...
下面我们将详细探讨Spring MVC的核心组件、工作流程以及与Struts2.x的比较。 1. **Spring MVC 核心组件** - **DispatcherServlet**:Spring MVC 的核心是DispatcherServlet,它作为一个前端控制器,负责接收请求...
2. Struts与Spring的整合,包括Action的配置、Service注入到Action、以及结果的处理。 3. 使用AspectJ的注解来定义切面,如`@Aspect`、`@Pointcut`、`@Before`、`@After`等。 4. 切面的织入策略,包括编译时织入和...
3. **Interceptor**:类似于Spring MVC的HandlerInterceptor,Struts2的拦截器用于在Action执行前后执行特定任务。 4. **Result**:处理Action执行后的结果,决定如何展示给用户。 5. **ValueStack**:Struts2的...
"spring-webmvc-struts"可能指的是Spring与Struts的集成包,Struts是另一个流行的Java Web MVC框架。这个库可能包含了一些桥接代码,帮助开发者将Spring的IoC(Inversion of Control,控制反转)和AOP功能与Struts的...
spring-webmvc-struts-2.5.6-sources
《构建摄影平台:Spring+Spring MVC+Struts+Hibernate整合详解》 在现代Web开发领域,Spring框架以其灵活性和强大的企业级应用支持而备受青睐。本项目“Spring+Spring MVC+Struts+Hibernate开发摄影平台完整版系统...
综上所述,"DWR与SPRING,DWR与STRUTS2的整合"主题涵盖了现代Java Web开发中重要的三个方面:DWR的实时通信能力、Spring的全面后端支持和Struts2的MVC架构。通过整合这三者,开发者可以构建出具有高效交互、灵活管理...
在IT行业中,MVC(Model-...理解并熟练运用MVC模式、Struts2框架、Spring框架以及Hibernate ORM,对于提升Java Web开发能力大有裨益。通过解答相关选择题,可以检验和巩固这些知识点的理解程度,进一步提升个人技能。
`struts2-spring-plugin-2.5.16.jar`是Struts2与Spring集成的插件,它使得Struts2可以利用Spring的依赖注入(DI)和面向切面编程(AOP)能力。通过这个插件,我们可以将Action类的实例化和管理交给Spring容器,从而...
Spring3、Struts2和Ibatis的整合,构建了一个完整的MVC+持久层架构。Spring作为整个应用的调度中心,管理所有对象的生命周期,包括Struts2的Action和Ibatis的SqlSession。Struts2负责接收HTTP请求,调用Action执行...
本项目“MVC注解Spring-Struts2Spring2hibernate3”结合了Spring、Struts2和Hibernate3这三大框架,以注解的方式实现了一个完整的MVC解决方案。下面将详细介绍这三个框架以及它们之间的协作。 首先,Spring框架是...
Spring MVC作为其Web层的一部分,与Struts相比,更加轻量级和灵活。Spring MVC通过DispatcherServlet作为入口点,处理HTTP请求,并通过配置或注解定义控制器(@Controller)。模型数据通常通过模型对象(Model或...