result元素
- 作用:为动作指定结果视图
- 属性name:逻辑视图的名称,对应着动作方法的返回值。默认值是success。
- type:结果类型,指的就是用什么方式转到定义的页面。默认是dispatcher。
- 常用type:dispatcher、redirect、redirectAction、chain
- dispatcher(默认值):使用请求转发,转向一个页面。
- redirect:使用重定向,转向一个页面。
- redirectAction:重定向到另一个动作。分为相同名称空间的动作和不同名称空间的动作。
- 相同名称空间的动作配置如下:
<result name="success" type="redirectAction">action2</result>
<result name="success" type="redirectAction">
<param name="namespace">/n2</param>
<param name="actionName">action2</param>
</result>
- chain:使用请求转发到另一个动作。分为相同名称空间和不同名称空间的动作。
- 相同名称空间的动作配置如下:
<result name="success" type="chain">action2</result>
<result name="success" type="chain">
<param name="namespace">/n2</param>
<param name="actionName">action2</param>
</result>
自定义拦截器
<package name="pack" extends="struts-default">
<interceptors>
<interceptor name="checkLoginInterceptor" class="interceptor.CheckLoginInterceptor" />
<interceptor-stack name="myDefaultStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="checkLoginInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<default-interceptor-ref name="myDefaultStack"></default-interceptor-ref>
<global-results>
<result name="input">/login.jsp</result>
</global-results>
<action name="login" class="action.DemoAction" method="login">
<interceptor-ref name="myDefaultStack">
<param name="checkLoginInterceptor.excludeMethods">login</param>
</interceptor-ref>
<result type="redirectAction">showMain</result>
</action>
<action name="showMain" class="action.DemoAction" >
<result>/main.jsp</result>
</action>
<action name="showOther" class="action.DemoAction" >
<result>/otherpage.jsp</result>
</action>
</package>
package interceptor
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;
public class CheckLoginInterceptor extends MethodFilterInterceptor {
public String doIntercept(ActionInvocation invocation) throws Exception {
HttpSession session = ServletActionContext.getRequest().getSession();
Object obj = session.getAttribute("user");
if(obj == null){
return "input";
}
String rtValue = invocation.invoke();
return rtValue;
}
}
文件上传
<constant name="struts.multipart.maxSize" value="5242880"></constant>
<package name="p1" extends="struts-default">
<action name="upload" class="action.UploadAction" method="upload">
<interceptor-ref name="defaultStack">
<param name="fileUpload.allowedTypes">image/jpg,image/pjpeg,image/png</param>
</interceptor-ref>
<result name="input">/upload.jsp</result>
</action>
</package>
package action;
import java.io.File;
import javax.servlet.ServletContext;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class UploadAction extends ActionSupport {
private String username;
private File photo;
private String photoFileName;
private String photoContentType;
public String upload(){
ServletContext application = ServletActionContext.getServletContext();
String filePath = application.getRealPath("/WEB-INF/uploadFiles");
File file = new File(filePath);
if(!file.exists()){
file.mkdirs();
}
photo.renameTo(new File(file,photoFileName));
return null;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public File getPhoto() {
return photo;
}
public void setPhoto(File photo) {
this.photo = photo;
}
public String getPhotoFileName() {
return photoFileName;
}
public void setPhotoFileName(String photoFileName) {
this.photoFileName = photoFileName;
}
public String getPhotoContentType() {
return photoContentType;
}
public void setPhotoContentType(String photoContentType) {
this.photoContentType = photoContentType;
}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>struts2中的文件上传</title>
</head>
<body>
<%--文件上传的必要前提:
1.请求方式必须是post
2.enctype属性的取值必须是multipart/form-data
3.提供一个文件选择域
--%>
<%-- 注意这里在jsp页面中使用的都是struts标签来代替html标签。
s:actionerror是用来回显动作类中的错误信息 --%>
<s:actionerror/>
<s:form action="upload.action" enctype="multipart/form-data">
<s:textfield name="username" label="用户名" />
<s:file name="photo" label="照片" />
<s:submit value="上传"/>
</s:form>
</body>
</html>
文件下载
<action name="download" class="action.DownloadAction" method="download">
<result name="success" type="stream">
<param name="contentType">application/octet-stream</param>
<param name="contentDisposition">attachment;filename=${@java.net.URLEncoder@encode(filename,"UTF-8")}</param>
<param name="inputName">inputStream</param>
</result>
</action>
package action;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownloadAction extends ActionSupport {
private InputStream inputStream;
private String filename;
public String download()throws Exception{
String filePath = ServletActionContext.getServletContext().getRealPath("/WEB-INF/files/5.jpg");
inputStream = new FileInputStream(filePath);
filename="照片.jpg";
return SUCCESS;
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
}
ActionContext存取数据
<action name="action1" class="action.Demo1Action">
<result>/demo1.jsp</result>
</action>
package action;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import org.apache.struts2.ServletActionContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import java.util.Map;
public class Demo1Action extends ActionSupport {
public String execute() {
ActionContext context = ActionContext.getContext();
context.put("contextMap", "hello contextMap");
Map<String, Object> sessionAttribute = context.getSession();
sessionAttribute.put("sessionMap", "hello sessionMap");
HttpSession session = ServletActionContext.getRequest().getSession();
session.setAttribute("sessionMap1", "hello sessionMap1");
Map<String, Object> applicationAttribute = context.getApplication();
applicationAttribute.put("applicationMap", "hello applicationMap");
ServletContext application = ServletActionContext.getServletContext();
application.setAttribute("applicationMap1", "hello applicationMap1");
return SUCCESS;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>取ActionContext数据</title>
</head>
<body>
<%--使用s:property来获取ActionContext中的数据。
value属性的取值是一个OGNL表达式。--%>
<br/>---------获取大Map中的数据-------------<br/>
<%--获取大Map中的数据,在取的时候是#key名称--%>
<s:property value="#contextMap"/>
<br/>---------获取小Map中的数据-------------<br/>
<%--获取大Map中小Map的数据 ,使用#大Map的key.小Map的key--%>
<s:property value="#session.sessionMap"/><br/>
<s:property value="#session.sessionMap1"/><br/>
<s:property value="#application.applicationMap"/><br/>
<s:property value="#application.applicationMap1"/>
<s:debug/>
</body>
</html>
---------获取大Map中的数据-------------
hello contextMap
---------获取小Map中的数据-------------
hello sessionMap
hello sessionMap1
hello applicationMap
hello applicationMap1
ValueStack存取数据
<action name="action2" class="action.Demo2Action">
<result>/demo2.jsp</result>
</action>
package action;
import domain.Student;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.util.ValueStack;
public class Demo2Action extends ActionSupport {
private String name = "泰斯特2";
public String execute() {
ActionContext context = ActionContext.getContext();
ValueStack vs = context.getValueStack();
vs.push(new Student("泰斯特", 21));
vs.setValue("#name", "张三");
vs.setValue("name", "李四");
vs.set("s1", new Student("王五", 18));
vs.push(new Student("test", 23));
vs.set("s2", new Student("aaa", 28));
vs.set("s3", new Student("bbb", 30));
return SUCCESS;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page import="com.opensymphony.xwork2.util.ValueStack" %>
<%@ page import="com.opensymphony.xwork2.ActionContext" %>
<html>
<head>
<title>取ValueStack中的数据</title>
</head>
<body>
<%--使用s:property标签,获取ValueStack中的元素。
value属性的取值是一个OGNL表达式。它只能获取元素中的属性。
注意:
取ValueStack中的对象属性时,不使用#。
它是从栈顶逐个对象查找指定的属性名称。只要找到了,就不再继续查找。
--%>
<s:property value="name"/><br/>
<%-- 获取ValueStack中指定位置的属性: --%>
0-name <s:property value="[0].name" /><br/>
1-name <s:property value="[1].name" /><br/>
2-name <s:property value="[2].name" /><br/>
3-name <s:property value="[3].name" /><br/>
4-name <s:property value="[4].name" /><br/>
<%--取HashMap中的元素 --%>
<s:property value="s3.name" /><br/>
<%--当s:property什么都不写:
默认取栈顶元素
--%>
<s:property />
<%//模拟原理:其实全是ValueStack的findValue和findString
ValueStack vs = ActionContext.getContext().getValueStack();
Object obj = vs.findValue("[2].name");
out.print("<br/>-------------------------<br/>");
out.print(obj);
%>
<s:debug/>
</body>
</html>
test
0-name test
1-name test
2-name 李四
3-name 李四
4-name 泰斯特2
bbb
{s3=domain.Student@7676f25f, com.opensymphony.xwork2.util.OgnlValueStack.MAP_IDENTIFIER_KEY=, s2=domain.Student@2643cfa8}
-------------------------
李四
struts2对EL表达式的改变
- 在jsp页面中,我们会使用EL表达式来获取域中的对象,正常的查找顺序是:
page Scope————>request Scope————>sessionScope————>application Scope
- 经过struts2对request的getAttribute方法进行重写,查找的顺序变成了:
page Scope————>request Scope————>valueStack————>contextMap————>sessionScope————>application Scope
iterator标签的使用
<action name="action4" class="action.Demo4Action" method="findAll">
<result>/demo4.jsp</result>
</action>
package action;
import java.util.ArrayList;
import java.util.List;
import domain.Student;
import com.opensymphony.xwork2.ActionSupport;
public class Demo4Action extends ActionSupport {
private List<Student> students;
public String findAll() {
students = new ArrayList<Student>();
students.add(new Student("张三", 23));
students.add(new Student("李四", 24));
students.add(new Student("王五", 21));
return SUCCESS;
}
public List<Student> getStudents() {
return students;
}
public void setStudents(List<Student> students) {
this.students = students;
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>s:iterator的使用</title>
</head>
<body>
<table width="500px" border="1" align="center">
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<%--s:iterator:struts2的迭代标签
属性详解:
begin,end,step和jstl的forEach标签是一样的
value属性:要遍历的集合,是OGNL表达式。
var属性:取值就是一个字符串
如果写了该属性:把var的值作为key,把当前遍历的元素作为value。存到ActionContext这个大Map中
如果不写该属性:把当前遍历的元素压入栈顶
status属性:遍历时的一些计数信息。
int getIndex() 从0开始
int getCount() 从1开始
boolean isFirst()
boolean isLast()
boolean isOdd()
boolean isEven()
--%>
<s:iterator value="students" var="s" status="vs" >
<tr>
<td><s:property value="#vs.index"/></td>
<td><s:property value="#s.name" /></td>
<td><s:property value="#s.age" /></td>
</tr>
</s:iterator>
</table>
<hr/>
<table width="500px" border="1" align="center">
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
</tr>
<s:iterator value="students" status="vs">
<tr>
<td><s:property value="#vs.count"/></td>
<td><s:property value="name" /></td>
<td><s:property value="age" /></td>
</tr>
</s:iterator>
</table>
<s:debug/>
</body>
</html>
struts2其他一些标签
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>struts2中的一些其他标签的使用</title>
</head>
<body>
<br/>-------s:set------------<br/>
<%--s:set标签
value属性:取值是一个OGNL表达式
var属性:是一个普通的字符串
它是把value属性的值作为value,把var属性的值作为key,把存到ActionContext大map中。
--%>
<s:set value="'test'" var="str1"/>
<br/>-------s:if s:ifelse s:else------------<br/>
<%-- 条件判断的标签--%>
<s:set value="'C'" var="grade"/>
<s:if test="#grade=='D'">差</s:if>
<s:elseif test="#grade=='C'">中</s:elseif>
<s:else>其他</s:else>
<br/>-------s:url------------<br/>
<%--s:url标签:
value属性:是把值直接输出到页面上
action属性:是把动作的请求地址输出到页面上 ${pageContext.request.contextPath}/action1
var属性:把action的取值作为value,把var的取值作为key,放到ActionContext中
注意:它会自动根据struts配置,来转换后缀名。
--%>
<s:url value="action1"/>
<s:url action="action1" var="url" >
<%--把name作为key,把value作为值,绑定到请求连接地址后面。相当于get方式拼接请求参数
注意:
name的取值就是一个普通的字符串
value的取值是一个OGNL表达式,要想转成字符串请使用''
--%>
<s:param name="name" value="'张三'"></s:param>
</s:url>
<br/>
<a href="<s:property value='#url' />" >点击 s:url</a>
<s:debug/>
</body>
</html>
struts2中的符号使用
#
- 取ActionContext中key时使用,例如<s:property value="#name" />
- OGNL中创建Map对象时使用,例如:<s:radio list="#{‘male’:‘男’,‘female’:‘女’}" />
$
- 在JSP中使用EL表达式时使用,例如${name}
- 在xml配置文件中,编写OGNL表达式时使用,例如文件下载时,文件名编码。struts.xml——>${@java.net.URLEncoder@encode(filename,“UTF-8”)}
%
- 在struts2中,有些标签的value属性取值就是一个OGNL表达式,例如<s:property value=“OGNL Expression” />
- 还有一部分标签,value属性的取值就是普通字符串,例如<s:textfield value=“username”/>,如果想把一个普通的字符串强制看成时OGNL,就需要使用%{}把字符串套起来。例如<s:textfield value="%{username}"/>。
struts2表单提交案例
<action name="saveCustomer" class="action.Demo7Action" method="save"/>
package action;
import domain.Customer;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
public class Demo7Action extends ActionSupport implements ModelDriven<Customer> {
private Customer customer = new Customer();
public Customer getModel() {
return customer;
}
public String save(){
System.out.println(customer);
return null;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
package domain;
import java.io.Serializable;
public class Customer implements Serializable{
private String name;
private String password;
private boolean married;
private String hobby;
private String city;
private String description;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isMarried() {
return married;
}
public void setMarried(boolean married) {
this.married = married;
}
public String getHobby() {
return hobby;
}
public void setHobby(String hobby) {
this.hobby = hobby;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Customer [name=" + name + ", password=" + password
+ ", married=" + married + ", hobby=" + hobby + ", city="
+ city + ", description=" + description + ", gender=" + gender
+ "]";
}
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>一个表单的小例子</title>
</head>
<body>
<s:form action="saveCustomer">
<s:textfield name="name" label="用户名" />
<s:password name="password" label="密码" />
<s:checkbox name="married" label="已婚" value="true" />
<s:checkboxlist name="hobby" list="{'摄影','旅行','足球'}" label="爱好" />
<s:select name="city" label="故乡" list="#{'BJ':'北京','SH':'上海','SZ':'苏州'}" headerKey="" headerValue="---请选择---"/>
<s:textarea name="description" label="个人介绍" rows="5" cols="25" />
<s:radio name="gender" list="#{'male':'男','female':'女'}" label="性别" value="'male'" /><%--value是一个OGNL表达式 --%>
<s:submit value="提交" /><s:reset value="重置" />
</s:form>
<s:debug/>
</body>
</html>