一 Struts框架(下)

时间:2024-08-19 14:36:26

1 struts FORM 标签

与jstl标准标签库类似的,struts有专属标签库
form标签用于提交数据

修改addProduct.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
    <title>submit</title>
</head>
<body>
<s:form action="addProduct">

    <s:textfield name="product.name" label="product name" />
    <s:submit value="Submit" />

</s:form>
</body>
</html>

一 Struts框架(下)

2 struts使用S:ITERATOR 标签遍历集合

  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;
     }
     public String list() {
    
     products=new ArrayList();
    
     Product p1 = new Product();
     p1.setId(1);
     p1.setName("product1");
     Product p2 = new Product();
     p2.setId(2);
     p2.setName("product2");
     Product p3 = new Product();
     p3.setId(3);
     p3.setName("product3");
    
     products.add(p1);
     products.add(p2);
     products.add(p3);
    
     return "list";
    
     }

struts.xml中添加

     <action name="listProduct" class="com.tzy.struts.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 是否是偶数
          <%@ page language="java" contentType="text/html; charset=UTF-8"
                   pageEncoding="UTF-8" isELIgnored="false"%>
    
          <%@ taglib prefix="s" uri="/struts-tags"%>
    
          <style>
              table {
                  border-collapse: collapse;
              }
    
              td {
                  border: 1px solid gray;
              }
          </style>
    
          <table align="center">
              <tr>
                  <td>id</td>
                  <td>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 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>
    
          </table>

    一 Struts框架(下)

3 struts如何使用CHECKBOXLIST 标签

修改ProductAction.java
再新增一个属性List
selectedProducts,用于存放哪些产品被选中了
注意: ListselectedProducts 里放的是id,而不是对象

  private List<Integer> selectedProducts;
    public List<Integer> getSelectedProducts() {
        return selectedProducts;
    }

    public void setSelectedProducts(List<Integer> selectedProducts) {
        this.selectedProducts = selectedProducts;
    } 

修改list方法

public String list() {

    products=new ArrayList();
    selectedProducts = new ArrayList();

    Product p1 = new Product();
    p1.setId(1);
    p1.setName("product1");
    Product p2 = new Product();
    p2.setId(2);
    p2.setName("product2");
    Product p3 = new Product();
    p3.setId(3);

    p3.setName("product3");

    products.add(p1);
    products.add(p2);
    products.add(p3);

    selectedProducts.add(2);
    selectedProducts.add(3);

    return "list1";

}

list1.jsp

  • 使用s:checkboxlist标签
    • value:哪些被选中
    • name:提交到服务端用的名称
    • list:用于遍历的集合
    • listValue:显示的checkbox的名称
    • listKey:checkbox的value
    <%@ page language="java" contentType="text/html; charset=UTF-8"
             pageEncoding="UTF-8" isELIgnored="false"%>

    <%@ taglib prefix="s" uri="/struts-tags"%>

    <s:checkboxlist value="selectedProducts" name="product.id"
                    list="products" listValue="name" listKey="id" />

一 Struts框架(下)

4 struts 如何使用标签

遍历products成为radio,并选中第二个

  • 在前例checkbox标签的基础上增加s:radio标签
    • value表示:哪项被选中
    • name表示:提交到服务端用的名称
    • list:用于遍历的集合
    • listValue:显示的radio的名称
    • listKey:radio的value

修改 list1.jsp

<s:radio name="product.id" value="2" list="products" listValue="name" listKey="id" />

一 Struts框架(下)

5 struts 如何使用S:SELECT 标签

  • 使用s:select标签
    • name表示:提交到服务端用的名称
    • list:用于遍历的集合
    • listKey:每个option的value
    • listValue:显示的名称
    • multiple:true表示可以选中多行
    • size="3"表示默认显示3行
    • value表示:哪些被选中
  • 注: 可以增加一个属性 theme="simple" 使得最后生成的最简单的风格的html,否则就会有一些奇奇怪怪的tr td
    • 或者直接在struts.xml中加一句 Servlet下载文件
    • 注: 如果要增加class,需要使用属性: cssClass

