Struts2框架进阶(二)

Struts2标签库

Struts2标签库提供了主题,模板支持,极大的简化了视图页面的编写,提供了代码的复用性。

Struts2标签库的标签不依赖于任何表现层技术,可以在JSP、Velocity和FreeMarker等模板技术中使用。

Struts2标签分类

用户界面标签 主要用来生成HTML元素的标签
非用户界面标签 主要用于数据访问、逻辑控制
AJAX标签 用于支持AJAX效果




本篇实例基于此系列的第一篇文章Struts2框架入门(一)

要使用Struts标签,需添加以下taglib指令

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

form标签(表单标签)

修改addProduct.jsp

<%@ taglib prefix="s" uri="/struts-tags" %>
 
<html>
 
<body>
 
<s:form action="addProduct">
 
  <s:textfield name="product.name" label="product name" />
  <s:submit value="Submit" />
 
</s:form>
 
</body>
</html>

iterator标签(迭代器标签)

修改ProductAction类

添加products属性和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

添加 listProduct路径

  <action name="listProduct" class="controller.ProductAction" method="list">
    <result name="list">list.jsp</result>
  </action>

创建list.jsp

使用s:iterator标签进行遍历

value(集合)

var(遍历出来的元素)

st(元素状态)

index(当前行号,基于0)

count(当前行号,基于1)

first(是否第一个元素)

last(是否最后一个元素)

odd(是否奇数)

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>

check标签(多选标签)

修改ProductAction类

添加ListselectedProducts属性,修改list方法

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

    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 "list";
  
    }

修改list.jsp

使用s:checkboxlist标签多选

value(被选中)

name(提交到的名称)

list(遍历的集合)

listValue(显示的数据)

listKey(值对应键)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<%@ taglib prefix="s" uri="/struts-tags"%>
 
<%@page isELIgnored="false"%>
 
<s:checkboxlist value="selectedProducts" name="product.id"
    list="products" listValue="name" listKey="id" />

radio标签(单选标签)

修改list.jsp

使用s:radio标签单选

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
 
<%@ taglib prefix="s" uri="/struts-tags"%>
 
<%@page isELIgnored="false"%>
 
<s:radio name="product.id" value="2" list="products" listValue="name"
    listKey="id" />

select标签(列表选择标签)

修改list.jsp

使用s:select标签进行列表选择

multiple:true(可以选择多行)

size(显示行数)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" isELIgnored="false"%>
  
<%@ taglib prefix="s" uri="/struts-tags"%>
  
<%@page isELIgnored="false"%>
  
<s:select label="products"
       name="product.id"
       list="products"
       listKey="id"
       listValue="name"
       multiple="true"
       size="3"
       value="selectedProducts"
/>

Struts2通配符

以上例子中每增加一个路径都需要添加一个action配置(本例中的add,show,list),而有些路径都是由同一个Action类控制逻辑,通配符可以将这些路径都归结为一个action。

修改struts.xml

*Product(表示所有以Product结尾的路径,都会匹配这个Action)

method={1} (表示第一个通配符,也就是*所省略的字符)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
 
<struts>
   
  <package name="basicstruts" extends="struts-default">

     <!--Struts2.5加强了安全验证,还需加上这句 -->
     <global-allowed-methods>regex:.*</global-allowed-methods>
  
  <action name="*Product" class="controller.ProductAction" method="{1}">
    <result name="show">show.jsp</result>
    <result name="list">list.jsp</result>
  </action>    
 
</package>
 
</struts>

Struts2拦截器

拦截器可以拦截指定的Action,进行相应的操作,Struts2也是基于拦截器实现的。

本例将实现自制拦截器,拦截ProductAction,注入当前时间。

修改ProductAction类

添加Date属性

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

修改list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
 pageEncoding="UTF-8" isELIgnored="false"%>
 
<%@ taglib prefix="s" uri="/struts-tags" %>
 
<%@page isELIgnored="false"%>
 
${date}

创建DateInterceptor类(拦截器类)

