MVC框架--之Struts2

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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值