Thursday, October 19, 2006

Sometimes Love Just Aint Enough

前几天(到底是几天已经忘记了)半夜把床边的吉他碰倒。吉他意外的不争气的只发出一声闷响。这才想起,几个星期前断了弦后,一直没买回。几天前(又忘记了)更把吉他其他弦都松掉了。。。。
哎,哎。。

晚上听孙燕姿的Sometimes Love Just Aint Enough 觉得还不错,就顺便找来谱子,抱起5根弦的吉他弹弹。恩,还有点意思,周末去买弦吧。

Wednesday, October 18, 2006

Strut 多模块的实现

Strut 多模块的功能还是很有用的,USER GUIDE上的介绍稍微简单了点。
在N次失败后,终于成功了,顺便把经验贴出来
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>

<init-param>
<param-name>config/man</param-name>
<param-value>/WEB-INF/struts-config-man.xml</param-value>
</init-param>

struts-config-man.xml里面配置了一个 path="/try" 的action
然后在网页的根目录上建了一个目录man,并在里面放上index.jsp
index.jsp有一个FORM,内容如下:
代码

<html:form action="/try">

......

</html:form>


这时若直接访问index.jsp会报错说找不到action什么的

但是如果不用html:form标签而是使用普通HTML是可以的:
代码

<form action="try.do">

......

</form>


原因是访问JSP时标签在LOOKUP对应的ACTION时module path还是根模块(上例中struts-config.xml所在的module)所以找不到ACTION。
解决办法是在man 所在的module里增加个action来跳转

如在struts-config-man.xml里加一个action:

代码
<action forward="/index.jsp" path="/index" />

访问/man/index.do后STRUTS就会载入man的module path ,于是就可以正常访问index.jsp了

Tuesday, October 17, 2006

翻译webwork user guide上关于OGNL的部分

无论webwork还是struts2都用到了OGNL,学习之余,顺便把webwork user guide上关于OGNL的部分翻译出来

原文路径:http://www.opensymphony.com/webwork/wikidocs/OGNL.html

OGNL意指对象图形导航语言(Object Graph Navigation Language),你可以到http://www.ognl.org看关于OGNL的完整资料。在本文,我们只会讲述OGNL的在WebWork中用到的部分。并就次说明一些基本的OGNL概念。

WebWork使用一个标准的命名上下文来获取OGNL表达式。OGNL所处理的最上一级的对象是一个MAP(通常看作一个上下文MAP)。OGNL有一个根对象(在WebWork里,为GNLValueStack).与根对象一起放入上下文MAP的其他对象包括session/application/request/attrmap。这些对象与根对象是无关的,它们只是一同存在于上下文MAP中而已。所以访问这些对象,需要添加#号。#号是用来告诉OGNL在上下文的其他部分,而不是在根对象中执行查找。


|--request
|
|--application
|
context map---|--OgnlValueStack(root)
|
|--session
|
|--attr
|
|--parameters



请注意还有其他的对象存在于上下文MAP中。这里只是列出了一部分作为例子。actions实际上是放在OGNLValueStack(译:即Root,根对象)里的,所以你可以访问你的bean属性,而无须使用#号。如:
<ww: value="myBean.myProperty">
对于sessions,request, 等其他上下文map中的对象:
<ww:property value="#session.mySessionPropKey"> or
<ww:property value="#session['mySessionPropKey']"> or
<ww:property value="#attr.mySessionPropKey">

Collections (Maps, Lists, Sets)

处理collection在webwrok 中是相当普遍的,这里列出了一些使用select 标签的例子:
list的语法:{e1,e2,e3}. 这将会创造一个包含‘name1','name2','name3的 list,并把 "name2" 作为默认值. 请注意,需要使用 Alt语法 来获得name2的值.

<ww:select label="label" name="name" list="{'name1','name2','name3'}" value="%{'name2'}">


map的语法: #{key1:value1,key2:value2}.这将会创造一个包含map。该MAP中 "foo" 是“foovalue" 的键,"bar"是 "barvalue"的键
<ww:select label="label" name="name" list="#{'foo':'foovalue', 'bar':'barvalue'}">

如果你需要判断一个元素是否已经存在于collection中,你可以用 in 和not in来完成:

<ww:if test="'foo' in {'foo','bar'}">
muhahaha
</ww:if>
<ww:else>
boo
</ww:else>

<ww:if test="'foo' not in {'foo','bar'}">
muhahaha
</ww:if>
<ww:else>
boo
</ww:else>

你还可以使用以下的通配符来获取collection中的一个子集:
* ? - 所有匹配选择逻辑的元素
* ^ - 第一个匹配选择逻辑的元素
* $ - 最后一个匹配选择逻辑的元素

比如,要在persion对象中获取子集:

person.relatives.{? #this.gender == 'male'}

Lambda Expressions

OGNL支持基本的lamba 表达式语法,使你能写简单的函数:例如:

Fibonacci: if n==0 return 0; elseif n==1 return 1; else return

fib(n-2)+fib(n-1);
fib(0) = 0
fib(1) = 1
fib(11) = 89

下例中,括弧里面的都是lambda 表达式.#this 变量是一个初始值为11的参数

<ww:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)"></ww:property>

Saturday, October 14, 2006

关于Strut的权限控制

javaeye上看到有人讨论
使用JIVE的代理模式来扩展struts+Spring+Hibernate的web框架
其实是想用PROXY实现权限控制,作者认为:

管理员对系统模块的操作权限认证,有主要有三种方法:
1.在每个需要认证的模块前面插入一段验证码.
2.使用AOP或拦截器.
3.使用代理设计模式.

第一种方法,太笨.
第二种方法,在struts中不易实现,因为Strust的Action被Struts容器接管理,Action初始化,实例化都是由系统自动进行的.如果真的是由AOP实现,也许是一大推代码,很麻烦.于是作者选择为action创建proxy类,其实这样一来就要为每个action 提供一个proxy,非常麻烦。如果使用动态PROXY,那会好点。不过个人认为动态PROXY,还不如加FILTER方便了,起码FILTER简单些

Thursday, October 12, 2006

Java中获取配置/资源文件

关键字: java 获取 配置文件 资源文件 Properties ClassLoader

几乎所有的系统都需要通过获取配置/资源文件来方便配置系统
但怎样获取资源文件呢

java的应用通常把配置文件和工程中的其他class放在一起(如log4j),原因是可以方便的使用classLoader的 getResourceAsStream()方法获取资源(其实java内部就是这样来
load class的),下面是一个简单例子:

比如你把文件(abc.properties)放到com.yourcompany.common包里面,在确保classpath包括该包的情况
下就可以按下面的方法获取资源

ClassLoader cl = this.getClass().getClassLoader();
InputStream is = cl.getResourceAsStream("com/yourcompany/"+abc.properties)

如果abc.properties是一个标准的properties文件的话 , 假设它的内容如下:

messageA = Ok!

则可以这样获取配置信息:
Properties props = new Properties();
props.load(is);
String messageA = props.getProperty("messageA ");

则messageA就会等于 "Ok"

当然properties也可以是XML格式,只要他符合http://java.sun.com/dtd/properties.dtd的规范并且声明了DOCTYPE declaration,就可以用props.loadFromXML(InputSteam in)方法载入property

ps:property 也提供store()和storeToXML方法保存属性
关于classLoader也可以看看 《classloader相关基础知识》 这个文章