Struts2 基础学习
Struts2 get/set 自动获取/设置数据
ActionSuport类引入
1、Action设置数据
1 属性驱动(fieldDriven)
A.基本数据类型属性 name password
B.JavaBean类型属性 User Bean user.name user.password
2 模型驱动(ModelDriven)
只能接受一种类型
2、Struts2处理传入多个值
1、处理数目不定的字符串
String[] hobbys 唱歌 跳舞 ……
2、处理数目不定的JavaBean对象
List<Students>
3、struts.xml配置
package
name
namespace
abstract
extends
action
name
class
method
4、划分模块
struts.xml
<include file="cheliang.xml"></include>
<include file="zichan.xml"></include>
5、通配符
<action name="*_*" class="com.zhagener.action.{1}Action" method="{2}"> 注意:{1}Action 并且传入的Action名称必须是与Action类名完全相同
6、动态方法调用
官方不建议使用(不安全)
http://localhost:8180/struts2LoginDemo/Wildcard!list 【!】
7、Action的生命周期
1 每次请求一个实例
2 Spring管理一个实例
8、result配置
1 type默认是dispatcher内部转发
2 type为redirect重定向
3 type为chain链条
4 type为redirectAction重定向到Action
5 freemarker freemarker魔板
6 httpheader 返回一个已配置好的HTTP头信息响应
7 stream 将原始数据作为流传递回浏览器端
8 velocity 呈现Velocity魔板
9 xslt 该XML可以通过XSL魔板进行转换
10 plaintext 返回普通文本内容
9、result全局配置,如果再Action中没有配置error,则到<global-result>中查找对应error配置
<global-result>
<result name="error">error.jsp</result>
</global-result>
10、struts2 拦截器
1 拦截器可拔插(AOP的一种实现),从而实现了可重用性
2 struts2 预定义拦截器 & 拦截器栈
3 自定义拦截器简单示例
11、Struts2 值栈
值栈:是对应每个请求对象的一套内存数据的封装,Struts2会给每个请求创建一个新的值栈。值栈能够线程安全地为每个请求提供公共的数据存取服务。
12、Struts2 OGNL
OGNL是对象图导航语言(Object-Graph Navigation Language)的缩写。它是功能强大的表达式语言OGNL访问ValueStack数据
<s:property value="account"/>
OGNL访问ActionContext数据:
parameter 请求参数 request.getParameter(……)
request 请求作用域中的数据 request.getAttribute(……)
session 会话作用域中的数据 session.getAttribute(……)
application 应用程序作用域的数据 application.getAttribute(……)
attr 按照 page request session application顺序查找值
OGNL 访问复杂对象:
访问JavaBean对象 <s:property value="对象引用名.属性名"/>
访问集合对象 <s:property value="对象引用名[index].属性名"/>
访问Map对象 <s:property value="对象引用名['key'].属性名"/>
OGNL 访问静态方法和属性:
访问静态属性 <s:property value="@staticClass@staticAtrr"/>
访问静态方法<s:property value="@staticClass@staticMethod()"/> <constant name="struts.ognl.allowStaticMethodAccess" value="true"></constant>/
13、Struts2 标签
Struts2自己封装了一套标签,比JSTL强大,而且与Struts2中的其他功能无缝结合。当然Struts2标签的内容较多,随着版本的升级,标签和属性越来越多,核心标签根据功能分为:
数据标签:控制标签:界面标签:其他标签:Struts的标签比JSTL标签强大的同时,性能较JSTL要差。
Struts2 --数据标签:
property标签
default标签 指定默认值
escapeHtml标签 执行HTML
set标签:
<s:set var="i" value="1"></s:set>
<s:set var="a" value="'action范围的值'" scope="action"></s:set>
<s:set var="p" value="'page范围的值'" scope="page"></s:set>
<s:set var="r" value="'request范围的值'" scope="request"></s:set>
<s:set var="s" value="'session范围的值'" scope="session"></s:set>
<s:set var="a" value="'application范围的值'" scope="application"></s:set>
<s:property value="#i"/><br/>
<s:property value="#a"/><br/>
<s:property value="#attr.p"/><br/>
<s:property value="#request.r"/><br/>
<s:property value="#session.s"/><br/>
<s:property value="#application.a"/><br/>
bean标签:
<s:bean name="com.zhagener.entity.Student" var="student">
<s:param name="name" value="'zhansan'"></s:param>
<s:param name="age" value="20"></s:param>
</s:bean>
<s:property value="#student.name"/><br/>
<s:property value="#student.age"/><br/>
date标签:
1、必须先引入Date类所属包:
<%@ page import="java.lang.*" %>
2、定义个request的值
request.setAttribute("date",new Date());
3、使用<s:date/>标签:
${date}<br/>
当前时间:<s:date name="#request.date" format="yyyy-MM-dd-mm-ss"/>
debug标签:(多用于查看值栈信息,供调试使用)
<s:debug></s:debug>
URL&a标签:
<s:url action="hello" namespace="" id="h">
<s:param name="name" value="'strut2'"></s:param>
</s:url>
<s:a href="%{h}">超链接</s:a>
<br/>
<s:a action="hello" namespace="/foreground" >
<s:param name="name" value="'struts2'"></s:param>超链接2
</s:a>
include标签:<s:include value="/footer.jsp"></s:include>
Struts2 --控制标签:
ifelse标签:
request.setAttribute("age",20);
<s:if test="#request.age < 20 ">
年龄小于20岁
</s:if>
<s:elseif test="#request.age > 20">
年龄大于20岁
</s:elseif>
<s:else>
年龄等于20
</s:else>
iterator标签:
<%@ page import="com.zhagener.entity.Student" %>
<%
List<Student> students = new ArrayList<Student>();
students.add(new Student("zhangsan_1",1));
students.add(new Student("zhangsan_2",2));
students.add(new Student("zhangsan_3",3));
students.add(new Student("zhangsan_4",4));
students.add(new Student("zhangsan_5",5));
request.setAttribute("students",students);
%>
<table >
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<s:iterator value="#request.students" status="status">
<tr>
<td><s:property value="#status.index+1"/></td>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
</tr>
</s:iterator>
</table>
append标签:
<%@ page import="com.zhagener.entity.Student" %>
List<Student> students = new ArrayList<Student>();
students.add(new Student("zhangsan_1",1));
students.add(new Student("zhangsan_2",2));
students.add(new Student("zhangsan_3",3));
students.add(new Student("zhangsan_4",4));
students.add(new Student("zhangsan_5",5));
List<Student> students1 = new ArrayList<Student>();
students1.add(new Student("zhangsan_11",11));
students1.add(new Student("zhangsan_21",21));
students1.add(new Student("zhangsan_31",31));
students1.add(new Student("zhangsan_41",41));
students1.add(new Student("zhangsan_51",51));
request.setAttribute("students",students);
request.setAttribute("students1",students1);
<s:append var="students3">
<s:param value="#request.students"></s:param>
<s:param value="#request.students1"></s:param>
</s:append>
<table >
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<table>
<s:iterator value="students3" status="status">
<tr>
<td><s:property value="#status.index+1"/></td>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
</tr>
</s:iterator>
</table>
generator分隔标签:
<s:generator separator="," val="'张三,李四,王五,赵六'" var="nameList"></s:generator>
<s:iterator value="#nameList">
<s:property/>
</s:iterator>
merge组合标签:(与append相似,只不过不是顺序的)
<s:merge var="students3">
<s:param value="#request.students"></s:param>
<s:param value="#request.students1"></s:param>
</s:merge>
sort标签:
List<Student> students = new ArrayList<Student>();
students.add(new Student("zhangsan_1",1));
students.add(new Student("zhangsan_2",2));
students.add(new Student("zhangsan_3",3));
students.add(new Student("zhangsan_4",4));
students.add(new Student("zhangsan_5",5));
List<Student> students1 = new ArrayList<Student>();
students1.add(new Student("zhangsan_11",11));
students1.add(new Student("zhangsan_21",21));
students1.add(new Student("zhangsan_31",81));
students1.add(new Student("zhangsan_41",41));
students1.add(new Student("zhangsan_51",51));
request.setAttribute("students",students);
request.setAttribute("students1",students1);
<s:merge var="merge_students">
<s:param value="#request.students"></s:param>
<s:param value="#request.students1"></s:param>
</s:merge>
<s:bean id="studentComparator" name="com.zhagener.comparator.StudentComparator"/>
<s:sort comparator="#studentComparator" source="merge_students">
<s:debug></s:debug>
<table >
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<s:iterator status="status">
<tr>
<td><s:property value="#status.index+1"/></td>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
</tr>
</s:iterator>
</table>
</s:sort>
subset标签:
List<Student> students = new ArrayList<Student>();
students.add(new Student("zhangsan_1",1));
students.add(new Student("zhangsan_2",2));
students.add(new Student("zhangsan_3",3));
students.add(new Student("zhangsan_4",4));
students.add(new Student("zhangsan_5",5));
List<Student> students1 = new ArrayList<Student>();
students1.add(new Student("zhangsan_11",11));
students1.add(new Student("zhangsan_21",21));
students1.add(new Student("zhangsan_31",81));
students1.add(new Student("zhangsan_41",41));
students1.add(new Student("zhangsan_51",51));
request.setAttribute("students",students);
request.setAttribute("students1",students1);
<s:merge var="merge_students">
<s:param value="#request.students"></s:param>
<s:param value="#request.students1"></s:param>
</s:merge>
<table>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<s:subset source="merge" count="3" start="0">
<s:iterator status="status">
<tr>
<td><s:property value="#status.index+1"/></td>
<td><s:property value="name"/></td>
<td><s:property value="age"/></td>
</tr>
</s:iterator>
</s:subset>
</table>
Struts2 --页面标签:
Form标签:表单标签
<s:form>
<s:textfield name="name" label="用户名:"></s:textfield><br/>
<s:password name="password" label="密码:"></s:password><br/>
<s:textarea name="des" label="备注:"></s:textarea><br/>
<s:submit value="Login on"></s:submit><br/>
<s:radio list="#{0:'男',1:'女'}" label="性别:" name="sex" value="0"></s:radio>
<s:checkboxlist list="#{0:'唱歌',1:'跳舞',2:'极限运动',3:'健身',4:'摄影'}" name="hobbies" value="{0,1,2,3,4}"></s:checkboxlist>
<s:select list="#{0:'唱歌',1:'跳舞',2:'极限运动',3:'健身',4:'摄影'}" name="select" value="{0,1,2}" multiple="true"></s:select>
</s:form>
Text标签:文本标签
<s:textfield name="name" label="用户名:"></s:textfield><br/>
<s:password name="password" label="密码:"></s:password><br/>
<s:textarea name="des" label="备注:"></s:textarea><br/>
Radios标签:单选框标签
<s:radio list="#{0:'男',1:'女'}" label="性别:" name="sex" value="0"></s:radio>
CheckBoxList标签:复选框标签
<s:checkboxlist list="#{0:'唱歌',1:'跳舞',2:'极限运动',3:'健身',4:'摄影'}" name="hobbies" value="{0,1,2,3,4}"></s:checkboxlist>
select标签:下拉框标签<s:select list="#{0:'唱歌',1:'跳舞',2:'极限运动',3:'健身',4:'摄影'}" name="select" value="{0,1,2}" multiple="true"></s:select>
Struts2 --其他标签:
updownselect标签:
<s:updownselect
list="#{0:'游戏',1:'唱歌',2:'跳舞'}"
name="hobbies"
headerKey="-1"
headerValue="请选择"
emptyOption="true"
allowMoveUp="true"
allowMoveDown="true"
allowSelectAll="true"
moveUpLabel="Move Up"
moveDownLabel="Move Down"
selectAllLabel="Select All"
/>
optiontransferselect标签:
<s:optiontransferselect label="选择你喜欢图书"
name="cnbook"
leftTitle="中文图书"
list="{'struts2权威指南','轻量级javaeye 企业应用空实战','ajax讲义'}"
doubleName="enBook"
rightTitle="外文图书"
doubleList="{'JavaScrip:The definitive Guide','export one-to-one'}"
multiple="true"
addToLeftLabel="向左移动"
addToRightLabel="向右移动"
addAllToRightLabel="全部右移"
addAllToLeftLabel="全部左移"
allowSelectAll="true"
headerKey="cnKey"
headerValue="选择图书"
emptyOption="true"
doubleHeaderKey="enKey"
doubleHeaderValue="选择外文图书"
doubleMultiple="true"
doubleEmptyOption="true"
leftDownLabel="向下移动"
rightDownLabel="向下移动"
leftUpLabel="向上移动"
rightUpLabel="向上移动" />
Struts2 --fn标签:
14、struts2国际化(Internationalization):
编码转换工具:http://tool.chinaz.com/Tools/Unicode.aspx
<constant name="struts.custom.i18n.resources" value="resource" />
resource_en_US.properties
resource_zh_CN.properties
resource.properties
userName=\u7528\u6237\u540d
password=\u5bc6\u7801
login=\u767b\u5f55
welcome=\u6b22\u8fce\u0020{0}
15、Struts2 内置验证:
普通字段验证:
验证表达式:
<s:actionerror/>
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"> <validators> <field name="user.userName"> <field-validator type="requiredstring"> <message>请输入用户名</message> </field-validator> <field-validator type="stringlength"> <param name="minLength">6</param> <param name="maxLength">10</param> <message>用户名必须在${minLength}和${maxLength}之间</message> </field-validator> </field> <field name="user.name"> <field-validator type="requiredstring"> <message>请输入姓名</message> </field-validator> </field> <field name="user.age"> <field-validator type="int"> <param name="min">18</param> <param name="max">120</param> <message>年龄必须满${min}岁</message> </field-validator> </field> <field name="user.email"> <field-validator type="email"> <message>邮件格式不正确</message> </field-validator> </field> <field name="user.homePage"> <field-validator type="url"> <message>主页格式不对</message> </field-validator> </field> <validator type="expression"> <param name="expression"><![CDATA[!user.name.equals(user.userName)]]></param> <message>用户名和真实姓名不能相同</message> </validator> </validators>
16、Struts2 内置验证:
1、添加自定义标签,并保存至项目根目录下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator Config 1.0//EN" "http://struts.apache.org/dtds/xwork-validator-config-1.0.dtd"> <validators> <validator name="required" class="com.opensymphony.xwork2.validator.validators.RequiredFieldValidator"/> <validator name="requiredstring" class="com.opensymphony.xwork2.validator.validators.RequiredStringValidator"/> <validator name="int" class="com.opensymphony.xwork2.validator.validators.IntRangeFieldValidator"/> <validator name="double" class="com.opensymphony.xwork2.validator.validators.DoubleRangeFieldValidator"/> <validator name="date" class="com.opensymphony.xwork2.validator.validators.DateRangeFieldValidator"/> <validator name="expression" class="com.opensymphony.xwork2.validator.validators.ExpressionValidator"/> <validator name="fieldexpression" class="com.opensymphony.xwork2.validator.validators.FieldExpressionValidator"/> <validator name="email" class="com.opensymphony.xwork2.validator.validators.EmailValidator"/> <validator name="url" class="com.opensymphony.xwork2.validator.validators.URLValidator"/> <validator name="visitor" class="com.opensymphony.xwork2.validator.validators.VisitorFieldValidator"/> <validator name="conversion" class="com.opensymphony.xwork2.validator.validators.ConversionErrorFieldValidator"/> <validator name="stringlength" class="com.opensymphony.xwork2.validator.validators.StringLengthFieldValidator"/> <validator name="regex" class="com.opensymphony.xwork2.validator.validators.RegexFieldValidator"/> <validator name="conditionalvisitor" class="com.opensymphony.xwork2.validator.validators.ConditionalVisitorFieldValidator"/> <validator name="sensitive" class="com.java1234.validators.SensitiveWordValidators"/> </validators>
2、定义自定义验证标签处理类:
package com.java1234.validators; import com.opensymphony.xwork2.validator.ValidationException; import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; public class SensitiveWordValidators extends FieldValidatorSupport{ @Override public void validate(Object object) throws ValidationException { String fieldName=this.getFieldName(); String value=this.getFieldValue(fieldName, object).toString(); if(!check(value)){ this.addFieldError(fieldName, object); } } public boolean check(String value){ String sensitiveWords[]={"操","你妈"}; for(int i=0;i<sensitiveWords.length;i++){ if(value.indexOf(sensitiveWords[i])>-1){ return false; } } return true; } }
3、使用自定义验证标签:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"> <validators> <field name="name"> <field-validator type="requiredstring"> <message>请输入姓名</message> </field-validator> <field-validator type="sensitive"> <message>有敏感词汇</message> </field-validator> </field> /validators>
17、Struts2 文件上传和下载:
struts2文件上传基于struts2拦截器实现的;
struts2文件上传使用的是fileupload组件;
Form配置 enctype="multipart/form-data";
struts2获取上传文件:name(name是文件表单的name);
struts2获取上传文件名:name+FileName;
struts2获取上传文件的类型:name+ContentType;
<constant name="struts.multipart.maxSize" value="20000000"></constant>
文件下载:
返回的是文件流;
<param name="contentDisposition">attachment;filename=${fileName}</param>
package com.zhagener.action; import java.io.File; import org.apache.commons.io.FileUtils; import com.opensymphony.xwork2.ActionSupport; public class FileUploadAction extends ActionSupport { // private File java1234;// file // private String java1234FileName;// file name // private String java1234ContentType;// file type private File[] java1234s;// file private String[] java1234sFileName;// file name private String[] java1234sContentType;// file type public File[] getJava1234s() { return java1234s; } public void setJava1234s(File[] java1234s) { this.java1234s = java1234s; } public String[] getJava1234sFileName() { return java1234sFileName; } public void setJava1234sFileName(String[] java1234sFileName) { this.java1234sFileName = java1234sFileName; } public String[] getJava1234sContentType() { return java1234sContentType; } public void setJava1234sContentType(String[] java1234sContentType) { this.java1234sContentType = java1234sContentType; } @Override public String execute() throws Exception { for (int i = 0; i < java1234s.length; i++) { System.out.println("File Name: " + java1234sFileName[i]); System.out.println("File Type: " + java1234sContentType[i]); File saveFile = new File("c:/" + java1234sFileName[i]); FileUtils.copyFile(java1234s[i], saveFile); } return "success"; } }
package com.zhagener.action; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import com.opensymphony.xwork2.ActionSupport; public class FileDownloadAction extends ActionSupport { private String fileName ; public String getFileName() throws Exception{ String fileName = new String(this.fileName.getBytes(),"ISO8859-1"); return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public InputStream getInputStream() throws FileNotFoundException { File file = new File("c:/美女1号.jpg"); this.fileName = "美女1号"; FileInputStream fs = new FileInputStream(file); return fs; } }
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts> <constant name="struts.multipart.maxSize" value="20000000"></constant> <package name="manager" extends="struts-default" namespace="/"> <action name="fileupload" class="com.zhagener.action.FileUploadAction"> <result name="success">/success.jsp</result> <result name="input">/index.jsp</result> <!-- <interceptor-ref name="fileUpload">--> <!-- <param name="allowedTypes">image/bmp,image/x-png,image/gif,image/jpg,image/jpeg,image/pjpeg</param>--> <!-- <param name="maximumSize">81101</param>--> <!-- </interceptor-ref>--> <interceptor-ref name="defaultStack"></interceptor-ref> </action> <action name="filedownload" class="com.zhagener.action.FileDownloadAction"> <result type="stream"> <param name="contentDisposition">attachment;filename=${fileName}</param> </result> </action> <action name="student" method="add" class="com.zhagener.action.StudentAction"> <result name="success">/success.jsp</result> <result name="input">/error.jsp</result> <!-- <interceptor-ref name="token"></interceptor-ref>--> <!-- <interceptor-ref name="defaultStack"></interceptor-ref>--> <!-- <result name="invalid.token">/index.jsp</result>--> <result name="tokenSession">/index.jsp</result> <interceptor-ref name="defaultStack"></interceptor-ref> </action> </package> </struts>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags"%> <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <s:fielderror></s:fielderror> <form action="fileupload" method="post" enctype="multipart/form-data"> 文件1: <input type="file" name="java1234s" /> <br /> 文件2: <input type="file" name="java1234s" /> <br /> 文件3: <input type="file" name="java1234s" /> <br /> <input type="submit" value="提交" /> </form> <a href="filedownload">文件下载</a> <br /> <s:actionerror/> <form action="student" method="post"> <s:token></s:token> 姓名: <input type="text" name="student.name" /> <br /> 年龄: <input type="text" name="student.age" /> <br /> <input type="submit" value="提交" /> </form> </body> </html>
18、Struts2 防止重复提交:
<action name="student" method="add" class="com.zhagener.action.StudentAction">
<result name="success">/success.jsp</result>
<result name="input">/error.jsp</result>
<!-- <interceptor-ref name="token"></interceptor-ref>-->
<!-- <interceptor-ref name="defaultStack"></interceptor-ref>-->
<!-- <result name="invalid.token">/index.jsp</result>-->
<result name="tokenSession">/index.jsp</result>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
package com.zhagener.action; import com.opensymphony.xwork2.ActionSupport; import com.zhagener.entity.Student; public class StudentAction extends ActionSupport { private Student student; @Override public String execute() throws Exception { return "success"; } public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public String add() { System.out.println("开始添加学生:" + student); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } return SUCCESS; } }