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