MVC框架--之Struts2

    技术2022-07-10  135

    文章目录

    struts2定义:搭建struts2环境1、导包13个核心jar包:2、web.xml中配置过滤器3、定义一个java类 action,用于处理请求,方法返回值类型Stringaction创建方式: 4、在src下配置struts.xml result的Type属性实现跳转global-results全局变量:分模块开发:Action访问方式:1、传统访问2、动态调用访问3、通配符调用访问 OGNL:获取表单数据:1、属性获取2、对象获取3、模型驱动获取4、获取数组5、获取list集合6、获取map集合 struts2自动类型转换 值栈:获取值栈对象值栈存值获取非值栈对象非值栈存值获取非值栈对象 拦截器定义:原理:过滤器和拦截器的区别?Servlet和action区别?自定义一个拦截器需要二步:1 .自定义一个实现Interceptor接口(或者继承自AbstractInterceptor)的类。2 .在struts.xml中action上方定义的拦截器,在需要使用的action中引用上述定义的拦截器。 案例: 单文件上传:多文件上传:文件下载:

    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>
    Processed: 0.012, SQL: 9