struts2
定义:
struts2是基于mvC设计模式的web应用框架,它的本质相当于一个servlet,在MVC设计模式中,Struts2作为控制器(controller)来建立模型与视图的数据交互,说白了Struts2就是对web项目中不同页面之间跳转到的控制器。但是该控制器架设在MVC智商,比MVC框架更有先天的技术优势和模型实现优势。是一个web开发的组件,通常spring,hibernate,mybatis等框架整合使用。在整个web项目中扮演者页面跳转控制器的角色。
servlet劣势?
1、如果有很多功能,你需要写很多个servlet,当然可以用反射简化但还是比较麻烦
2、servlet需要得到页面传递过来的数据,request.getParamter("")方法获取,如果获取得值很多就要写很多request.getParamter("")
搭建struts2环境
1、导包13个核心jar包:
2、web.xml中配置过滤器
Struts2的核心控制器默认拦截以下请求
- .action为后缀的请求
- 没有任何后缀的请求
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>struts2Day1_01</display-name>
<!-- 配置过滤器 -->
<filter>
<filter-name>Struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
在filter节点下,我们设置filter对应的类,这里是固定的。在filter-mapping节点里,设置url-pattern的值为/*,代表全局生效,所有请求生效,也就是说,每个http请求都会由struts2来进行处理。
3、定义一个java类 action,用于处理请求,方法返回值类型String
action创建方式:
1、实现Action接口,可以直接使用Action提供的常量,必须重写默认处理方法execute()。
2、继承ActionSupport类,推荐使用。
3、直接定义一个普通类【可以从struts-default.xml文件最后位置可以看到】
<default-class-ref class="com. opensymphony.xwork2.ActionSupport" />
已经默认帮你继承ActionSupport类了。
我们在使用servlet的时候,每次访问servlet,服务器都会执行servlet方法,在struts2中,我们把每一次请求叫做action,当用户访问action的时候,默认执行的方法为execute,因此,我们新建一个类,如下:
package action;
import com.opensymphony.xwork2.Action;
public class LoginAction implements Action{
private String userName;
private String passWord;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String execute() throws Exception {
System.out.println("用户名:"+this.getUserName());
System.out.println("密码:"+this.getPassWord());
return "success";
}
}
4、在src下配置struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 一定要继承struts-default.xml -->
<package name="default" namespace="/" extends="struts-default" method="execute">
<action name="login" class="action.LoginAction">
<result name="success">/loginSuccess.jsp</result>
<!-- <result name="success">/fail.jap</result> -->
</action>
</package>
</struts>
1.package节点:表示一个包,一个包里面可以包含多个action,一个程序里面也可以有很多个包,我们让它继承struts-default.xml。
- name:包的名称。必须配置
- namespace:表示命名空间,namespace的值为“/”,表示我们在访问action的时候,直接通过“IP/action名称的方式来访问”,比如:http://localhost:8081/struts2Day1_01/login.action,如果我们给namespace的值定义为user在访问的时候需要:http://localhost:8081/struts2Day1_01/user/login.action 这样访问。
2.action节点:name属性来标识你提交表单的名称,对应一个class类。
3.result节点:代表处理结果,name属性代表action类中方法处理完毕后返回的字符结果,根据返回字符结果做出相应处理,如上返回success字符串(默认转发)转发到loginSuccess.jsp。
result的Type属性实现跳转
<action name="login" class="action.LoginAction">
<result name="success">/loginSuccess.jsp</result>
<result name="fail" type="redirect">/fail.jsp</result>
</action>
1、dispatcher:默认值,转发
2、redirect:重定向
3、chain:转发到action,一般不用,缓存问题
4、redirectAction:重定向到Action
global-results全局变量:
如果多个action返回结果一样并且去的页面一样,其实可以配置全局变量。
<package name="user" namespace="/user" extends="struts-default" >
<action name="login" class="action.LoginAction" method="login">
<result name="success">/login.jsp</result>
</action>
<action name="register" class="action.LoginAction" method="register">
<result name="success">/register.jsp</result>
</action>
<!-- 配置全局变量 -->
<global-results>
<result name="error">/hello.jsp</result>
</global-results>
</package>
分模块开发:
在项目开发中,一般多人开发,为了不让大家都去配置同一各strut.xml文件,一般都是分模块开发,这 样就不会乱套。把每个人需要做的模块功能写成独立的配置文件。
strut.xml文件:
<struts>
<!-- 不指定路径的话,默认在src下使用 -->
<include file="struts-shop.xml"></include>
<!-- 在src下action包 -->
<include file="action/struts-shop.xml"></include>
</struts>
Action访问方式:
1、传统访问
使用action标签里面的method属性,在这个属性里面配执行的action方法,如果不写就是默认执行execute()方法
<!-- struts.xml -->
<package name="user" namespace="/user" extends="struts-default">
<action name="login" class="action.LoginAction" method="login">
<result name="success">/login.jsp</result>
<result name="fail" type="redirect">/fail.jsp</result>
</action>
<action name="register" class="action.LoginAction" method="register">
<result name="success">/register.jsp</result>
<result name="fail" type="redirect">/fail.jsp</result>
</action>
</package>
<!-- index.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 action="/user/login" method="post">
<input type="submit" value="去登录" />
</s:form>
<s:form action="/user/register" method="post">
<input type="submit" value="去注册" />
</s:form>
</body>
</html>
2、动态调用访问
<!-- struts.xml -->
<!-- 设置常量为允许动态方法调用 -->
<constant name="struts.enable.DynamicMethodInvocation" value="true" />
<package name="user" namespace="/user" extends="struts-default">
<!-- /user/userFacillity!register.action 调用action.LoginAction下的 register方法-->
<action name="userFacillity" class="action.LoginAction" >
<result name="dologin">/login.jsp</result>
<result name="doregister">/register.jsp</result>
</action>
</package>
<!-- index.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>
<!--package节点的namespace + action节点的name + !方法名( )-->
<s:form action="/user/userFacillity!login" method="post">
<input type="submit" value="去登录" />
</s:form>
<s:form action="/user/userFacillity!register" method="post">
<input type="submit" value="去注册" />
</s:form>
</body>
</html>
3、通配符调用访问
<!-- struts.xml -->
<package name="user" namespace="/user" extends="struts-default">
<!--
addUser.action deleteUser.action都会请求*User.action
{1}代表第一个*号
-->
<action name="*User" class="action.LoginAction" method="{1}" >
<result name="doadd">/{1}_User.jsp</result>
<result name="dodelete">/{1}_User.jsp</result>
</action>
</package>
<!-- index.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 action="/user/addUser" method="post">
<input type="submit" value="去增加">
</s:form>
<s:form action="/user/deleteUser" method="post">
<input type="submit" value="去删除">
</s:form>
</body>
</body>
</html>
OGNL:
web阶段用EL表达式在jsp页面中来获取对域对象里面的值,struts2提供了OGNL标签,比EL表达式功能更强大
OGNL(object Graph Navigation Language),对象图导航语言,它是一种强大的表达式语言,通过它可以非常方便的来操作对象属性。
开源项目,不是strus2自带的,但是通常和struts2框架结合使用,用于取代页面的java脚本,简化数据访问和EL表达式都属于表达式语言。
OGNL在struts2中做两件事:
1、表达式语言:
将表单或struts2标签与特定的java数据绑定起来,用来将数据移入、移出框架。
2、类型自动转换
数据进入和流出框架,页面输入的字符串数据和java数据和java数据类型之间可以实现自动转换。
获取表单数据:
1、属性获取
LoginAction.java
package action;
import com.opensymphony.xwork2.Action;
import entity.User;
public class LoginAction implements Action{
private String username;
private String password;
private String address;
private String message;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String execute() throws Exception {
System.out.println("username:"+username);
System.out.println("password:"+password);
System.out.println("address:"+address);
System.out.println("message:"+message);
return "success";
}
}
index.jsp
<form action="login.action">
用户名:<input type="text" name="username"><br/>
密码:<input type="text" name="password"><br/>
地址:<input type="text" name="address"><br/>
普通消息:<input type="text" name="message"><br/>
<input type="submit" value="提交">
</form>
success.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:property value="username"/><br/>
<s:property value="password"/><br/>
<s:property value="address"/><br/>
</body>
</html>
2、对象获取
LoginAction.java
package action;
import com.opensymphony.xwork2.Action;
import entity.User;
public class LoginAction implements Action{
//封装对象
private User user;
//封装属性
private String message;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
@Override
public String execute() throws Exception {
System.out.println("username:"+user.getUsername());
System.out.println("password:"+user.getPassword());
System.out.println("address:"+user.getAddress());
System.out.println("message:"+message);
return "success";
}
}
index.jsp
<form action="login.action">
用户名:<input type="text" name="user.username"><br/>
密码:<input type="text" name="user.password"><br/>
地址:<input type="text" name="user.address"><br/>
普通消息:<input type="text" name="message"><br/>
<input type="submit" value="提交">
</form>
success.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:property value="user.username"/><br/>
<s:property value="user.password"/><br/>
<s:property value="user.address"/><br/>
<s:property value="message"/>
</body>
</html>
3、模型驱动获取
LoginAction.java
package action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;
import entity.User;
public class LoginAction implements Action,ModelDriven<User>{
//封装对象
private User user =new User();
@Override
public User getModel() {
return user;
}
@Override
public String execute() throws Exception {
System.out.println("username:"+user.getUsername());
System.out.println("password:"+user.getPassword());
System.out.println("address:"+user.getAddress());
return "success";
}
}
index.jsp
<form action="login.action">
用户名:<input type="text" name="username"><br/>
密码:<input type="text" name="password"><br/>
地址:<input type="text" name="address"><br/>
普通消息:<input type="text" name="message"><br/>
<input type="submit" value="提交">
</form>
success.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:property value="username"/><br/>
<s:property value="password"/><br/>
<s:property value="address"/><br/>
</body>
</html>
4、获取数组
ArrayDataAction.java
package action;
import com.opensymphony.xwork2.Action;
import com.opensymphony.xwork2.ModelDriven;
import entity.User;
public class ArrayDataAction implements Action{
private String[] hobbies;
//自动类型转换
//定义了double类型,但是页面提交的数据都是文本类型
//Struts2的类型转换是基于OGNL表达式的自动进行类型转换,
//再也不用Double.parseDouble("123")转换
private Double[] numbers = new Double[3];
public String[] getHobbies() {
return hobbies;
}
public void setHobbies(String[] hobbies) {
this.hobbies = hobbies;
}
public Double[] getNumbers() {
return numbers;
}
public void setNumbers(Double[] numbers) {
this.numbers = numbers;
}
@Override
public String execute() throws Exception {
for (int i = 0; i < hobbies.length; i++) {
System.out.println(hobbies[i]);
}
System.out.println("------------------------");
for (int i = 0; i < numbers.length; i++) {
System.out.println(numbers[i]);
}
return "success";
}
}
index.jsp
<form action="ArrayData.action">
爱好1:<input type="text" name="hobbies" /> <br/>
爱好2:<input type="text" name="hobbies" /> <br/>
爱好3:<input type="text" name="hobbies" /> <br/>
数字1:<input type="text" name="numbers" /> <br/>
数字2:<input type="text" name="numbers" /> <br/>
数字3:<input type="text" name="numbers" /> <br/>
<input type="submit" value="提交">
</form>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引入jstl标准标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!-- 设置项目的根路径 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>
<%@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>
<--遍历获取数组数据-->
<c:forEach items="${hobbies}" var="hobbie">
<span>${hobbie}</span>
</c:forEach>
<c:forEach items="${numbers}" var="number">
<span>${number}</span>
</c:forEach>
</body>
</html>
5、获取list集合
ListDataAction.java
package action;
import java.util.List;
import com.opensymphony.xwork2.Action;
public class ListDataAction implements Action{
private List<String> hobbies;
private List<String> numbers;
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public List<String> getNumbers() {
return numbers;
}
public void setNumbers(List<String> numbers) {
this.numbers = numbers;
}
@Override
public String execute() throws Exception {
for (int i = 0; i < hobbies.size(); i++) {
System.out.println(hobbies.get(i));
}
System.out.println("------------------------");
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
return "success";
}
}
index.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>
<form action="ListData.action">
用户名1:<input type="text" name="list[0].username" /> <br/>
密码1:<input type="text" name="list[0].password" /> <br/>
地址1:<input type="text" name="list[0].address" /> <br/>
用户名2:<input type="text" name="list[1].username" /> <br/>
密码2:<input type="text" name="list[1].password" /> <br/>
地址2:<input type="text" name="list[1].address" /> <br/>
用户名3:<input type="text" name="list[2].username" /> <br/>
密码3:<input type="text" name="list[2].password" /> <br/>
地址3:<input type="text" name="list[2].address" /> <br/>
<input type="submit" value="提交">
</form>
</body>
</html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引入jstl标准标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!-- 设置项目的根路径 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>
<%@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>
<!-- 获取集合的值方式1 -->
<s:property value="list[0].username"/><br/>
<s:property value="list[0].password"/><br/>
<s:property value="list[0].address"/><br/>
<s:property value="list[1].username"/><br/>
<s:property value="list[1].password"/><br/>
<s:property value="list[1].address"/><br/>
<s:property value="list[2].username"/><br/>
<s:property value="list[2].password"/><br/>
<s:property value="list[2].address"/><br/>
<hr/>
<!-- 获取集合的值方式2 struts2 标签迭代 -->
<s:iterator value="list">
<s:property value="username"/> <br/>
<s:property value="password"/> <br/>
<s:property value="address"/> <br/>
</s:iterator>
<hr/>
<!-- 获取集合的值方式3 el表达式 -->
<c:forEach items="${list}" var="user">
<span>${user.username}</span>
<span>${user.password}</span>
<span>${user.address}</span>
</c:forEach>
</body>
</html>
6、获取map集合
MapDataAction.java
package action;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import entity.User;
public class MapDataAction implements Action{
private Map<String,User> map;
public Map<String, User> getMap() {
return map;
}
public void setMap(Map<String, User> map) {
this.map = map;
}
@Override
public String execute() throws Exception {
User user1 = map.get("one");
User user2 = map.get("two");
System.out.println("map1:"+user1.toString());
System.out.println("map2:"+user2.toString());
return "success";
}
}
index.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>
<form action="MapDataAction.action">
用户名1:<input type="text" name="map['one'].username" /> <br/>
密码1:<input type="text" name="map['one'].password" /> <br/>
地址1:<input type="text" name="map['one'].address" /> <br/>
用户名2:<input type="text" name="map['two'].username" /> <br/>
密码2:<input type="text" name="map['two'].password" /> <br/>
地址2:<input type="text" name="map['two'].address" /> <br/>
<input type="submit" value="提交">
</form>
</body>
</html>
success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!-- 引入jstl标准标签库 -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!-- 设置项目的根路径 -->
<c:set var="ctx" value="${pageContext.request.contextPath}"></c:set>
<%@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>
<--键值对遍历-->
<c:forEach var="item" items="${map}">
${item.key} > ${item.value} <br>
</c:forEach>
<--键遍历-->
<c:forEach var="item" items="${map}">
${item.key}<br>
</c:forEach>
<--值遍历-->
<c:forEach var="item" items="${map}">
${item.value}<br>
</c:forEach>
</body>
</html>
struts2自动类型转换
我们之前在servlet时候去获取页面的数据,因为页面的数据提交过来的数据都是文本类型的数据,如果需要转换成其他类型,比如int类型,我们需要Integer.parselnt(request.getparame("")去转换成int类型,或者说我们做增加
的时候。
值栈:
1.之前在web阶段,在servlet里面进行操作,把数据放到域对象,在页面中使用EL表达式获取到,域对象在一-定范围内,存储和取值
2、在struts2框架提供了本身的一种存储机制,类似于域对象,是值栈。可以存值和取值,通过action里面把数据放到值栈里面,在页面中获取到值栈的数据,值栈具有栈的特点。
3、servlet和action的区别
(1)servlet:默认在第一次访问的时候创建,创建一次,单例模式。
(2)Action:访问时候创建,每次访问action的时候,都会创建action对象,创建多次,多实例对象。
4、值栈存储位置
(1)每次访问action时候,都会创建action对象
(2)在每个action对象里面都会有一个值栈对象(只有一个)
获取值栈对象
//获取ActionContext对象
ActionContext context = ActionContext.getContext();
//获取到值栈对象,每个action对象只有一个值栈对象
ValueStack stack1 = context.getValueStack();
ValueStack stack2 = context.getValueStack();
System.out.println(stack1==stack2);
值栈存值
//值栈存储方式1:
//stack1.set("username", "张三");
//值栈存储方式2:
//stack1.push("abcd");
//值栈存储方式3:最常用,在action中定义变量,生成变量get/set方法(好处是减少空间的分配)
name="myname";
获取非值栈对象
非值栈对象:application、session、request、parameters、attr
//application
Map<String, Object> application = ActionContext.getContext().getApplication();
//session
Map<String, Object> session = ActionContext.getContext().getSession();
//request
HttpServletRequest request = ServletActionContext.getRequest();
非值栈存值
//application
session.put(key, value);
//session
application.put(key, value)
//request
request.setAttribute("name", value);
获取非值栈对象
<!-- 非值栈对象获取方式用#-->
<s:iterator>
<s:property value="#user.username"/>
<s:property value="#user.password"/>
</s:iterator>
拦截器
定义:
java里的拦截器是动态拦截Action调用的对象。它提供了一种机制可以使开发者可以定义在一个action 执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种可以提取action中可 重用部分的方式。在AOP(Aspect-Oriented Programming)中拦截器用于在某个方法或字段被访问之 前,进行拦截然后在之前或之后加入某些操作。
原理:
过滤器和拦截器的区别?
(1)过滤器:服务器启动时创建,过滤器理论上可以任意内容,比如 html、jsp、servlet、图片路径
(2)拦截器:拦截器只可以拦截action 2 Servlet和action区别 。
Servlet和action区别?
(1)servlet默认第一次访问时候创建,创建一次,单实例对象
(2) action每次访问时候创建,创建多次,多实例对象
自定义一个拦截器需要二步:
在struts2里面有很多拦截器,这些拦截器是struts2封装的功能,但是在实际开发中,struts2里面的拦 截器中可能没有要使用的功能,这个时候需要自己写拦截器实现功能。
1 .自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。
package interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class MyTimeInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation invocation) throws Exception {
//开始时间
long startTime = System.currentTimeMillis();
System.out.println("Action开始时间"+startTime);
//负责调用action,在此之前会依次调用所有配置的拦截 器,返回action结果
String result = invocation.invoke();
long endTime = System.currentTimeMillis();
long execTime = endTime-startTime;
System.out.println("Action结束时间:"+endTime);
System.out.println("执行Action总共时间"+execTime);
System.out.println("执行Action返回的result结果:"+result);
return result;
}
}
2 .在struts.xml中action上方定义的拦截器,在需要使用的action中引用上述定义的拦截器。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<!-- 配置拦截器 -->
<interceptors>
<interceptor name="myTime" class="interceptor.MyTimeInterceptor"/>
</interceptors>
<action name="login" class="action.MyTimeAction" method="execute">
<result name="success">/success.jsp</result>
<result name="fail" type="redirect">/fail.jsp</result>
<!-- 在action里面引用自定义的拦截器 -->
<interceptor-ref name="myTime">
<!-- 可以通过参数去设置action的某些方法不进行拦截 -->
<!-- <param name="excludeMethods">add,delete</param> -->
</interceptor-ref>
<interceptor-ref name="defaultStack"/>
</action>
</package>
</struts>
案例:
单文件上传:
UploadFileAction.java
package action;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
public class UploadFileAction{
private String savePath;
private File upload;
private String uploadContentType;
private String uploadFileName;
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String uploadFile() throws Exception {
// File destFile = new File(ServletActionContext.getRequest().getRealPath(save));
String file = ServletActionContext.getRequest().getRealPath(savePath)+"\\"+this.getUploadFileName();
File destFile = new File(file);
FileUtils.copyFile(upload, destFile);
return "success";
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- <include file="action/struts-time.xml"></include> -->
<package name="default" namespace="/" extends="struts-default">
<action name="upload" class="action.UploadFileAction" method="uploadFile">
<param name="savePath">/upload</param>
<result name="input">/uploadError.jsp</result>
<result name="success">/uploadFile.jsp</result>
<!-- 使用struts2 FileUploadInterceptor上传的拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 上传文件的大小 单位字节,10M -->
<param name="maximumSize">10240000</param>
<!-- 上传文件的类型 -->
<param name="allowedTypes">png,gif,jpg,jpej</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
uploadFile.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 action="upload.action" enctype="multipart/form-data" method="post">
<s:file name="upload" />
<s:submit value="上传" />
</s:form>
<img width="600px" height="200px" src="upload/<s:property value='uploadFileName'/>">
</body>
</html>
多文件上传:
UploadFileAction.java
package action;
import java.io.File;
import org.apache.commons.io.FileUtils;
import org.apache.struts2.ServletActionContext;
public class UploadFileAction{
private String savePath;
private File[] upload;
private String[] uploadContentType;
private String[] uploadFileName;
public String getSavePath() {
return savePath;
}
public void setSavePath(String savePath) {
this.savePath = savePath;
}
public File[] getUpload() {
return upload;
}
public void setUpload(File[] upload) {
this.upload = upload;
}
public String[] getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String[] uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String[] getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String[] uploadFileName) {
this.uploadFileName = uploadFileName;
}
public String uploadFile() throws Exception {
for (int i = 0; i < upload.length; i++) {
String file = ServletActionContext.getRequest().getRealPath(savePath)+"\\"+this.getUploadFileName()[i];
File destFile = new File(file);
//upload[i]遍历upload对象(上传文件)
FileUtils.copyFile(upload[i], destFile);
}
return "success";
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- <include file="action/struts-time.xml"></include> -->
<package name="default" namespace="/" extends="struts-default">
<action name="upload" class="action.UploadFileAction" method="uploadFile">
<param name="savePath">/upload</param>
<result name="input">/uploadError.jsp</result>
<result name="success">/uploadFile.jsp</result>
<!-- 使用struts2 FileUploadInterceptor上传的拦截器 -->
<interceptor-ref name="fileUpload">
<!-- 上传文件的大小 单位字节,10M -->
<param name="maximumSize">10240000</param>
<!-- 上传文件的类型 -->
<param name="allowedTypes">png,gif,jpg,jpej</param>
</interceptor-ref>
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
uploadFile.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 action="upload.action" enctype="multipart/form-data" method="post">
<s:file name="upload" />
<s:file name="upload" />
<s:file name="upload" />
<s:submit value="上传" />
</s:form>
<s:iterator value="uploadFileName">
<img width="600px" height="200px" src="upload/<s:property />">
</s:iterator>
</body>
</html>
文件下载:
DownloadAction.java
package action;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownloadAction extends ActionSupport{
private String fileName;
private String inputPath;
private InputStream inputStream;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getInputPath() {
return inputPath;
}
public void setInputPath(String inputPath) {
this.inputPath = inputPath;
}
public InputStream getInputStream() throws Exception {
//得到从服务器需要下载的文件路径
String path = ServletActionContext.getRequest().getRealPath(inputPath+"\\"+fileName);
//返回流对象
return new BufferedInputStream(new FileInputStream(path));
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public String login(){
return "success";
}
}
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<!-- 设置常量 三种文件总大小5M 超出报异常-->
<constant name="struts.multipart.maxsize" value="50971520"></constant>
<package name="default" namespace="/" extends="struts-default">
<action name="download" class="action.DownloadAction" method="login">
<!-- 非Action中inputPath赋值,从服务器/upload文件下载 -->
<param name="inputPath">/upload</param>
<result type="stream">
<!-- 下载以二进制方式下载 -->
<param name="contentType">application/octet-stream</param>
<!-- 默认调用getinputStream()方法进行下载 -->
<param name="inputName">inputStream</param>
<!-- 下载弹出框信息 -->
<param name="contentDisposition">
attachment;filename="${fileName}"
</param>
<!-- 设置缓存区大小 单位字节 -->
<param name="bufferSize">4096</param>
</result>
</action>
</package>
</struts>
downloadFile.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>
<a href="download.action?fileName=1.png">下载</a>
</body>
</html>