修改 list1.jsp

<s:select label="products"
          name="product.id"
          list="products"
          listKey="id"
          listValue="name"
          multiple="true"
          size="3"
          value="selectedProducts"
/>

一 Struts框架(下)

6 struts 使用ITERATOR 迭代遍历集合中的集合

创建Category.java

Category除了有id和name属性外,还有List属性
表示category和product是一对多关系

    public class Category {

        int id;
        String name;
        List<Product> products;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public List<Product> getProducts() {
            return products;
        }
        public void setProducts(List<Product> products) {
            this.products = products;
        }
    }

修改ProductAction.java

private List<Category> categories =new ArrayList();

public List<Category> getCategories() {
    return categories;
}

public void setCategories(List<Category> categories) {
    this.categories = categories;
}
public String list() {
    Category category1 =new Category();
    category1.setId(1);
    category1.setName("category1");

    Category category2 =new Category();
    category2.setId(2);
    category2.setName("category2");

    categories.add(category1);
    categories.add(category2);

    List<Product> products1=new ArrayList();
    Product p1 = new Product();
    p1.setId(1);
    p1.setName("product1");
    Product p2 = new Product();
    p2.setId(2);
    p2.setName("product2");
    Product p3 = new Product();
    p3.setId(3);
    p3.setName("product3");

    products1.add(p1);
    products1.add(p2);
    products1.add(p3);

    List<Product> products2=new ArrayList();
    Product p4 = new Product();
    p4.setId(4);
    p4.setName("product4");
    Product p5 = new Product();
    p5.setId(5);
    p5.setName("product5");
    Product p6 = new Product();
    p6.setId(6);
    p6.setName("product6");

    products2.add(p4);
    products2.add(p5);
    products2.add(p6);

    category1.setProducts(products1);
    category2.setProducts(products2);

    return "list2";

}

list2.jsp

遍历每一个category,接着把每个category下对应的products也遍历出来

    <%@ page language="java" contentType="text/html; charset=UTF-8"
             pageEncoding="UTF-8" isELIgnored="false"%>

    <%@ taglib prefix="s" uri="/struts-tags" %>

    <%@page isELIgnored="false"%>

    <table border="1" cellspacing="0">

        <tr>
            <td>id</td>
            <td>name</td>
            <td>products</td>
        </tr>

        <s:iterator value="categories" var="c">
            <tr>
                <td>${c.id}</td>
                <td>${c.name}</td>
                <td>
                    <s:iterator value="#c.products" var="p">
                        ${p.name}<br/>
                    </s:iterator>
                </td>
            </tr>
        </s:iterator>

    </table>

    <s:debug/>

一 Struts框架(下)

7 调试1

有上面的debug标签生成的调试页面是struts自带的调试工具
一 Struts框架(下)
一 Struts框架(下)

8 调试2

需要jar
一 Struts框架(下)

访问http://127.0.0.1:8080/config-browser/actionNames可以看到当前struts配置了哪些Action可以使用

一 Struts框架(下)

9 struts 使用使用通配符匹配

一 Struts框架(下)
修改struts.xml

  • *Product 表示所有以Product结尾的路径,都会匹配在这个Action上
    • method={1}表示第一个通配符
    • 如果访问的是addProduct就会调用add方法
    • 如果访问的是listProduct就会调用list方法
      以此类推
      一 Struts框架(下)

一 Struts框架(下)

10 struts 如何使用拦截器的例子

修改ProductAction.java

    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

修改list页面加入

${date}

取时间

创建拦截器

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
import com.tzy.struts.action.ProductAction;

import java.util.Date;

public class DateInterceptor extends AbstractInterceptor {

    @Override
    public String intercept(ActionInvocation invocation) throws Exception {
        //把拦截到的Action强制转换成 ProductAction,并设置当前时间(注入)
       ProductAction action = (ProductAction)invocation.getAction();
       action.setDate(new Date());
       return invocation.invoke();
    }
}

