Struts2 Core Developers Guide-Cookbook

1.Handling File Uploads
  • 采用FileUploadInterceptor实现文件上传操作.
  • 定义struts.properties文件中的如下属性来实现一下参数的配置
  • struts.multipart.parser定义解析用户上传文件的库.
    struts.multipart.saveDir定义用户上传文件保存的路径.
    struts.multipart.maxSize指定上传文件的最大值设置.

2.HibernateAndSpringEnabledExecuteAndWaitInterceptor
  • 该例子是对ExecuteAndWaitInterceptor的一个扩展
  • 目的是为了让后台线程运行的时候可以获取到hibernate的session中的对象,感觉上和opensessioninview类似.
  • 具体的实现类是OpenSessionExecuteAndWaitInterceptor
  • 重新新的OpenSessionBackgroundProcess类以确保在后台线程执行的过程中,session始终不被关闭,以保证事务.

3.How to validate field formats, such as a phone number
可以利用正则表达式实现
<validators>
    <field name="phone">
        <field-validator type="regex">
            <param name="expression">\([\d][\d][\d]\) [\d][\d][\d]-[\d][\d][\d][\d]</param>
            <message>Phone number must be in the format (XXX) XXX-XXXX</message>
        </field-validator>
    </field>

4.如何在jsp页面上访问session,request等对象中的属性
如下
<s:property value="#application\['foo'\]"/>
<s:property value="#session\['baz'\]"/>

struts2中所有的ognl的对象都默认暴露给jsp或者jstl标记库.
5.Value Stack Internals(值堆栈的内部实现机制)
Value本质上就是一个list
在value stack上调用[1]返回是的是从index 1开始的一个子列表,只有调用stack上的peek或者pop等方法才能返回实际stack中的实际对象.
举例如下,假设有一个列表包含了[model,action]
[0]返回CompoundRoot对象包含[model,action]
[1]返回CompoundRoot对象包含[action]
[0].toString()调用value stack上第一个存在toString()方法的对象.
[1].foo从调用从action stack上的第一个对象的getFoo()方法,
<ww:property value="[0].peek()"/>不会正常工作因为sturts2会把该方法翻译为从堆栈头部开始查找有peek()方法的第一个对象.
在struts2中栈中的对象有
    *  req - the current HttpServletRequest
    * res - the current HttpServletResponse
    * stack - the current OgnlValueStack
    * ognl - an instance of OgnlTool
    * ui - a (now deprecated) instance of a ui tag renderer
6.OGNL
OGNL规则
假设堆栈中有两个对象foo,bar,foo是堆栈root元素,要获取堆栈中的值可以用如下语法
#foo.blash
#bar.blash
blash-->foo.bash(由于foo是root元素所以foo和#前缀可以省略.
OGNL栈在struts的实现中处于是的栈的root元素
value stack上存储了很多对象,但是对与ognl来说它们看起来就像只有一个对象.
在root元素之外struts2还存储了其他的对象例如session,request等等的对象.
他们之中数值的访问必须加上#session,#request等等前缀.
实际的树状图如下
        |
                     |--application
                     |
                     |--session
       context map---|
                     |--value stack(root)
                     |
                     |--request
                     |
                     |--parameters
                     |
                     |--attr (searches page, request, session, then application scopes)
                     |
value stack中的对象有
action对象.
7.Collections (Maps, Lists, Sets)的创建和处理
list: {e1,e2,e3}
map: #{key1:value1,key2:value2}
判断集合中是否有某个元素
<s:if test="'foo' in {'foo','bar'}">
   muhahaha
</s:if>
<s:else>
   boo
</s:else>

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

获取集合的子集
    *  ? - All elements matching the selection logic
    * ^ - Only the first element matching the selection logic
    * $ - Only the last element matching the selection logic
person.relatives.{? #this.gender == 'male'}
Lambda Expressions
<s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" />

上列语句中[]以内的部分为lambda表达式,#this表示函数的参数
8.在页面上显示action中的bean的值
如果需要显示多个bean的值
<webwork:property value="myBean"> 
<!- This will call getName() on your TestBean and print it to the page -->
The name is: <webwork:property value="name"/>
</webwork:property>

如果只需要显示单个的值
<webwork:property value="myBean.name" />
9.Tabular inputs(批量输入)
<s:iterator value="cart.items" status="rowstatus">
  <s:hidden name="cart.items[%{#rowstatus.index}].productId" value="%{productId}">
  <s:textfield name="cart.items[%{#rowstatus.index}].qty" value="%{qty}" />
  <s:textfield name="cart.items[%{#rowstatus.index}].note" value="%{note}" />
</s:iterator>

如果后台list中item的个数不确定的话可以使用XworkList来代替ArrayList.Xwork中get方法的源码如下
        while (index >= this.size()) {
            try {
                //todo
                this.add(objectFactory.buildBean(clazz, null)); //ActionContext.getContext().getContextMap()));
            } catch (Exception e) {
                throw new XWorkException(e);
            }
        }

        return super.get(index);

10.HTML form buttons HOWTO
[list]
  • Determine Which Button Was Pressed(一个form多个button多个方法)
  • cookbook中列举的例子是利用每个button的name对应一个boolean的属性来解决.
    但是在spring+struts的例子中看好像也可以通过如下方式实现
    <s:submit value="%{getText('button.label.cancel')}" name="redirect-action:index"/>
  • Dynamic Set of Buttons(列表中存在多个submit按钮每个按钮提交到对应的需要修改的对象)
  • 前端
    <form action="UpdateCart.action">
      <s:iterate value="items">
        <s:property value="name"> 
        <input type="submit" name="delete[<s:property value='id'>]" value="delete" /> <br/>
      </s:iterate>
    </form>

    后台
     private Map delete = new HashMap();

    提交到id将被提交到后台页面上作为key保留.
    该技术可以用于提供批量保存的功能.



  • [/list]

    你可能感兴趣的:(spring,Hibernate,bean,正则表达式,struts)