- 浏览: 149267 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
fei33423:
流程引擎的流转比状态机要复杂太多了把. 我觉得你即可以看成平行 ...
工作流引擎是否应该建立在有限状态机(Finite State Machine, FSM)引擎之上? -
c601097836:
为什么你们都说FSM,而不是UML State machine ...
工作流引擎是否应该建立在有限状态机(Finite State Machine, FSM)引擎之上? -
ronghao:
di1984HIT 写道类似啊,我现在也有这个困惑、我的工作流 ...
工作流引擎是否应该建立在有限状态机(Finite State Machine, FSM)引擎之上? -
di1984HIT:
不错啊。学习了。
[转]hadoop使用中的几个小细节(一) -
di1984HIT:
好的、
工作流20种基本模式的理解
之前只是简单的使用JSTL/EL进行输出,一般的思路很简单:retrieve data -> put to Request -> JSTL/EL
一直没太注意两个问题:
1、JSTL/EL官方上无法方便、直接的访问静态变量。
比如,我们定义了一个Constants类:
我们并不能直接这样使用:
原因很简单:
1)这个Constants必须出现在某个scope,比如requestScope;
2)这个CONSTANT_A必须有一个getter方法,EL支持bean和map的规范
怎么办?
2、JSTL/EL如何才能简单的使用CodeTable(存储于DB的应用系统变量)?
应用系统变量几乎是无可避免的,好处大家都懂的。
一般人的思维肯定是:
1)提供一个service,拥有若干方法,比如getCodesByType(String codeType);
2)用的时候get出来,然后put到request上面,最后在JSP中用JSTL/EL来取出
最后的用法,以Spring MVC的tag为例,一般是:
此时表示要获取Gender的CodeTable,并以codeValue为值,codeName为Label
是否存在更简单有效的方法?
我目前正在整合一些信息并加以模式化,试图提供一个简洁有效的办法来达成目标,也希望大家参与讨论,提供“一站式”的解决方案
你说的对,这就是我认为比较有意思的设计之一:这里存放的只是KEY及其引用,以确保值是refreshable的。
这样的话,是否缓存及其缓存策略,都交给原来的service/dao来做(比如我所涉及的项目就是用了简单的iBatis LRU缓存,24小时自动flush),这里既然是轻量级的做法,就不要管这些了。
当然了,你如果愿意,也可以在这里考虑缓存,但此时需要考虑缓存的生命周期管理了
我们几年前是通过自定义tag,还有freemarker宏实现这种鸟功能。每个人只要放一个key进去,就能取出各种值:单值,列表,map之类的。
极不情愿地最后一次回你的贴。
看问题要看清问题的本质。你能说出“自己再维护一个ValueStack”这种话来,只能证明你对StrutsRequestWrapper的工作原理根本还不理解,也不知道Struts2为什么要这么做。
其实你的这个问题早在2004年就在Javaeye中讨论过,不过当时侧重点转向了Tag实现,直到Webwork2.2的发布,大家才发现RequestWrapper是最简单有效的方案。时代在进步,7年过去了,难道讨论还始终停留在7年前的水平么?
哈哈,终于把高手惹毛了。
我感觉我是理解RequestWrapper的用意的,既然在servlet API标准中就考虑到了这种设计,自然鼓励servlet容器或者大型的基础框架中适度采用装饰模式加以扩展,自然是不错的实践。
按照我的理解,采用RequestWrapper无非两点:
1、可以扩展自己的数据交换堆栈,即ValueStack或类似实现,这样自然可以有自己的存放、转换等更自由的扩展、实现;
2、根据某种约定来获取和交换数据
但是……对于我这种场景,各位大牛们确定我的实现是04年的水平而严重out了之举?
这样吧,如果还有大牛愿意浪费笔墨来点评,请:
1.直接了当说明我这种实现最烂最out的地方,以便一棍子打到04年乃至更早去;
2.也直接了当说明RequestWrapper的实现能确保跟上范冰冰2011年的春装,即便我不喜欢她。
另外说一下,我不用Struts2,我用Spring MVC 3
custom的标签完全可以和EL并存啊,甚至EL表达式可以放到自定义标签中作为一个参数。
个人认为为了扩展Jstl去wrapper request 的确有些傻
极不情愿的下载了struts2,看了StrutsRequestWrapper的源码,两点感觉:
1.自己再维护一个ValueStack,不愿意也不会这么干;
2.看到了这个类的Comment,不爽:
All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL works with request attributes, so this class delegates to the value stack except for a few cases where required to prevent infinite loops.
你们自己看看这个because
如果为了这个JSTL还要自己扩展request wrapper,感觉太委屈了自己——没必要这么找罪受吧我想
抱歉downpour,咱的境界也许没到你那个层次,咱只会干些投机取巧的事情(好像有这种感觉),总是觉得简单明了的解决方案就是最好的
极不情愿地最后一次回你的贴。
看问题要看清问题的本质。你能说出“自己再维护一个ValueStack”这种话来,只能证明你对StrutsRequestWrapper的工作原理根本还不理解,也不知道Struts2为什么要这么做。
其实你的这个问题早在2004年就在Javaeye中讨论过,不过当时侧重点转向了Tag实现,直到Webwork2.2的发布,大家才发现RequestWrapper是最简单有效的方案。时代在进步,7年过去了,难道讨论还始终停留在7年前的水平么?
你对HttpServletRequestWrapper的作用还不理解,所以我才让你去看StrutsRequestWrapper的源码。
你的需求是试图通过JSTL或者EL来获取Java对象中的值。途径只有两种:第一,把你要取的值放到request/session/application中。第二,不要从request/session/application中去取值。
之前所有讨论的思路都是第一种途径,这种途径其实没有从本质上解决你的问题,尤其是reloadable的需求。第二种途径是推荐的做法,既干净又有效。
我之所以推荐第二种方式,是因为你的问题其实和Struts2与JSTL整合的问题是极其类似的。JSTL和EL想要获取Struts2中Action内部的属性的值,通过什么方法呢?Action内部的值,完全不存在request/session/application的作用域中。Struts2给出的方案就是采用StrutsRequestWrapper。你可以思考一下,为什么一个框架级别的解决方案,也采用了这种方法呢?因为它是一种最佳实践。
极不情愿的下载了struts2,看了StrutsRequestWrapper的源码,两点感觉:
1.自己再维护一个ValueStack,不愿意也不会这么干;
2.看到了这个类的Comment,不爽:
All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL works with request attributes, so this class delegates to the value stack except for a few cases where required to prevent infinite loops.
你们自己看看这个because
如果为了这个JSTL还要自己扩展request wrapper,感觉太委屈了自己——没必要这么找罪受吧我想
抱歉downpour,咱的境界也许没到你那个层次,咱只会干些投机取巧的事情(好像有这种感觉),总是觉得简单明了的解决方案就是最好的
这种做法也太笨重了吧?
难道其他引用request的地方也要考虑使用自己的request wrapper以求得一劳永逸?
我见过重新封装request,session,application的,但需求场景应该严重不一样。
还请多加指点
你对HttpServletRequestWrapper的作用还不理解,所以我才让你去看StrutsRequestWrapper的源码。
你的需求是试图通过JSTL或者EL来获取Java对象中的值。途径只有两种:第一,把你要取的值放到request/session/application中。第二,不要从request/session/application中去取值。
之前所有讨论的思路都是第一种途径,这种途径其实没有从本质上解决你的问题,尤其是reloadable的需求。第二种途径是推荐的做法,既干净又有效。
我之所以推荐第二种方式,是因为你的问题其实和Struts2与JSTL整合的问题是极其类似的。JSTL和EL想要获取Struts2中Action内部的属性的值,通过什么方法呢?Action内部的值,完全不存在request/session/application的作用域中。Struts2给出的方案就是采用StrutsRequestWrapper。你可以思考一下,为什么一个框架级别的解决方案,也采用了这种方法呢?因为它是一种最佳实践。
这种做法也太笨重了吧?
难道其他引用request的地方也要考虑使用自己的request wrapper以求得一劳永逸?
我见过重新封装request,session,application的,但需求场景应该严重不一样。
还请多加指点
咱是实战派的,呵呵
不过这个帖子响应率超级低,可见大家应该有其他更好的方案
不是这个问题,或者说这不是问题,我们要解决和讨论的是其他问题:)
当然,这两种方法的思路其实都一样:put到application scope里。
这里外加一点小技巧——对于code table,提供的是引用而非真实数据,确保reloadable.
用自定义ELResolver的好处是,它允许你在求值的瞬间,对求值过程拥有完全的支配权。在ELResolver的getValue方法中你可以拿到EL表达式被求值瞬间的实时上下文,当然包括访问数据库或拿到spring bean。坏处是实现起来相对麻烦,要实现好几个接口方法。
在系统启动期把值put到application scope的好处是实现简单,事实上是借用了求值过程不可控的ScopedAttributeELResolver。问题是put进去与实际求值两个行为之间有个时间差。而reload,就是在还可控的代码中不断地调整application scope中的东西,使得在不可控的求值过程中能获取到尽可能最新的上下文。
当然,我个人觉得还是实用至上,能满足当前需求的方案就是好方案。自定义ELResolver可以作为一种候选方案,等有一天确实application scope方案满足不了再考虑也不迟。
谢谢指点
你说的这种方式看来是最“正统”的办法了——而我所提供的方法是更Spring-ly的
当然,这两种方法的思路其实都一样:put到application scope里。
这里外加一点小技巧——对于code table,提供的是引用而非真实数据,确保reloadable.
该系统变量时 单独对 Map 里某个 key 作更新就好了,为何要reload.
你这种思路是:更改后马上更新,即时生效。
也是不错的思路
但需要remove掉原先application scope中,当前在改的key的map,然后再reload进来,感觉有点麻烦——会不会对原先的code table管理部分造成不必要的困扰?
补充用法:
1、在HTLM元素中使用:
这里表示要以Code Type为Gender的作为下拉框元素
2、用以打印:
对了,我这里为了方便,封装了个简单的CodeTable POJO,一并贴出来:
该系统变量时 单独对 Map 里某个 key 作更新就好了,为何要reload.
一直没太注意两个问题:
1、JSTL/EL官方上无法方便、直接的访问静态变量。
比如,我们定义了一个Constants类:
public class Constants implements Serializable { public static final String CONSTANT_A= "ABC"; ... }
我们并不能直接这样使用:
<c:out value="${Constants.CONSTANT_A}"/>
原因很简单:
1)这个Constants必须出现在某个scope,比如requestScope;
2)这个CONSTANT_A必须有一个getter方法,EL支持bean和map的规范
怎么办?
2、JSTL/EL如何才能简单的使用CodeTable(存储于DB的应用系统变量)?
应用系统变量几乎是无可避免的,好处大家都懂的。
一般人的思维肯定是:
1)提供一个service,拥有若干方法,比如getCodesByType(String codeType);
2)用的时候get出来,然后put到request上面,最后在JSP中用JSTL/EL来取出
最后的用法,以Spring MVC的tag为例,一般是:
<form:select path="gender"> <form:option value="-" label="--Please Select"/> <form:options items="${CodeTable.Gender}" itemValue="codeValue" itemLabel="codeName"/> </form:select>
此时表示要获取Gender的CodeTable,并以codeValue为值,codeName为Label
是否存在更简单有效的方法?
我目前正在整合一些信息并加以模式化,试图提供一个简洁有效的办法来达成目标,也希望大家参与讨论,提供“一站式”的解决方案
评论
25 楼
itstarting
2011-04-28
haitaohehe 写道
楼主 看下你的代码bulidCodeTables()中map为空啊 并没有放值啊..
你说的对,这就是我认为比较有意思的设计之一:这里存放的只是KEY及其引用,以确保值是refreshable的。
这样的话,是否缓存及其缓存策略,都交给原来的service/dao来做(比如我所涉及的项目就是用了简单的iBatis LRU缓存,24小时自动flush),这里既然是轻量级的做法,就不要管这些了。
当然了,你如果愿意,也可以在这里考虑缓存,但此时需要考虑缓存的生命周期管理了
24 楼
fuyaner
2011-04-28
itstarting 写道
之前只是简单的使用JSTL/EL进行输出,一般的思路很简单:retrieve data -> put to Request -> JSTL/EL
一直没太注意两个问题:
1、JSTL/EL官方上无法方便、直接的访问静态变量。
比如,我们定义了一个Constants类:
我们并不能直接这样使用:
原因很简单:
1)这个Constants必须出现在某个scope,比如requestScope;
2)这个CONSTANT_A必须有一个getter方法,EL支持bean和map的规范
怎么办?
2、JSTL/EL如何才能简单的使用CodeTable(存储于DB的应用系统变量)?
应用系统变量几乎是无可避免的,好处大家都懂的。
一般人的思维肯定是:
1)提供一个service,拥有若干方法,比如getCodesByType(String codeType);
2)用的时候get出来,然后put到request上面,最后在JSP中用JSTL/EL来取出
最后的用法,以Spring MVC的tag为例,一般是:
此时表示要获取Gender的CodeTable,并以codeValue为值,codeName为Label
是否存在更简单有效的方法?
我目前正在整合一些信息并加以模式化,试图提供一个简洁有效的办法来达成目标,也希望大家参与讨论,提供“一站式”的解决方案
一直没太注意两个问题:
1、JSTL/EL官方上无法方便、直接的访问静态变量。
比如,我们定义了一个Constants类:
public class Constants implements Serializable { public static final String CONSTANT_A= "ABC"; ... }
我们并不能直接这样使用:
<c:out value="${Constants.CONSTANT_A}"/>
原因很简单:
1)这个Constants必须出现在某个scope,比如requestScope;
2)这个CONSTANT_A必须有一个getter方法,EL支持bean和map的规范
怎么办?
2、JSTL/EL如何才能简单的使用CodeTable(存储于DB的应用系统变量)?
应用系统变量几乎是无可避免的,好处大家都懂的。
一般人的思维肯定是:
1)提供一个service,拥有若干方法,比如getCodesByType(String codeType);
2)用的时候get出来,然后put到request上面,最后在JSP中用JSTL/EL来取出
最后的用法,以Spring MVC的tag为例,一般是:
<form:select path="gender"> <form:option value="-" label="--Please Select"/> <form:options items="${CodeTable.Gender}" itemValue="codeValue" itemLabel="codeName"/> </form:select>
此时表示要获取Gender的CodeTable,并以codeValue为值,codeName为Label
是否存在更简单有效的方法?
我目前正在整合一些信息并加以模式化,试图提供一个简洁有效的办法来达成目标,也希望大家参与讨论,提供“一站式”的解决方案
我们几年前是通过自定义tag,还有freemarker宏实现这种鸟功能。每个人只要放一个key进去,就能取出各种值:单值,列表,map之类的。
23 楼
haitaohehe
2011-04-28
楼主 看下你的代码bulidCodeTables()中map为空啊 并没有放值啊..
22 楼
itstarting
2011-04-18
downpour 写道
极不情愿地最后一次回你的贴。
看问题要看清问题的本质。你能说出“自己再维护一个ValueStack”这种话来,只能证明你对StrutsRequestWrapper的工作原理根本还不理解,也不知道Struts2为什么要这么做。
其实你的这个问题早在2004年就在Javaeye中讨论过,不过当时侧重点转向了Tag实现,直到Webwork2.2的发布,大家才发现RequestWrapper是最简单有效的方案。时代在进步,7年过去了,难道讨论还始终停留在7年前的水平么?
哈哈,终于把高手惹毛了。
我感觉我是理解RequestWrapper的用意的,既然在servlet API标准中就考虑到了这种设计,自然鼓励servlet容器或者大型的基础框架中适度采用装饰模式加以扩展,自然是不错的实践。
按照我的理解,采用RequestWrapper无非两点:
1、可以扩展自己的数据交换堆栈,即ValueStack或类似实现,这样自然可以有自己的存放、转换等更自由的扩展、实现;
2、根据某种约定来获取和交换数据
但是……对于我这种场景,各位大牛们确定我的实现是04年的水平而严重out了之举?
这样吧,如果还有大牛愿意浪费笔墨来点评,请:
1.直接了当说明我这种实现最烂最out的地方,以便一棍子打到04年乃至更早去;
2.也直接了当说明RequestWrapper的实现能确保跟上范冰冰2011年的春装,即便我不喜欢她。
另外说一下,我不用Struts2,我用Spring MVC 3
21 楼
xieke
2011-04-18
itstarting 写道
标签?不行吧,有了custom的标签,如何用EL?
自己封装fn,我也觉得不好,或者说你在这方面有啥更具体的建议?
自己封装fn,我也觉得不好,或者说你在这方面有啥更具体的建议?
custom的标签完全可以和EL并存啊,甚至EL表达式可以放到自定义标签中作为一个参数。
个人认为为了扩展Jstl去wrapper request 的确有些傻
20 楼
downpour
2011-04-18
itstarting 写道
极不情愿的下载了struts2,看了StrutsRequestWrapper的源码,两点感觉:
1.自己再维护一个ValueStack,不愿意也不会这么干;
2.看到了这个类的Comment,不爽:
All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL works with request attributes, so this class delegates to the value stack except for a few cases where required to prevent infinite loops.
你们自己看看这个because
如果为了这个JSTL还要自己扩展request wrapper,感觉太委屈了自己——没必要这么找罪受吧我想
抱歉downpour,咱的境界也许没到你那个层次,咱只会干些投机取巧的事情(好像有这种感觉),总是觉得简单明了的解决方案就是最好的
极不情愿地最后一次回你的贴。
看问题要看清问题的本质。你能说出“自己再维护一个ValueStack”这种话来,只能证明你对StrutsRequestWrapper的工作原理根本还不理解,也不知道Struts2为什么要这么做。
其实你的这个问题早在2004年就在Javaeye中讨论过,不过当时侧重点转向了Tag实现,直到Webwork2.2的发布,大家才发现RequestWrapper是最简单有效的方案。时代在进步,7年过去了,难道讨论还始终停留在7年前的水平么?
19 楼
itstarting
2011-04-17
downpour 写道
你对HttpServletRequestWrapper的作用还不理解,所以我才让你去看StrutsRequestWrapper的源码。
你的需求是试图通过JSTL或者EL来获取Java对象中的值。途径只有两种:第一,把你要取的值放到request/session/application中。第二,不要从request/session/application中去取值。
之前所有讨论的思路都是第一种途径,这种途径其实没有从本质上解决你的问题,尤其是reloadable的需求。第二种途径是推荐的做法,既干净又有效。
我之所以推荐第二种方式,是因为你的问题其实和Struts2与JSTL整合的问题是极其类似的。JSTL和EL想要获取Struts2中Action内部的属性的值,通过什么方法呢?Action内部的值,完全不存在request/session/application的作用域中。Struts2给出的方案就是采用StrutsRequestWrapper。你可以思考一下,为什么一个框架级别的解决方案,也采用了这种方法呢?因为它是一种最佳实践。
极不情愿的下载了struts2,看了StrutsRequestWrapper的源码,两点感觉:
1.自己再维护一个ValueStack,不愿意也不会这么干;
2.看到了这个类的Comment,不爽:
All Struts requests are wrapped with this class, which provides simple JSTL accessibility. This is because JSTL works with request attributes, so this class delegates to the value stack except for a few cases where required to prevent infinite loops.
你们自己看看这个because
如果为了这个JSTL还要自己扩展request wrapper,感觉太委屈了自己——没必要这么找罪受吧我想
抱歉downpour,咱的境界也许没到你那个层次,咱只会干些投机取巧的事情(好像有这种感觉),总是觉得简单明了的解决方案就是最好的
18 楼
downpour
2011-04-17
itstarting 写道
downpour 写道
最好的方案应该是使用包装模式,把HttpServletRequest包装起来,并在包装类中定义特殊的表达式形式和值获取方式来返回结果。
请参照Struts2中的StrutsRequestWrapper是怎么处理JSTL标签对ValueStack的取值方式的。
请参照Struts2中的StrutsRequestWrapper是怎么处理JSTL标签对ValueStack的取值方式的。
这种做法也太笨重了吧?
难道其他引用request的地方也要考虑使用自己的request wrapper以求得一劳永逸?
我见过重新封装request,session,application的,但需求场景应该严重不一样。
还请多加指点
你对HttpServletRequestWrapper的作用还不理解,所以我才让你去看StrutsRequestWrapper的源码。
你的需求是试图通过JSTL或者EL来获取Java对象中的值。途径只有两种:第一,把你要取的值放到request/session/application中。第二,不要从request/session/application中去取值。
之前所有讨论的思路都是第一种途径,这种途径其实没有从本质上解决你的问题,尤其是reloadable的需求。第二种途径是推荐的做法,既干净又有效。
我之所以推荐第二种方式,是因为你的问题其实和Struts2与JSTL整合的问题是极其类似的。JSTL和EL想要获取Struts2中Action内部的属性的值,通过什么方法呢?Action内部的值,完全不存在request/session/application的作用域中。Struts2给出的方案就是采用StrutsRequestWrapper。你可以思考一下,为什么一个框架级别的解决方案,也采用了这种方法呢?因为它是一种最佳实践。
17 楼
itstarting
2011-04-16
downpour 写道
最好的方案应该是使用包装模式,把HttpServletRequest包装起来,并在包装类中定义特殊的表达式形式和值获取方式来返回结果。
请参照Struts2中的StrutsRequestWrapper是怎么处理JSTL标签对ValueStack的取值方式的。
请参照Struts2中的StrutsRequestWrapper是怎么处理JSTL标签对ValueStack的取值方式的。
这种做法也太笨重了吧?
难道其他引用request的地方也要考虑使用自己的request wrapper以求得一劳永逸?
我见过重新封装request,session,application的,但需求场景应该严重不一样。
还请多加指点
16 楼
downpour
2011-04-15
最好的方案应该是使用包装模式,把HttpServletRequest包装起来,并在包装类中定义特殊的表达式形式和值获取方式来返回结果。
请参照Struts2中的StrutsRequestWrapper是怎么处理JSTL标签对ValueStack的取值方式的。
请参照Struts2中的StrutsRequestWrapper是怎么处理JSTL标签对ValueStack的取值方式的。
15 楼
itstarting
2011-04-15
haitaohehe 写道
希望楼主多分享类似于这样有价值的文章。。。 实用
咱是实战派的,呵呵
不过这个帖子响应率超级低,可见大家应该有其他更好的方案
14 楼
haitaohehe
2011-04-14
希望楼主多分享类似于这样有价值的文章。。。 实用
13 楼
itstarting
2011-01-05
kongzhizhen 写道
为啥不在启动的时候就加载存放在Application Scope呢?
或者以内存表的方式加载并存储。
或者以内存表的方式加载并存储。
不是这个问题,或者说这不是问题,我们要解决和讨论的是其他问题:)
12 楼
kidneyball
2011-01-05
itstarting 写道
当然,这两种方法的思路其实都一样:put到application scope里。
这里外加一点小技巧——对于code table,提供的是引用而非真实数据,确保reloadable.
用自定义ELResolver的好处是,它允许你在求值的瞬间,对求值过程拥有完全的支配权。在ELResolver的getValue方法中你可以拿到EL表达式被求值瞬间的实时上下文,当然包括访问数据库或拿到spring bean。坏处是实现起来相对麻烦,要实现好几个接口方法。
在系统启动期把值put到application scope的好处是实现简单,事实上是借用了求值过程不可控的ScopedAttributeELResolver。问题是put进去与实际求值两个行为之间有个时间差。而reload,就是在还可控的代码中不断地调整application scope中的东西,使得在不可控的求值过程中能获取到尽可能最新的上下文。
当然,我个人觉得还是实用至上,能满足当前需求的方案就是好方案。自定义ELResolver可以作为一种候选方案,等有一天确实application scope方案满足不了再考虑也不迟。
11 楼
kongzhizhen
2011-01-05
为啥不在启动的时候就加载存放在Application Scope呢?
或者以内存表的方式加载并存储。
或者以内存表的方式加载并存储。
10 楼
itstarting
2011-01-05
kidneyball 写道
既然是增强EL表达式的解释能力,添加一个ELResolver会更加自然。
大致思路是,在应用启动时(例如你上面的 initApplicationContext()方法中,或者一个load-on-startup的servlet的init方法里)用
方法加入一个ELResolver的实现。(这个方法不能在应用已经处理过请求之后使用,否则会抛IllegalStateException)
这个ELResolver会被加入到JSP规范的默认的ImplicitObjectELResolver之后,其他规范ELResolver之前(例如BeanELResolver与ScopedAttributeELResolver)。也就是说,优先级低于隐含对象,高于scope属性。
在ELResolver中,是知道了EL表达式的实际内容(例如"Constants"字符串),再去求值。这时你可以用forName或者ClassLoader拿到Constants类(拿不到就不处理,留给后续的ELResolver处理,如果后续的Resolver也无法处理,容器就报错),这就没有reload的需要了。
详情可参考 http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/JspApplicationContext.html
大致思路是,在应用启动时(例如你上面的 initApplicationContext()方法中,或者一个load-on-startup的servlet的init方法里)用
JspFactory.getJspApplicationContext(javax.servlet.ServletContext).addELResolver(ELResorver resolver)
方法加入一个ELResolver的实现。(这个方法不能在应用已经处理过请求之后使用,否则会抛IllegalStateException)
这个ELResolver会被加入到JSP规范的默认的ImplicitObjectELResolver之后,其他规范ELResolver之前(例如BeanELResolver与ScopedAttributeELResolver)。也就是说,优先级低于隐含对象,高于scope属性。
在ELResolver中,是知道了EL表达式的实际内容(例如"Constants"字符串),再去求值。这时你可以用forName或者ClassLoader拿到Constants类(拿不到就不处理,留给后续的ELResolver处理,如果后续的Resolver也无法处理,容器就报错),这就没有reload的需要了。
详情可参考 http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/JspApplicationContext.html
谢谢指点
你说的这种方式看来是最“正统”的办法了——而我所提供的方法是更Spring-ly的
当然,这两种方法的思路其实都一样:put到application scope里。
这里外加一点小技巧——对于code table,提供的是引用而非真实数据,确保reloadable.
9 楼
kidneyball
2011-01-04
既然是增强EL表达式的解释能力,添加一个ELResolver会更加自然。
大致思路是,在应用启动时(例如你上面的 initApplicationContext()方法中,或者一个load-on-startup的servlet的init方法里)用
方法加入一个ELResolver的实现。(这个方法不能在应用已经处理过请求之后使用,否则会抛IllegalStateException)
这个ELResolver会被加入到JSP规范的默认的ImplicitObjectELResolver之后,其他规范ELResolver之前(例如BeanELResolver与ScopedAttributeELResolver)。也就是说,优先级低于隐含对象,高于scope属性。
在ELResolver中,是知道了EL表达式的实际内容(例如"Constants"字符串),再去求值。这时你可以用forName或者ClassLoader拿到Constants类(拿不到就不处理,留给后续的ELResolver处理,如果后续的Resolver也无法处理,容器就报错),这就没有reload的需要了。
详情可参考 http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/JspApplicationContext.html
大致思路是,在应用启动时(例如你上面的 initApplicationContext()方法中,或者一个load-on-startup的servlet的init方法里)用
JspFactory.getJspApplicationContext(javax.servlet.ServletContext).addELResolver(ELResorver resolver)
方法加入一个ELResolver的实现。(这个方法不能在应用已经处理过请求之后使用,否则会抛IllegalStateException)
这个ELResolver会被加入到JSP规范的默认的ImplicitObjectELResolver之后,其他规范ELResolver之前(例如BeanELResolver与ScopedAttributeELResolver)。也就是说,优先级低于隐含对象,高于scope属性。
在ELResolver中,是知道了EL表达式的实际内容(例如"Constants"字符串),再去求值。这时你可以用forName或者ClassLoader拿到Constants类(拿不到就不处理,留给后续的ELResolver处理,如果后续的Resolver也无法处理,容器就报错),这就没有reload的需要了。
详情可参考 http://download.oracle.com/docs/cd/E17802_01/products/products/jsp/2.1/docs/jsp-2_1-pfd2/javax/servlet/jsp/JspApplicationContext.html
8 楼
itstarting
2010-12-28
xieke 写道
itstarting 写道
我目前的思路是:
1、对于Constants,我将自动在启动时导出为applicationScope的map;
2、对于Code Table,我将自动在启动时加载到一系列的map,以CodeType为key
那之后就可以用“标准”的EL语法透明的访问Constants和CodeTable了。
但在这里有一个问题,那就是对于Code Table而言,一旦“自动在启动时加载到一系列的map”,会不会导致这些Code Table是non-reloadable的——我想这是难以让人接受的——总不能改一下系统变量就要reload一次application吧?
1、对于Constants,我将自动在启动时导出为applicationScope的map;
2、对于Code Table,我将自动在启动时加载到一系列的map,以CodeType为key
那之后就可以用“标准”的EL语法透明的访问Constants和CodeTable了。
但在这里有一个问题,那就是对于Code Table而言,一旦“自动在启动时加载到一系列的map”,会不会导致这些Code Table是non-reloadable的——我想这是难以让人接受的——总不能改一下系统变量就要reload一次application吧?
该系统变量时 单独对 Map 里某个 key 作更新就好了,为何要reload.
你这种思路是:更改后马上更新,即时生效。
也是不错的思路
但需要remove掉原先application scope中,当前在改的key的map,然后再reload进来,感觉有点麻烦——会不会对原先的code table管理部分造成不必要的困扰?
7 楼
itstarting
2010-12-28
itstarting 写道
而针对code table的解决方案,其实有不少技巧:
1、暴露到application scope的不是简单的数据,而是引用[color=red][/color]。这一点非常重要,也确保了我们的code table是reloadable的——而reload的策略,完全取决于业务的需要,比如我们用ibatis,可以简单的配置cache-model就行了,此时在DAO层cache,如要在service层,要专门考虑采用cache框架的API;
2、单独定义一个需要真正业务实现的接口,这样就变得更具通用性了。
接口定义:
为此,解决方案提供完毕。
当然了,关于Constants和Code table是整合考虑的方案,我分开了描述,只是为了阐述更有针对性而已
大家整合两部分的代码即可
欢迎讨论
1、暴露到application scope的不是简单的数据,而是引用[color=red][/color]。这一点非常重要,也确保了我们的code table是reloadable的——而reload的策略,完全取决于业务的需要,比如我们用ibatis,可以简单的配置cache-model就行了,此时在DAO层cache,如要在service层,要专门考虑采用cache框架的API;
2、单独定义一个需要真正业务实现的接口,这样就变得更具通用性了。
public class ApplicationScopeLoader extends WebApplicationObjectSupport { ... /** code table service */ private final CodeTableLoaderService codeTableLoaderService = ApplicationContextManager .getBean("codeTableLoaderService",CodeTableLoaderService.class); private final static String CODE_TABLE_CONTEXT_NAME = "CodeTable"; protected void initApplicationContext() { try { //build constants and put it to the application scope this.buildConstants(); //build code table and put it to the application scope this.buildCodeTables(); } catch (Exception e) { e.printStackTrace(); } } /** * build code tables * each code table will be group by the type * for example, if there is a code table type 'gender' * then will be put to */ private void buildCodeTables(){ String[] codeTypes = codeTableLoaderService.loadAllCodeTypes(); for(String codeType: codeTypes){ this.buildOneCodeTableByCodeType(codeType); } } /** * extract given codes to a sub array of codes by code type * @param codes * @return */ private void buildOneCodeTableByCodeType(String codeType){ Map<Object,Object> codeMap = new HashMap<Object,Object>() { private static final long serialVersionUID = -1759893921358235848L; /** * get from the service, not raw data for avoiding non-refresh issue */ public Object get(Object key) { return codeTableLoaderService.getCodesByType(String.valueOf(key)); } public boolean containsKey(Object key) { return true; } }; logger.debug("put code table of [{}] to application scope.", codeType); this.getServletContext().setAttribute(CODE_TABLE_CONTEXT_NAME, codeMap); } }
接口定义:
/** * It's a code table loading service * for exporting code tables to application scope * * but we don't put the dummy data to application scope directly * for avoiding non-refreshable issue * * @author bright_zheng * */ public interface CodeTableLoaderService { /** * load all code types from db/cache * * @return an array including all code types */ public String[] loadAllCodeTypes(); /** * get all code objects/beans filter by code type * * @param codeType * @return responding code objects/beans */ public Object[] getCodesByType(String codeType); }
为此,解决方案提供完毕。
当然了,关于Constants和Code table是整合考虑的方案,我分开了描述,只是为了阐述更有针对性而已
大家整合两部分的代码即可
欢迎讨论
补充用法:
1、在HTLM元素中使用:
--这里用了Spring的TAG,当然谁的TAG并不是关键 <form:select path="hotel.country"> <form:option value="-" label="--Please Select"/> <form:options items="${CodeTable.Gender}" itemValue="codeValue" itemLabel="codeName"/> </form:select>
这里表示要以Code Type为Gender的作为下拉框元素
2、用以打印:
<c:forEach var="ct" items="${CodeTable.Gender}"> -->codeName: ${ct.codeName}, -->codeValue: ${ct.codeValue}, -->codeDesc: ${ct.codeDesc}<br> </c:forEach>
对了,我这里为了方便,封装了个简单的CodeTable POJO,一并贴出来:
public class CodeTable implements Serializable { private String codeType; private String codeName; private String codeValue; private String codeDesc; //getter/setter omitted ... }
6 楼
xieke
2010-12-28
itstarting 写道
我目前的思路是:
1、对于Constants,我将自动在启动时导出为applicationScope的map;
2、对于Code Table,我将自动在启动时加载到一系列的map,以CodeType为key
那之后就可以用“标准”的EL语法透明的访问Constants和CodeTable了。
但在这里有一个问题,那就是对于Code Table而言,一旦“自动在启动时加载到一系列的map”,会不会导致这些Code Table是non-reloadable的——我想这是难以让人接受的——总不能改一下系统变量就要reload一次application吧?
1、对于Constants,我将自动在启动时导出为applicationScope的map;
2、对于Code Table,我将自动在启动时加载到一系列的map,以CodeType为key
那之后就可以用“标准”的EL语法透明的访问Constants和CodeTable了。
但在这里有一个问题,那就是对于Code Table而言,一旦“自动在启动时加载到一系列的map”,会不会导致这些Code Table是non-reloadable的——我想这是难以让人接受的——总不能改一下系统变量就要reload一次application吧?
该系统变量时 单独对 Map 里某个 key 作更新就好了,为何要reload.
发表评论
-
Netty + Protobuf 的客户端模式运用和问题探讨
2012-05-14 16:04 6161使用NETTY之前,当然需要先看一下所带的samples。 ... -
实战:使用JMeter的Java Sampler轻松定制自己的benchmark
2012-05-06 22:08 4498以前碰到更多的是WEB APP ... -
如何从零开始编写一个企业级的生物匹配引擎
2012-04-29 23:35 1322考虑编写一篇文章,以分享个人的一些所谓引擎策划、架构、实现和验 ... -
JBoss在单机下多实例的配置备忘
2011-06-17 16:41 2557版本:jboss-5.1.0.GA + JDK 1.6 ... -
能不能让log4j跑的“更快”,对业务总体执行时间影响更小?
2011-06-10 00:00 2803最近事情不多,翻了一下log4j的源代码,发现这个一直跟 ... -
大家都用什么Maven插件?及本人的几个常用插件分享
2011-01-25 12:47 5156两个月前我只是一直知道有Maven,但从来没用过也没这个计划, ... -
Spring MVC 3.x annotated controller的几点心得体会
2010-11-29 17:59 9972最近拿Spring MVC 3.x做项目,用了最新的系列相关A ... -
让Ajax框架Buffalo支持JSON协议而非仅仅自定义的XML协议[JS前端及单元测试完成]
2010-01-14 16:01 2869Buffalo默认实现了一套很棒的自定义XML协议(具体请参考 ... -
Ajax框架Buffalo深度研究
2010-01-11 14:37 2240Buffalo深度研究 ——2010.01.11, IT进行 ...
相关推荐
当你遇到`java.lang.NoClassDefFoundError: javax/servlet/jsp/jstl/core/ConditionalTagSupport`这样的异常时,意味着在运行时系统找不到这个类,这通常是由于缺少JSTL相关的依赖或者配置不正确所导致的。...
无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core],解决办法:WEB/INF的lib下,除了导入jstl.jar包,还要导入standard.jar包。另外,解压standard.jar包,把.tld文件...
JavaWeb分页展示数据是Web应用开发中的常见需求,它涉及到多个关键技术的综合运用,包括AJAX、JSTL、EL表达式以及JSP标准动作。在这个项目中,我们将深入探讨这些技术,以便理解如何有效地在网页上实现数据的动态...
添加依赖项到一个WEB应用程序: 在web应用程序中,添加以下JAR包到/web-inf/lib目录: - taglibs-standard-spec-1.2.5.jar - taglibs-standard-impl-1.2.5.jar - taglibs-standard-jstlel-1.2.5.jar - xalan-...
JSTL是一组标签库,提供了处理常见任务如迭代、条件判断、XML操作等功能,而EL则是一种轻量级的表达式语言,用于在JSP中简洁地访问和操作数据。 **1. EL(Expression Language)** 1. **EL表达式语法** EL表达式...
**JSTL(JavaServer Pages Standard Tag Library)与EL(Expression Language)是Java Web开发中的两个重要组件,它们极大地简化了JSP页面的编写和管理,使得代码更加清晰和易于维护。** **JSTL** 是一个标准的标签...
有的时候在开发jsp时,需要使用jstl时,在jsp上面引用jstl却出现错误:Can not find the tag library descriptor for "http://java.sun.com/jsp/jstl/core,这是由于缺少两个jar包导致的。
EL 表达式和 JSTL 是 JSP 开发中非常重要的技术,它们可以使开发人员更方便地访问页面内容,实现逻辑控制,优化代码结构。但是,EL 表达式和 JSTL 也需要开发人员具备一定的知识和经验,以便更好地使用它们。
它的主要目标是提供一种简单的方式来访问存储在作用域中的对象属性,以及执行基本的算术和逻辑操作。EL表达式通常在`${}`中书写,比如`${user.name}`用来获取名为`user`的对象的`name`属性。 **JSTL中的核心标签库...
### JSTL与EL的关系详解 #### 引言 在探讨JSTL(JSP Standard Tag Library,JSP标准标签库)与EL(Expression Language,表达式语言)之间的关系前,我们首先需理解两者的基本概念及其在JSP(JavaServer Pages)...
**JSTL(JavaServer Pages Standard Tag Library)和EL(Expression Language)是Java Web开发中的两个重要组件,它们极大地简化了JSP页面的编写和管理。** **JSTL** 是一套标准的标签库,提供了丰富的功能,如迭代...
在JavaServer Pages (JSP)开发中,JSTL(JavaServer Pages Standard Tag Library)和EL(Expression Language)是两种非常重要的技术,用于简化页面逻辑和增强可读性。本篇将详细介绍如何在JSP中利用JSTL与EL表达式...
《基于JSTL和EL的学生管理系统详解》 在IT行业中,Web开发是不可或缺的一部分,而JavaWeb技术则是其中的重要支柱。对于初学者来说,掌握一套简单易懂的Web项目框架至关重要,"学生管理系统JSTL+EL.zip" 就是一个很...
会议管理系统使用EL和JSTL优化jsp页面
EL用于获取和设置应用程序范围内的对象属性,而JSTL标签则用于处理复杂的逻辑。例如,`<c:out>`标签可以配合EL表达式显示变量的值。 **示例:** ```jsp <%@ taglib prefix="c" uri="http://java.sun....
1. 访问变量:EL 表达式可以访问 JSP 页面中的变量,包括 page、request、session 和 application 等四个作用域中的变量。 例如:${user.name} 访问 user 对象的 name 属性 2. 进行逻辑操作:EL 表达式可以进行...
**JSF(JavaServer Faces)** 是一个Java平台上的开源Web应用程序框架,它提供了一种组件化和事件驱动的方式来创建用户界面。JSF的核心概念是UI组件,这些组件可以组合成复杂的用户界面,并且能够与后端数据模型进行...
在Java Web开发中,JSTL(JavaServer Pages Standard Tag Library)和EL(Expression Language)是两个非常重要的组件,它们极大地简化了页面逻辑的编写,提高了代码的可读性和维护性。下面将详细介绍这两个概念以及...
通过这样的方式,我们可以利用JSTL和EL的强大功能,将复杂的分页逻辑封装在后端,保持JSP页面的整洁和高效。在ACCP 5.0这样的课程中,学习如何使用JSTL和EL进行分页是非常有价值的一部分,因为它们是企业级Web开发中...