把拦截到Action强制转换成ProductAction,注入当前时间

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

声明拦截器,对ProductAction使用拦截器。因为使用自制的拦截器,默认的就失效了,所以还需加上defaultStack

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
 
<struts>
   
  <package name="basicstruts" extends="struts-default">

     <!--Struts2.5加强了安全验证,还需加上这句 -->
     <global-allowed-methods>regex:.*</global-allowed-methods>

        <interceptors>
            <interceptor name="dateInterceptor" class="interceptor.DateInterceptor" />
        </interceptors>
  
  <action name="*Product" class="controller.ProductAction" method="{1}">
            <interceptor-ref name="dateInterceptor" />
            <interceptor-ref name="defaultStack" />
    <result name="show">show.jsp</result>
    <result name="list">list.jsp</result>
  </action>    
 
</package>
 
</struts>

Struts2表单验证

Struts2的表单验证有两种方式:编码校验和XML校验

以下例子中,如果输入的name为空,会给出提示

编码校验

修改ProductAction类

验证功能需要继承ActionSupport类并覆写validate方法

public class ProductAction extends ActionSupport{
    private Product product;
     
    public String show(){
        product = new Product();
        product.setName("mi5");
        return "show";
    }
    public String add(){
        return "show";
    }
     
    public void validate(){
        if ( product.getName().length() == 0 ){ 
            addFieldError( "product.name", "name can't be empty" );
        }
    }   
     
    public Product getProduct() {
        return product;
    }
    public void setProduct(Product product) {
        this.product = product;
    }
}

修改struts.xml

校验没有通过默认会返回input字符

  <action name="addProduct" class="controller.ProductAction" method="add">
    <result name="input">addProduct.jsp</result>
    <result name="show">show.jsp</result>
  </action> 

修改show.jsp

添加提示

<%@ taglib prefix="s" uri="/struts-tags" %>
 
<html>
 
<s:head/>
 
<body>

<div style="color:red"><s:fielderror/></div>
 
<s:form action="addProduct">
 
  <s:textfield name="product.name" label="product name" />
  <s:submit value="Submit" />
 
</s:form>
 
</body>
</html>

XML校验

在ProductAction类同包下新建ProductAction-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>

Struts2注解

以上例子都是以XML方式配置路径,其实Struts2还支持以注解方式

常用注解

Namespace 指定命名空间
ParentPackage 指定父包
Result 提供了Action结果的映射
Results “Result”注解列表

ResultPath

指定结果页面的基路径
Action 指定Action的访问URL
Actions “Action”注解列表
ExceptionMapping 指定异常映射
ExceptionMapping 声明异常数组
InterceptorRel 拦截器引用
InterceptorRefs 拦截器引用组

在pom.xml添加注解依赖

<!-- https://mvnrepository.com/artifact/org.apache.struts/struts2-convention-plugin -->
<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-convention-plugin</artifactId>
    <version>2.5.16</version>
</dependency>

修改struts.xml

注释配置信息

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
  
<struts>
  <package name="basicstruts" extends="struts-default">
  
<!--   <action name="showProduct" class="controller.ProductAction" method="show"> -->
<!--     <result name="show">show.jsp</result> -->
<!--   </action>     -->
  
</package>
  
</struts>

修改ProductAction类

注:使用注解Action类所在包必须以.action结尾

@Namespace("/")	//表示访问路径
@ParentPackage("struts-default")	//与配置文件中的struts-default相同,表示使用默认的一套拦截器
@Results({ @Result(name = "show", location = "/show.jsp"), @Result(name = "list", location = "list.jsp") })	//预先定义多个results, "show" 返回"/show.jsp"
public class AnnotationTest extends ActionSupport {

	private Product product;

	@Action("showProduct")	//当访问路径是showProduct的时候,就会调用show方法 
	public String show() {
		product = new Product();
		product.setName("小米5");

		return "show";
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

}

猜你喜欢

转载自blog.csdn.net/the_programlife/article/details/80650585
今日推荐