struts2学习笔记(3)——标签、其他

jstl标准标签库类似的,struts有专属标签库 
form标签用于提交数据
修改addProduct.jsp
<html>
 
<body>
 
<s:form action="addProduct">
 
  <s:textfield name="product.name" label="product name" />
  <s:submit value="Submit" />
 
</s:form>
 
</body>
</html>
访问
http://127.0.0.1:8080/struts/addProduct.jsp

通过浏览器查看源码可以发现,struts把表单里的内容自动转换成了table
<form id="addProduct" name="addProduct" action="addProduct.action" method="post">
<table class="wwFormTable">
 
  <tr>
    <td class="tdLabel"><label for="addProduct_product_name" class="label">product name:</label></td>
    <td
><input type="text" name="product.name" value="" id="addProduct_product_name"/></td>
</tr>
 
  <tr>
    <td colspan="2"><div align="right"><input type="submit" id="addProduct_0" value="Submit"/>
</div></td>
</tr>
 
</table></form>

JSTL标准标签库c:forEach类似的,struts也提供了一个s:iterator用于遍历一个集合中的数据
为ProductAction增加list方法
1. 为ProductAction增加一个products属性,类型是List,并提供getter setter 
2. 为ProductAction增加一个list()方法,为products添加3个product对象,并返回“list"
private List<Product> products;
  
    public List<Product> getProducts() {
        return products;
    }
  
    public void setProducts(List<Product> products) {
        this.products = products;
    }
struts.xml
配置路径listProduct,并返回list.jsp
<action name="listProduct" class="com.how2java.action.ProductAction" method="list">
    <result name="list">list.jsp</result>
  </action
list.jsp
使用s:iterator标签进行遍历
value 表示集合
var 表示遍历出来的元素
st 表示遍历出来的元素状态
st.index 当前行号 基0
st.count 当前行号 基1
st.first 是否是第一个元素
st.last 是否是最后一个元素
st.odd 是否是奇数
st.even 是否是偶数
<s:iterator value="products" var="p" status="st">
        <tr>
            <td>${p.id}</td>
            <td>${p.name}</td>
            <td>${st.index}</td>
            <td>${st.count}</td>
            <td>${st.first}</td>
            <td>${st.last}</td>
            <td>${st.odd}</td>
            <td>${st.even}</td>
        </tr>
    </s:iterator>

遍历3个product成为checkbox 
并且第2个和第3个是默认选中的
除了前例中准备的products
再新增一个属性ListselectedProducts,用于存放哪些产品被选中了
注意: ListselectedProducts 里放的是id,而不是对象
private List<Integer> selectedProducts;
    public List<Integer> getSelectedProducts() {
        return selectedProducts;
    }
 
    public void setSelectedProducts(List<Integer> selectedProducts) {
        this.selectedProducts = selectedProducts;
    

使用s:checkboxlist标签
value:哪些被选中
name:提交到服务端用的名称
list:用于遍历的集合
listValue:显示的checkbox的名称
listKey:checkbox的value
<s:checkboxlist value="selectedProducts" name="product.id"
    list="products" listValue="name" listKey="id" />

遍历products成为radio,并选中第二个
在前例checkbox标签的基础上增加s:radio标签
value表示:哪项被选中
name表示:提交到服务端用的名称
list:用于遍历的集合
listValue:显示的radio的名称
listKey:radio的value
<s:radio name="product.id" value="2" list="products" listValue="name"
    listKey="id" />

遍历products成为select标签 
默认选中第2个和第3个

使用s:select标签
name表示:提交到服务端用的名称
list:用于遍历的集合
listKey:每个option的value
listValue:显示的名称
multiple:true表示可以选中多行
size="3"表示默认显示3行
value表示:哪些被选中

注: 可以增加一个属性 theme="simple" 使得最后生成的最简单的风格的html,否则就会有一些奇奇怪怪的tr td
或者直接在struts.xml中加一句 Servlet下载文件 
<constant name="struts.ui.theme" value="simple"/>
注: 如果要增加class,需要使用属性: cssClass
<s:select label="products"
       name="product.id"
       list="products"
       listKey="id"
       listValue="name"
       multiple="true"
       size="3"
       value="selectedProducts"
/>


学习到目前为止,addshow, list分别需要进行配置 
通过通配符匹配可以把这3个配置整合在一个配置中实现
*Product 表示所有以Product结尾的路径,都会匹配在这个Action上 
method={1}表示第一个通配符 
如果访问的是addProduct就会调用add方法 
如果访问的是listProduct就会调用list方法 
<struts>
  <constant name="struts.i18n.encoding" value="UTF-8"></constant>
   
  <package name="basicstruts" extends="struts-default">
  
  <action name="*Product" class="com.how2java.action.ProductAction" method="{1}">
    <result name="show">show.jsp</result>
    <result name="list">list.jsp</result>
  </action>   
 
</package>
 
</struts>

拦截器可以简单地看成是Struts中的"filter" 
拦截器可以拦截指定的Action,并且对Action进行相应的操作 
在本例里,拦截了ProductAction,并且注入了当前时间
ProductAction.java
准备一个Date属性,用于被拦截器注入时间
list.jsp
用于显示时间 
当然现在是显示不出来的,因为还没有拦截器对ProductAction进行时间注入
${date}
把拦截到的Action强制转换成 ProductAction,并设置当前时间(注入)
package com.how2java.interceptor;
import java.util.Date; 
import com.how2java.action.ProductAction;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class DateInterceptor extends AbstractInterceptor {
 
    public String intercept(ActionInvocation invocation) throws Exception {
       ProductAction action = (ProductAction)invocation.getAction();
       action.setDate(new Date());
       return invocation.invoke();
    }
}

配置struts.xml
10-12 声明dateInterceptor 
16 对ProductAction使用拦截器dateInterceptor 
17 一旦使用了自定义的拦截器,本来配置在action上的默认的拦截器就失效了。 所以需要再加上defaultStack
struts2学习笔记(3)——标签、其他

Struts 默认跳转方法是服务端跳转 
本例演示如何进行客户端跳转
ProductAction.java
新增addPage方法,返回“addPage"
public String addPage(){
        return "addPage";
    }
配置客户端跳转 
在result标签里加上新的属性: type="redirect"
<action name="addPageProduct" class="com.how2java.action.ProductAction" method="addPage">
    <result name="addPage" type="redirect">addProduct.jsp</result>
  </action

客户端跳转传参
ProductAction.java
1. 准备name属性 
2. 在addPage()中设置name的值
private String name;
     
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
public String addPage(){
        name = "default name";
        return "addPage";
    }

struts.xml
设置参数传递 
增加?name=${name}
<action name="addPageProduct" class="com.how2java.action.ProductAction" method="addPage">
    <result name="addPage" type="redirect">addProduct.jsp?name=${name}</result>
  </action
addProduct.jsp
获取参数:
<form action="addProduct">
 
 <input type="text" name="product.name" value="${param.name}">
    <br/>
 <input type="submit" value="submit">
</form>

在默认设置下,Action是多实例的,每次访问都会创建新的Action实例
修改ProductAction
在ProductAction的构造方法里打印this