Structs2(2访问web资源)耦合和解耦两种方式

Structs2.xml介绍

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Action

struts.xml文件中

<include file="example.xml"/>

将其他的struct.xml放进该.xml文件中

action VS Action类

1). action: 代表-一个Struts2 的请求。
2). Action类:能够处理Struts2 请求的类.

属性的名字必须遵守与JavaBeans 属性名相同的命名规则.
属性的类型可以是任意类型。从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生
必须有一个不带参的构造器:通过反射创建实例
至少有-个供struts 在执行这个action 时调用的方法
同一个Action 类可以包含多个action 方法。
Struts2 会为每一个 HTTP请求创建一个新的 Action实例,即Action不是单例的,是线程安全的。

在Action 中访问WEB资源

l). 什么是WEB资源?
HttpServletRequest, HttpSession, ServletContext 等原生的Servlet API.
II).为什么访问WEB资源?
B\S的应用的Controller中必然需要访问WEB资源:向域对象中读写属性,读写Cookie,获取realPath …

III).如何访问?
1.和Servlet API解耦的方式:只能访问有限的Servlet API对象,且只能访问其有限的方法(读取请求参数,读写域对象的属性,使session销毁>

使用ActionContext
实现XxxAware接口
选用的建议:若-一个Action类中有多个action 方法,且多个方法都需要使用城对象的Map或parameters, 则建议使用Aware接口的方式
session对应的Map实际上是Sess ionMap 类型的!强转后若调用其invalidate() 方法,可以使其session失效!

2.和Servlet API耦合的方式:可以访问更多的Servlet API对象,且可以调用其原生的方法●

使用 ServletActionContext
实现ServletXxxAware 接口

代码:
index.jsp

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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="TestActionContext.action?name=a">Test ActionContext</a>
	
	<br><br>
	
	<a href="TestAware.do?name=123">Test Aware</a>

	<br><br>
	
	<a href="testActionSupport.do">Test ActionSupport</a>

	<br><br>
	
	<a href="testResult.do?number=4">Test Result</a>

	<br><br>
	
	<a href="testDynamicMethodInvocation.do">Test DynamicMethodInvocation</a>

	<% 
		if(application.getAttribute("date") == null)
			application.setAttribute("date", new Date());
	
		request.setAttribute("req", "reqvalue");
	%>
	
</body>
</html>

与 Servlet API 解耦的访问方式

通过ActionContext访问
ActionContext 是 Action 执行的上下文对象, 在 ActionContext 中保存了 Action 执行所需要的所有对象, 包括 parameters, request, session, application 等.
获取 HttpSession 对应的 Map 对象:
public Map getSession()
获取 ServletContext 对应的 Map 对象:
public Map getApplication()
获取请求参数对应的 Map 对象:
public Map getParameters()
获取 HttpServletRequest 对应的 Map 对象:
public Object get(Object key): ActionContext 类中没有提供类似 getRequest() 这样的方法来获取 HttpServletRequest 对应的 Map 对象. 要得到 HttpServletRequest 对应的 Map 对象, 可以通过为 get() 方法传递 “request” 参数实现

TestActionContextAction.java

package product;

import java.util.Map;

import org.apache.struts2.dispatcher.SessionMap;

import com.opensymphony.xwork2.ActionContext;

public class TestActionContextAction {

	public String execute(){
		
		//0. 获取 ActionContext 对象
		//ActionContext 是 Action 的上下文对象. 可以从中获取到当往 Action 需要的一切信息
		ActionContext actionContext = ActionContext.getContext();
		
		//1. 获取 application 对应的 Map, 并向其中添加一个属性
		//通过调用 ActionContext 对象的 getApplication() 方法来获取 application 对象的 Map 对象
		Map<String, Object> applicationMap = actionContext.getApplication();
		//设置属性
		applicationMap.put("applicationKey", "applicationValue");
		
		//获取属性
		Object date = applicationMap.get("date");
		System.out.println("date: " + date);
		
		//2. session
		Map<String, Object> sessionMap = actionContext.getSession();
		sessionMap.put("sessionKey", "sessionValue");
		
		System.out.println(sessionMap.getClass()); 
		
		if(sessionMap instanceof SessionMap){
			SessionMap sm = (SessionMap) sessionMap;
			sm.invalidate();
			System.out.println("session 失效了. ");
		}
		
		//3. request* 
		//ActionContext 中并没有提供 getRequest 方法来获取 request 对应的 Map
		//需要手工调用 get() 方法, 传入 request 字符串来获取. 
		Map<String, Object> requestMap = (Map<String, Object>) actionContext.get("request");
		requestMap.put("requestKey", "requestValue");
		
		//4. 获取请求参数对应的 Map, 并获取指定的参数值. 
		//键: 请求参数的名字, 值: 请求参数的值对应的字符串数组
		//注意: 1. getParameters 的返回值为在 Map<String, Object>, 而不是 Map<String, String[]>
		//     2. parameters 这个 Map 只能读, 不能写入数据, 如果写入, 但不出错, 但也不起作用!
		Map<String, Object> parameters = actionContext.getParameters();
		System.out.println(((String[])parameters.get("name"))[0]);
		
		parameters.put("age", 100);
		
		return "success";
	}
	
}

通过 Action 实现接口
Action 类通过可以实现某些特定的接口, 让 Struts2 框架在运行时向 Action 实例注入 parameters, request, session 和 application 对应的 Map 对象:
在这里插入图片描述
TestAwareAction.java

package product;

import java.util.Map;

import org.apache.struts2.interceptor.ApplicationAware;
import org.apache.struts2.interceptor.ParameterAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

public class TestAwareAction implements ApplicationAware, SessionAware, RequestAware,
	ParameterAware{
	
	public String execute(){
		
		//1. 向 application 中加入一个属性: applicationKey2 - applicationValue2
		application.put("applicationKey2", "applicationValue2");
		
		//2. 从 application 中读取一个属性 date, 并打印. 
		System.out.println(application.get("date"));
		
		return "success";
	}
	
	public String save(){
		
		return null;
	}

	private Map<String, Object> application;
	
	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}

	@Override
	public void setParameters(Map<String, String[]> parameters) {
		
	}

	@Override
	public void setRequest(Map<String, Object> request) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setSession(Map<String, Object> session) {
		// TODO Auto-generated method stub
		
	}
	
}

