1.标签概述和OGNL说明
Java领域的MVC框架:
主要实现控制器。
提供了大量的标签库,可以简化View的开发。
pageContext | 可以获取JSP九大内置对象,相当于使用该对象调用getxxx()方法,例如pageContext.getRequest()可以写为${pageContext.request) |
---|---|
pageScope | 获取pageContext域属性,相当于pageContext.getAttribute(“xxx”) |
requestScope | 获取request域属性,相当于request.getAttribute(“xxx”) |
sessionScope | 获取session域属性,相当于session.getAttribute(“xxx”) |
applicationScope | 获取application域属性,相当于application.getAttribute(“xxx”) |
param | 对应参数,它是一个Map,其中key是参数,value是参数值,适用于单值的参数,相当于request.getParameter(“xxx”) |
paramValues | 对应参数,她是一个Map,其中key是参数,value是多个参数值,适用于多值的参数,相当于request.getParameterValues(“xxx”) |
header | 对应请求头,它是一个Map,其中key表示头名称,value是单个头值,适用于单值的请求头,相当于request.getHeader(“xxx”) |
headerValues | 对应请求头,它是一个Map,其中key表示头名称,value是多个头值,适用于多值的请求头,相当于request.getHeaders(“xxx”) |
cookie | 用于获取cookie,Map集合中key是cookie的name,value是cookie对象,例如${cookie.JSESSIONID.value }就是获取sessionId, |
initParem | 获取web.xml中内的参数,${ initParam.xxx},xxx就是标签内的值,进而得到中的值 |
OGML表达式语言(数据访问语言)
既然要访问数据,必须要有个东西装数据,OGML的装数据的东西叫“Stack Context(OGNL Context)”,可以理解它相当于一个Map。
1、它里面的每个对象,都应该有个名字,根据名字来访问。
#对象名
假如OGNL Context中有3个对象:foo、bar、test
#bar.abc – 访问bar对象的getAbc()返回值。
#test.xyz.abc.def – 访问test对象的getXyz().getAbc().getDef()。
2、OGNL Context中有个根(root)对象。如果我们要访问根(root)对象的属性,可以省略对象名。
假如OGNL Context中有3个对象:foo、bar、test,但bar是根对象。
abc.xyz.def – 访问bar. getXyz().getAbc().getDef()。
3、OGNL可以直接创建List对象:{ele1, ele2, ele3, …}
4、OGNL可以直接创建Map对象:#{key1:value1, key2:value2, key3:value3, …}
5、OGNL可以直接获取“子集合”
person.cats.{? #this.age > 2} – 获取person所养的猫中age大于2的所有猫。
person.cats.{^ #this.age > 2} – 获取person所养的猫中age大于2的第一只猫。
person.cats.{$ #this.age > 2} – 获取person所养的猫中age大于2的最后一只猫。
6、OGNL还支持直接调用静态成员。需要将struts.ognl.allowStaticMethodAccess常量设置为true。
类名@静态Field
类名@静态方法(参数值)
2.控制标签
Stack Context(OGNL Context / Context Map / Action Context)
ValueStack(根对象)
Stack Context中包含了ValueStack(根对象)
if/else if/else:模拟流程控制的分支
/controlTag/WebContent/WEB-INF/content/s_if.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:if标签</title>
</head>
<body>
<!-- scope属性默认是action,意味着将该值放入Stack Context中 -->
<s:set var="MyAge" value="22"/>
<s:debug/>
<s:if test=" #MyAge > 60 ">
老年
</s:if>
<s:elseif test=" #MyAge > 40 ">
中年
</s:elseif>
<s:elseif test=" #MyAge > 20 ">
青年
</s:elseif>
<s:else>
少年
</s:else>
</body>
</html>
运行项目http://localhost:8080/controlTag/s_if
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/94fd0a4416873da141c9015a1ee4f4dc.jpeg)
iterator:模拟流程控制的迭代
/controlTag/WebContent/WEB-INF/content/s_iterator.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:iterator标签</title>
</head>
<body>
<ul>
<s:iterator value='{"123","456","789","987","654","321"}' var="name">
<li>${name}</li>
</s:iterator>
</ul>
<ul>
<s:iterator value='{"123","456","789","987","654","321"}' var="name" begin="2" end="4" status="st">
<li <s:if test="#st.odd">style="background-color:red"</s:if>>${name}</li>
</s:iterator>
</ul>
<table width="400" border="1">
<s:iterator value='#{"book1":20,"book2":30,"book3":40,"book4":50}' var="entry">
<tr>
<td>${entry.key}</td>
<td>${entry.value}</td>
</tr>
</s:iterator>
</table>
</body>
</html>
运行项目http://localhost:8080/controlTag/s_iterator
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/b9a9ba0e2f2c8b257eb1ad7fec0b13e5.jpeg)
append/merge:把两个或两个以上的集合合并成新集合
/controlTag/WebContent/WEB-INF/content/s_append.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:append标签</title>
</head>
<body>
<s:append var="newList">
<s:param value="{'123','456','789'}" />
<s:param value="{'987','654','321'}" />
</s:append>
<ul>
<s:iterator value="#newList" var="myItem">
<li>${myItem}</li>
</s:iterator>
</ul>
</body>
</html>
/controlTag/WebContent/WEB-INF/content/s_merge.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:merge标签</title>
</head>
<body>
<s:merge var="newList">
<s:param value="{'123','456','789'}" />
<s:param value="{'987','654','321'}" />
</s:merge>
<ul>
<s:iterator value="#newList" var="myItem">
<li>${myItem}</li>
</s:iterator>
</ul>
</body>
</html>
运行项目
http://localhost:8080/controlTag/s_append
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/0941d4f397863c58b3479f71318d2e89.jpeg)
http://localhost:8080/controlTag/s_merge
![这里写图片描述](https://i-blog.csdnimg.cn/blog_migrate/77a2871b14d98ded68ca3c0e87a360af.jpeg)
generator:被某种规则把字符串分割成一个集合
/controlTag/WebContent/WEB-INF/content/s_generator.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:generator标签</title>
</head>
<body>
<s:generator val="'123:456:789:987:654:321'" separator=":" var="newList">
</s:generator>
<ul>
<s:iterator value="#newList" var="myItem">
<li>${myItem}</li>
</s:iterator>
</ul>
</body>
</html>
运行项目http://localhost:8080/controlTag/s_generator
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/9321089f9f142293f37072fba2a9930b.jpeg)
subset:截取子集合
/controlTag/WebContent/WEB-INF/content/s_subset.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:subset标签</title>
</head>
<body>
<s:subset var="newList"
source="{'a','b','c','d','e' }"
start="2"
count="2"/>
<!-- 因为subset的返回值放到了page context中,所以需要attr.访问 -->
<s:iterator value="#attr.newList" var="myItem">
<li>${myItem}</li>
</s:iterator>
</body>
</html>
运行项目http://localhost:8080/controlTag/s_subset
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/b9b1f5ad9b21c5d348298b2f3e9dc2b8.jpeg)
sort:对集合元素排序,需要指定一个Comparator类
/controlTag/WebContent/WEB-INF/content/s_sort.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:sort标签</title>
</head>
<body>
<s:bean var="nc" name="Struts2.util.NameComparator"/>
<s:sort var="newList"
source="{'aaaa','bbb','cc','ddddd','e' }"
comparator="nc"
/>
<ul>
<s:iterator value="#attr.newList" var="myItem">
<li>${myItem}</li>
</s:iterator>
</ul>
</body>
</html>
/controlTag/src/Struts2/util/NameComparator.java
程序代码如下:
package Struts2.util;
import java.util.Comparator;
public class NameComparator implements Comparator<Object> {
//如果返回值大于0,表明o1>o2
//如果返回值等于0,表明o1==o2
//如果返回值小于0,表明o1<o2
@Override
public int compare(Object o1, Object o2) {
return o1.toString().length() > o2.toString().length() ? 1 :
o1.toString().length() < o2.toString().length() ? -1 : 0;
}
}
运行项目/controlTag/WebContent/WEB-INF/content/s_sort.jsp
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/e01eb82a65dffd006730d23cb5542f2a.jpeg)
3.数据标签
已经使用过的一些数据标签
set | 设置变量值。var指定变量名字,value指定变量值,scope指定范围。 |
---|---|
bean | 创建一个Bean对象,var指定对象的名(放在Stack Context中),name指定类。 |
debug | 帮助调试。观察ValueStack以及Stack Context中的数据。 |
i18n | 为指定页面加载国际化资源文件,name指定国际化资源包的baseName。 |
text | 输出国际化消息。也通过name指定国际化消息的key。 |
property | 输出指定表达式值。通过value属性来指定表达式。 如果指定了value属性,就输出value属性对应的表达式的值。 如果没有指定value属性,就输出ValueStack栈顶的值。 |
include | 用户包含指定的JSP页面。 |
param | 用于设置参数。 |
action:可以直接在页面上调用指定Action
/dataTag/src/Struts2/action/ListUserAction.java
程序代码如下:
package Struts2.action;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.Action;
public class ListUserAction implements Action {
private List<String> users;
public List<String> getUsers() {
return users;
}
public void setUsers(List<String> users) {
this.users = users;
}
@Override
public String execute() throws Exception {
System.out.println("ListUserAction被调用");
users = new ArrayList<String>();
users.add("123");
users.add("456");
users.add("789");
return SUCCESS;
}
}
/dataTag/src/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">
<!-- START SNIPPET: xworkSample -->
<struts>
<package name="default" namespace="/" extends="struts-default">
<action name="listUser" class="Struts2.action.ListUserAction">
<result>/WEB-INF/content/listUser.jsp</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
<!-- END SNIPPET: xworkSample -->
/dataTag/WebContent/WEB-INF/content/listUser.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>列出所有用户</title>
</head>
<body>
<ul>
<s:iterator value="users">
<li><s:property/></li>
</s:iterator>
</ul>
</body>
</html>
运行项目http://localhost:8080/dataTag/listUser
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/d1a617dcebf9fcf659734f20c01eab13.jpeg)
/dataTag/WebContent/WEB-INF/content/s_action1.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:action1</title>
</head>
<body>
<!-- executeResult="true"将调用Action处理之后的视图页面完全包含到当前页中 -->
<s:action name="listUser" executeResult="true"/>
</body>
</html>
运行项目http://localhost:8080/dataTag/s_action1
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/03cace2bb8e62531a6d9aea1f50a329b.jpeg)
/dataTag/WebContent/WEB-INF/content/s_action2.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:action2</title>
</head>
<body>
<!-- ignoreContextParams="true"将指定当前页面的请求参数不会传入被调用的Action中 -->
<s:action name="listUser" ignoreContextParams="true"/>
</body>
</html>
运行项目http://localhost:8080/dataTag/s_action2
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/366da9ae876284469222a63075792bc2.jpeg)
/dataTag/WebContent/WEB-INF/content/s_action3.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:action3</title>
</head>
<body>
<!-- 只指定var属性,将被调用Action放入Stack Context -->
<s:action var="listUserAction" name="listUser"/>
<s:property value="#listUserAction.users"/>
</body>
</html>
运行项目http://localhost:8080/dataTag/s_action3
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/83e14e7221c783cffd44135b7ad579a4.jpeg)
date:对日期进行格式化输出
name:指定要格式化输出的日期。
format:指定格式化字符串。
/dataTag/WebContent/WEB-INF/content/s_date.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:date表单</title>
</head>
<body>
<s:bean var="now" name="java.util.Date"/>
<s:property value="#now"/><br>
<!-- 指定format属性对日期进行格式化 -->
<s:date name="#now" format="yyyy年MM月dd日"/><br>
<!-- nice="true"输出该日期与当前日期之间的时间差 -->
<%
java.util.Date ago = new java.util.Date();
ago.setDate(1);
request.setAttribute("ago", ago);
%>
<s:date name="#request.ago" nice="true"/><br>
</body>
</html>
运行项目http://localhost:8080/dataTag/s_date
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/9d4f5339cda43ce44848a4d66b79d516.jpeg)
push:把表达式的值,放入ValueStack的栈顶
/dataTag/WebContent/WEB-INF/content/s_push.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>s:push</title>
</head>
<body>
<!-- 只指定var属性,将被调用Action放入Stack Context -->
<s:action var="listUserAction" name="listUser"/>
<s:property value="#listUserAction.users[0]"/>
<s:property value="#listUserAction.users[1]"/>
<s:property value="#listUserAction.users[2]"/>
<hr>
<s:push value="#listUserAction">
<!-- 直接获取栈顶元素,因此性能更好 -->
<s:property value="users[0]"/>
<s:property value="users[1]"/>
<s:property value="users[2]"/>
</s:push>
</body>
</html>
运行项目http://localhost:8080/dataTag/s_push
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/1c136c2e6433ae2f61e5e65c00933ace.jpeg)
4.主题与模板
当我们在页面上使用s:textfield标签时,它生成两列布局,并提供了label标签。因为Struts2为所有标签都提供了一个模板。每个标签所表现出来的效果,由它对应的模板来决定。如果为所有的标签都提供了模板,这系列的模板就组成了主题。
simple:没有额外的附加行为的主题,只生成最核心的HTML元素,其他附加的东西(比如两列布局,label全部都没有)。
xhtml:默认主题。
1、两列布局。
2、生成label
3、输出错误提示
4、客户端校验支持
css_xhtml:就是在xhtml增加了一些css样式。
/formTag/WebContent/WEB-INF/content/s_theme.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>简单表单</title>
</head>
<body>
<s:form action="" >
<s:textfield name="name" label="用户名"/>
<s:password name="pass" label="密码"/>
<s:checkbox name="married" label="婚否"/>
<tr>
<td colspan="2" align="right">
<s:submit value="提交"/>
<s:reset value="重置" />
</td>
<tr>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_theme
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/6f9712b5de403c24bb1e67f9fd9cc36c.jpeg)
直接通过struts.ui.theme来设置默认的主题
/formTag/src/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">
<!-- START SNIPPET: xworkSample -->
<struts>
<constant name="devMode" value="true"></constant>
<constant name="struts.ui.theme" value="simple"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
<!-- END SNIPPET: xworkSample -->
/formTag/WebContent/WEB-INF/content/s_theme1.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>简单表单</title>
</head>
<body>
<s:form action="" >
<s:textfield name="name" label="用户名"/>
<s:password name="pass" label="密码"/>
<s:checkbox name="married" label="婚否"/>
<tr>
<td colspan="2" align="right">
<s:submit value="提交"/>
<s:reset value="重置" />
</td>
<tr>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_theme1
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/201a3a6066b55f67d1e4820f899b265d.jpeg)
通过page\request\application范围内的theme来设置主题
为标签设置theme属性,子标签默认使用父标签theme属性所设置的主题
/formTag/WebContent/WEB-INF/content/s_theme2.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>简单表单</title>
</head>
<body>
<s:form action="" theme="simple">
<s:textfield name="name" label="用户名"/>
<s:password name="pass" label="密码"/>
<s:checkbox name="married" label="婚否"/>
<tr>
<td colspan="2" align="right">
<s:submit value="提交" />
<s:reset value="重置" />
</td>
<tr>
</s:form>
---------------------------------------------
<s:form action="" theme="xhtml">
<s:textfield name="name" label="用户名"/>
<s:password name="pass" label="密码"/>
<s:checkbox name="married" label="婚否"/>
<tr>
<td colspan="2" align="right">
<s:submit value="提交" />
<s:reset value="重置" />
</td>
<tr>
</s:form>
---------------------------------------------
<s:form action="" theme="css_xhtml">
<s:textfield name="name" label="用户名"/>
<s:password name="pass" label="密码"/>
<s:checkbox name="married" label="婚否"/>
<tr>
<td colspan="2" align="right">
<s:submit value="提交" />
<s:reset value="重置" />
</td>
<tr>
</s:form>
</body>
</html>
/formTag/WebContent/WEB-INF/content/s_theme3.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>简单表单</title>
</head>
<body>
<s:form action="" theme="xhtml">
<s:textfield name="name" label="用户名"/>
<s:password name="pass" label="密码"/>
<s:checkbox name="married" label="婚否"/>
<tr>
<td colspan="2" align="right">
<s:submit value="提交" theme="simple"/>
<s:reset value="重置" theme="simple"/>
</td>
<tr>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_theme2
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/2303fc27e3eb627e5a73031985ffd367.jpeg)
运行项目http://localhost:8080/formTag/s_theme3
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/d7d4fa355734973182fe404616250e2f.jpeg)
5.表单标签
这些UI标签都可指定cssClass、cssStyle来指定CSS样式,还可以指定大量的onXxx属性,用于绑定JavaScript函数。
简单的一些表单标签
checkbox | 生成一个复选框。 |
---|---|
head | 引入一些辅助的CSS样式和JS脚本。 |
file | 生成一个文件上传域。 |
form | 生成一个form表单 |
hidden | 生成一个隐藏域。 |
label | 生成一个标签。 |
password | 生成一个密码输入框 |
reset | 重置按钮。 |
submi | 提交按钮。 |
textarea | 多行文本框。 |
textfile | 单行文本域。 |
checkboxlist / radio / select / optgroup:复选框列表/单选框/下拉框/创建选项组
/formTag/src/Struts2/action/ListXuelisAction.java
程序代码如下:
package Struts2.action;
import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.Action;
import Struts2.domain.Xueli;
public class ListXuelisAction implements Action {
private List<Xueli> xuelis;
public List<Xueli> getXuelis() {
return xuelis;
}
public void setXuelis(List<Xueli> xuelis) {
this.xuelis = xuelis;
}
@Override
public String execute() throws Exception {
xuelis = new ArrayList<>();
xuelis.add(new Xueli(1,"大专","基本要求"));
xuelis.add(new Xueli(2,"本科","挺好"));
xuelis.add(new Xueli(3,"硕士","高级人才"));
xuelis.add(new Xueli(4,"博士","稀有人才"));
xuelis.add(new Xueli(5,"烈士","顶尖人才"));
return null;
}
}
/formTag/src/Struts2/domain/Xueli.java
程序代码如下:
package Struts2.domain;
public class Xueli {
private Integer id;
private String name;
private String desc;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Xueli(Integer id, String name, String desc) {
super();
this.id = id;
this.name = name;
this.desc = desc;
}
public Xueli() {}
}
/formTag/src/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">
<!-- START SNIPPET: xworkSample -->
<struts>
<constant name="devMode" value="true"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="listXuelis" class="Struts2.action.ListXuelisAction"></action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
<!-- END SNIPPET: xworkSample -->
/formTag/WebContent/WEB-INF/content/s_select.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>表单</title>
</head>
<body>
<s:action name="listXuelis" var="listXuelis"/>
<s:form action="">
<s:select label="选择学历"
name="a"
list="#listXuelis.xuelis"
listKey="id"
listValue="name"/>
<s:select label="选择学历"
name="a"
list="#listXuelis.xuelis"
listKey="id"
listValue="desc"/>
<s:radio label="选择学历"
name="b"
list="#listXuelis.xuelis"
listKey="id"
listValue="name"/>
<s:checkboxlist label="选择学历"
name="c"
list="#listXuelis.xuelis"
listKey="id"
listValue="name"/>
<s:select label="选择学历"
name="a"
list="#listXuelis.xuelis"
listKey="id"
listValue="name">
<s:optgroup label="再次选择"
list="#listXuelis.xuelis"
listKey="id"
listValue="name"/>
</s:select>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_select
![运行效果](https://i-blog.csdnimg.cn/blog_migrate/cacb927943c42743c35e38e1c4ed5a8f.jpeg)
combobox:生成一个文本框与列表框的组合
/formTag/WebContent/WEB-INF/content/s_combobox.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<s:form>
<s:combobox
label="请选择"
name="number"
list="{'123' , '456' ,'789'}" />
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_combobox
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/9e0f70d6c302545859128545ada29159.jpeg)
updownselect:一个增强版的select
/formTag/WebContent/WEB-INF/content/s_updownselect.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>表单</title>
</head>
<body>
<s:action name="listXuelis" var="listXuelis"/>
<s:form action="">
<s:updownselect
label="选择学历"
cssStyle="width:120px"
name="a"
moveDownLabel="下移"
list="#listXuelis.xuelis"
listKey="id"
listValue="name"/>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_updownselect
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/b3bf955c3f8796fbbf0f1a679868c08c.jpeg)
optiontransferselect:两个updownselect的组合
/formTag/WebContent/WEB-INF/content/s_optiontransferselect.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>表单</title>
</head>
<body>
<s:action name="listXuelis" var="listXuelis"/>
<s:form action="">
<s:optiontransferselect label="选择学历"
name="a"
list="#listXuelis.xuelis"
listKey="id"
listValue="name"
addAllToRightLabel="全部右移"
addAllToLeftLabel="全部左移"
doubleList="{'abc','bcd','cde'}"
doubleName="b"/>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_optiontransferselect
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/a534d8388462143008a7cd52de352c22.jpeg)
doubleselect:两个列表框组合,有级联效果
/formTag/WebContent/WEB-INF/content/s_doubleselect.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>表单</title>
</head>
<body>
<s:set var="renwus"
value="#{ '西游记':{'孙悟空','猪八戒','唐僧'},
'水浒传':{'林冲','武松','鲁智深'},
'三国演义':{'刘备','关羽','张飞'},
'红楼梦':{'贾宝玉','薛宝钗','林黛玉'}
}"/>
<!-- 使用s:doubleselect 标签时,它所在form标签的action属性必须有一个值,该值可以任意一个值 -->
<s:form action="a">
<s:doubleselect
name="book1"
list="{'西游记','水浒传'}"
doubleList="top == '西游记' ? {'孙悟空','猪八戒','唐僧'} : {'林冲','武松'} "
doubleName="renwu1"
label="请选择"/>
<s:doubleselect
name="book2"
list="#renwus.keySet()"
doubleList="#renwus.get(top)"
doubleName="renwu2"
label="请选择"/>
</s:form>
</body>
</html>
运行项目http://localhost:8080/formTag/s_doubleselect
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/1203ec2c5b8ce21e0020ae48c90b5483.jpeg)
token:防刷新(看下章节)
6.使用token标签控制防刷新
token:防刷新。
默认情况下,如果没有进行防刷新控制,每次刷新都会添加一条完全相同的记录。
(1)需要在表单页面上增加<s:token/>
标签。
(2)在action配置中增加一个token拦截器,检测用户是否刷新了页面。当它检测用户刷新页面时,系统会返回一个invalid.token的逻辑视图。
(3)还需要为invalid.token的逻辑视图配置一个物理视图资源。
/token/src/Struts2/action/AddUserAction.java
程序代码如下:
package Struts2.action;
import com.opensymphony.xwork2.ActionSupport;
import Struts2.domain.User;
import Struts2.service.UserService;
public class AddUserAction extends ActionSupport {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String execute(){
UserService us = new UserService();
//调用业务逻辑组件来添加用户
Integer id = us.addUser(user);
if(id>0){
return SUCCESS;
}
return ERROR;
}
}
/token/src/Struts2/action/ListUsersAction.java
程序代码如下:
package Struts2.action;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;
import Struts2.domain.User;
import Struts2.service.UserService;
public class ListUsersAction extends ActionSupport {
private List<User> users;
public List<User> getUsers() {
return users;
}
public void setUsers(List<User> users) {
this.users = users;
}
@Override
public String execute(){
UserService us = new UserService();
setUsers(us.getAllUsers());
return SUCCESS;
}
}
/token/src/Struts2/domain/User.java
程序代码如下:
package Struts2.domain;
public class User {
private Integer id;
private String name;
private String pass;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
/token/src/Struts2/service/UserService.java
程序代码如下:
package Struts2.service;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import Struts2.domain.User;
public class UserService {
static List<User> userdb = new ArrayList<>();
public Integer addUser(User user) {
user.setId(new Random().nextInt(99999));
userdb.add(user);
return user.getId();
}
public List<User> getAllUsers() {
return userdb;
}
}
/token/WebContent/WEB-INF/content/addUser.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>添加用户</title>
</head>
<body>
<!-- 此处就是一个简单的表单页 -->
<s:form action="addUserPro">
<s:textfield name="user.name" label="用户名"/>
<s:textfield name="user.pass" label="密码"/>
<!-- s:token就是用来做防刷新 -->
<s:token/>
<s:submit value="添加"/>
</s:form>
</body>
</html>
/token/WebContent/WEB-INF/content/listUsers.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>列出系统中所有用户</title>
</head>
<body>
<table width="400" border="1">
<s:iterator value="users" var="u">
<tr>
<td>${u.id}</td>
<td>${u.name}</td>
<td>${u.pass}</td>
</tr>
</s:iterator>
</table>
</body>
</html>
/token/WebContent/WEB-INF/content/noref.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>请不要刷新</title>
</head>
<body>
<h2>数据已经提交,请不要刷新</h2>
</body>
</html>
/token/src/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">
<!-- START SNIPPET: xworkSample -->
<struts>
<constant name="devMode" value="true"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="addUserPro" class="Struts2.action.AddUserAction">
<!-- 该拦截器会检测用户的刷新,当Struts2检测到用户刷新页面时,
Struts2会返回一个invalid.token的逻辑视图名 -->
<interceptor-ref name="token"/>
<!-- 下面是Struts2默认的拦截器 -->
<interceptor-ref name="defaultStack"/>
<result type="chain">listUsers</result>
<result name="invalid.token">/WEB-INF/content/noref.jsp</result>
</action>
<action name="listUsers" class="Struts2.action.ListUsersAction">
<result>/WEB-INF/content/listUsers.jsp</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
<!-- END SNIPPET: xworkSample -->
运行项目http://localhost:8080/token/addUser
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/c9e9584d7fd0a63788630da92f76c61d.jpeg)
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/22e968c7cd77ec72b4c5ff28dd8490c2.jpeg)
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/48a35c12f66a5c478fd06d0197fe0c11.jpeg)
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/1f3e3365bbefdc4fdb0e4af47e2436ad.jpeg)
7.非表单标签
actionerror/actionmessage:他们体现的是Struts2的消息机制。
当我们需要把Action中的一段文本传入下个页面显示时,就可借助Struts2的消息机制。
(1)Action中可通过addActionError()或addActionMessage()来添加消息。
(2)接下来就可以在下一个页面中使用<s:actionerror/>
或者<s:actionmessage/>
输出消息。
fielderror:输出类型转换失败、输入校验失败后的错误提示。
/actionMessages/src/Struts2/action/LoginProAction.java
程序代码如下:
package Struts2.action;
import com.opensymphony.xwork2.ActionSupport;
public class LoginProAction extends ActionSupport {
private String name;
private String pass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
@Override
public String execute()
{
if(name.equals("123") && pass.equals("456"))
{
addActionMessage("恭喜你!" + name + "登录成功");
return SUCCESS;
}
addActionError("用户名或者密码不正确,登录失败!");
return ERROR;
}
}
/actionMessages/src/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">
<!-- START SNIPPET: xworkSample -->
<struts>
<constant name="devMode" value="true"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="loginPro" class="Struts2.action.LoginProAction">
<result>/WEB-INF/content/welcome.jsp</result>
<result name="error">/WEB-INF/content/loginForm.jsp</result>
</action>
<action name="*">
<result>/WEB-INF/content/{1}.jsp</result>
</action>
</package>
</struts>
<!-- END SNIPPET: xworkSample -->
/actionMessages/WebContent/WEB-INF/content/loginForm.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录系统</title>
<s:head/>
</head>
<body>
<s:actionerror/>
<s:form action="loginPro">
<s:textfield name="name" label="用户名"/>
<s:textfield name="pass" label="密码"/>
<s:submit value="登录"/>
</s:form>
</body>
</html>
/actionMessages/WebContent/WEB-INF/content/welcome.jsp
程序代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>登录成功</title>
<s:head/>
</head>
<body>
<s:actionmessage/>
</body>
</html>
运行项目http://localhost:8080/actionMessages/loginForm
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/fd852124000ff8776ffd446db351868d.jpeg)
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/f06c2a39912a8371110af94b3c089ae8.jpeg)
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/1b99a91e1ec7c0a30a4fe426d80df47f.jpeg)
![运行项目](https://i-blog.csdnimg.cn/blog_migrate/8280979d8d0599e8c32e2aa385314792.jpeg)