配置struts.xml
一 Struts框架(下)

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <package name="default" namespace="/" extends="struts-default">
        <interceptors>
            <interceptor name="dateInterceptor" class="com.tzy.struts.interceptor.DateInterceptor" />
        </interceptors>

        <action name="*Product" class="com.tzy.struts.action.ProductAction" method="{1}">
            <interceptor-ref name="dateInterceptor" />
            <interceptor-ref name="defaultStack" />
            <result name="show">show.jsp</result>
            <result name="list2">list2.jsp</result>
        </action>
    </package>
</struts>

一 Struts框架(下)

11 转发

Struts 默认跳转方法是内部跳转()
如何进行外部转发?从之前的例子中看出
一 Struts框架(下)

在相对应的返回值接收处添加属性
一 Struts框架(下)

一 Struts框架(下)

12 外部转发传参

修改ProductAction.java

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添加

   <action name="addPageProduct" class="com.tzy.struts.action.ProductAction" method="addPage">
        <result name="addPage" type="redirect">addproduct.jsp?name=${name}</result>
    </action>

一 Struts框架(下)

12 struts 表单验证

创建testvalidation.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<s:head/>
<body>
<s:form action="addProduct">
    <s:textfield name="product.name" label="product name" />
    <s:submit value="Submit" />
</s:form>
</body>
</html>

在ProductAction中增加validate()方法
注意: ProductAction类要继承 ActionSupport

public void validate(){
    if ( product.getName().length() == 0 ){
        addFieldError( "product.name", "name can't be empty" );
    }
} 

增加一个input 的result

    <action name="addProduct" class="com.tzy.struts.action.ProductAction" method="add">
        <result name="input">testvalidation.jsp</result>
        <result name="show">show.jsp</result>
    </action>

一 Struts框架(下)
什么都不传
一 Struts框架(下)

13 struts 表单验证常用方法是用xml配置

做上面例子的效果,删除validate方法

新建文件ProductAction-validation.xml
文件一定要放在和ProductAction相同的包下面
文件命名必须是{actionname}-validation.xml

<!DOCTYPE validators PUBLIC
        "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
        "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
<validators>
    <validator type="requiredstring">
        <param name="fieldName">product.name</param>
        <message>name is required.</message>
    </validator>
</validators>

14 struts 的ACTION是多实例的

在默认设置下,Action是多实例的,每次访问都会创建新的Action实例

在ProductAction的构造方法里打印this

public ProductAction(){
    System.out.println("product action instance: " + this);
}

重启tomcat,访问
http://127.0.0.1:8080/listProduct

一 Struts框架(下)

15 struts 使用注解方式进行配置实例

以上的教程都是基于XML进行配置的,除此之外,Struts还能够基于注解进行配置
添加ja包
一 Struts框架(下)

一 Struts框架(下)

然后就是在ProductAction类上面添加注解

    @Namespace("/")
    @ParentPackage("struts-default")
    @Results({@Result(name="show", location="/show.jsp"),
            @Result(name="home", location="/index.jsp")})

一 Struts框架(下)

  • 其他常用注解

    • Namespace:指定命名空间。
    • ParentPackage:指定父包。

    • Result:提供了Action结果的映射。(一个结果的映射)
    • Results:“Result”注解列表
    • ResultPath:指定结果页面的基路径。

    • Action:指定Action的访问URL。
    • Actions:“Action”注解列表。

    • ExceptionMapping:指定异常映射。(映射一个声明异常)
    • ExceptionMappings:一级声明异常的数组。

    • InterceptorRef:拦截器引用。
    • InterceptorRefs:拦截器引用组。

    一般说来,不是所有的注解都会用到,真正用到哪个的时候再来查一下就知道怎么回事了。

可以看出来,注解方式,就是把本来做在struts.xml里的事情,搬到了Action类里面来做。
那么到底应该用注解还是配置呢?从个人经验来讲,小项目适合用注解,大项目因为其复杂性,采用注解会导致配置信息难以维护和查询,更适合采用xml配置方式。