与 Servlet 耦合的访问方式

直接访问 Servlet API 将使 Action 与 Servlet 环境耦合在一起, 测试时需要有 Servlet 容器, 不便于对 Action 的单元测试.
使用ServletActionContext
直接获取 HttpServletRequest 对象:
ServletActionContext.getRequest()
直接获取 HttpSession 对象
ServletActionContext.getRequest().getSession()
直接获取 ServletContext 对象
ServletActionContext.getServletContext()

package product;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

public class ouhe {
	public String execute(){
		HttpServletRequest a=ServletActionContext.getRequest();
		HttpSession b=a.getSession();
		ServletContext c=ServletActionContext.getServletContext();
		System.out.println("run");
		return "success";
	}
}

通过实现 ServletRequestAware, ServletContextAware 等接口的方式

package product;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.*;
import org.apache.struts2.util.ServletContextAware;

public class ouhejiekou implements ServletRequestAware,ServletContextAware,ServletResponseAware{

	@Override
	public void setServletRequest(HttpServletRequest arg0) {
		// TODO Auto-generated method stub
		System.out.println("nihao");
	}
	public String execute(){
		
		return "success";
	}
	@Override
	public void setServletContext(ServletContext arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void setServletResponse(HttpServletResponse arg0) {
		// TODO Auto-generated method stub
		
	}

}

test-actionContext.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!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>
	
	<h4>Test ActionContext Page</h4>
	
	application : ${applicationScope.applicationKey }
	<br><br>
	
	session: ${sessionScope.sessionKey }
	<br><br>
	
	request: ${requestScope.requestKey }
	<br><br>
	
	age: ${parameters.age }
	
</body>
</html>

struts2.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 可以受理的请求的扩展名 -->
	<constant name="struts.action.extension" value="action,do,"></constant>
	
	<!-- 打开允许动态方法调用的开关, 默认是 false -->
	<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
	
    <package name="default" namespace="/" extends="struts-default">

		<action name="TestActionContext" 
			class="product.TestActionContextAction">
			<result  name="success">/test-actionContext.jsp</result>	
		</action>
		
		<action name="TestAware" 
			class="product.TestAwareAction">
			<result>/test-aware.jsp</result>	
		</action>
		
		<action name="testActionSupport">
			<result>/testActionSupport.jsp</result>
		</action>

		<action name="testResult" class="com.atguigu.struts2.action.TestResultAction">
			<result name="success" type="dispatcher">/success.jsp</result>
			<result name="login" type="redirect">/login.jsp</result>
			
			<!-- 重定向到一个 Action -->
			<!--  
			<result name="index" type="redirectAction">
				<param name="actionName">testAction</param>
				<param name="namespace">/atguigu</param>
			</result>
			-->
			
			<!-- 通过 redirect 的响应类型也可以便捷的实现 redirectAction 的功能! -->
			<result name="index" type="redirect">/atguigu/testAction.do</result>
			
			<!-- 转发到一个 Action -->
			<!--  
			<result name="test" type="chain">
				<param name="actionName">testAction</param>
				<param name="namespace">/atguigu</param>
			</result>
			-->
			
			<!-- 不能通过 type=dispatcher 的方式转发到一个 Action -->
			<result name="test">/atguigu/testAction.do</result>
			
			
		</action>
		
		<action name="testDynamicMethodInvocation"
			class="product.TestDynamicMethodInvocationActoin"
			method="save">
			<result>/success.jsp</result>	
		</action>

    </package>
    
    <package name="testPackage" namespace="/atguigu" extends="struts-default">
    	<action name="testAction" 
    		class="product.TestAction">
    		<result>/success.jsp</result>
    	</action>
    </package>


</struts>

猜你喜欢

转载自blog.csdn.net/feiqipengcheng/article/details/106451682