Struts2 的BaseAction

Action类的三种编写方式

第一种.使用公共的POJO类作为Action.提供公共的无参数的Action方法.(不推荐).

缺点:

    没有一种方式约束Action方法必须是公共的无参数的.

    Action方法的返回逻辑视图名可以自定指定. 有时起名不规范. 比如:"ooxx".

解决方案:第二种.

第二种.定义一个类,实现于com.opensymphony.xwork2.Action接口.并覆写execute方法即可.(不推荐)

Action接口中,不仅提供了Action方法的声明,也提供了常用的逻辑视图名称:

publicstatic final String SUCCESS = "success";

publicstatic final String NONE = "none";

publicstatic final String ERROR = "error";

publicstatic final String INPUT = "input";

publicstatic final String LOGIN = "login";

缺点:不支持国际化,数据校验,消息机制.

解决方案:第三种:

第三种.定义一个类,继承于com.opensymphony.xwork2.ActionSupport.(推荐)

public classActionSupport implements Action, Validateable, ValidationAware, TextProvider,LocaleProvider, Serializable {}

---------------------------------------------

真实开发中,我们却往往再提供一个BaseAction.

--BaseActionextends ActionSupport

-----AActionextends BaseAction

-----BActionextends BaseAction


访问ServletApi

通过ActionContext工具类

Struts2将作用域对象重新使用Map集合进行了封装,所以现在操作作用域中的共享数据就是直接操作对应的Map集合

理解ActionContext:从字面上分析,表示Action的上下文对象.

ActionContext封装每一次请求的相关信息.

可以使用ActionContext中的非静态方法来获取Servlet相关的API

所以需要获取到ActionContext的对象


import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 耦合方法一:
 * 	不能直接访问api对象本身 只能访问三大作用域中的属性值
 * 使用ActionContext对象获得
 * @author Administrator
 *
 */
public class ServletMethodOneAction extends ActionSupport{
	
	@Override
	public String execute() throws Exception {
		//1.获得action的上下文环境
		ActionContext act = ActionContext.getContext();
		
		//2.1 获得request作用域中的值
		Map<String, Object> request = (Map<String, Object>) act.get("request");
		//往作用域中存放值
		request.put("username", "request");
		
		//2.2 获得session作用域中的值
		Map<String, Object> session = act.getSession();
		session.put("username", "session");
		
		//2.3 获得application作用域中的值
		Map<String, Object> application = act.getApplication();
		application.put("username", "application");
		return SUCCESS;
	}

}


import java.util.Map;

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

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 解耦方法二:
 * 	不能直接访问api对象本身 只能访问三大作用域中的属性值
 * 	使用实现接口的方法获得
 * @author Administrator
 *
 */
public class ServletMethodTwoAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{
	
	private Map<String, Object> request;
	private Map<String, Object> session;
	private Map<String, Object> application;
	
	@Override
	public String execute() throws Exception {
		//往作用域中存放值
		request.put("username", "request");
		
		session.put("username", "session");
		
		application.put("username", "application");
		return SUCCESS;
	}

	@Override
	public void setRequest(Map<String, Object> arg0) {
		this.request = arg0;
	}

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

	@Override
	public void setSession(Map<String, Object> arg0) {
		this.session = arg0;
	}

}

通过ServletActionContext工具类.

通过ServletActionContext类中的静态方法,得到Servlet相关的Api

这种方式直接通过ServletActionContext的静态方法就可以获取ServletAPI对象,操作和理解非常简单.

在开发中很多人都喜欢使用,但是依然是ActionServletAPI有耦合


import java.util.Map;

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.ApplicationAware;
import org.apache.struts2.interceptor.RequestAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
/**
 * 耦合方法三:
 * 	直接访问api对象本身 
 * 	使用 ServletActionContext
 * @author Administrator
 *
 */
public class ServletMethodThreeAction extends ActionSupport{
	

	
	@Override
	public String execute() throws Exception {
		//获得request对象
		HttpServletRequest request = ServletActionContext.getRequest();
		
		String ip = request.getRemoteAddr();//获得远程的ip地址
		System.out.println("ip->"+ip);
		
		
		//获得 session对象
		HttpSession session = request.getSession();
		//获得application对象
		ServletContext application = ServletActionContext.getServletContext();
		
		//获得response对象
		HttpServletResponse response = ServletActionContext.getResponse();
		
		return SUCCESS;
	}

}
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;

import com.opensymphony.xwork2.ActionSupport;
/**

Action类实现感知接口.

ServletRequestAware:感知HttpServletRequest对象;

ServletResponseAware:感知HttpServletResponse对象;

ServletSessionAware:感知HttpSession对象;

存在的问题,和ServletAPI耦合严重;

问题:Action中感知接口的方法是谁在调用?----->servletConfig拦截器(优先于Action执行)

* */public abstract class BaseAction extends ActionSupport implements ServletRequestAware, ServletResponseAware{protected HttpServletRequest request;protected HttpServletResponse response;@Overridepublic void setServletRequest(HttpServletRequest arg0) {this.request = arg0;}@Overridepublic void setServletResponse(HttpServletResponse arg0) {this.response = arg0;}} 提供一个 BaseAction . 根据需求访问serveltAPI, 尽量解耦合, ActionContext工具类 比较好。

Action中多方法调用

问题:在一个Action中可能包含多个Action方法,比如EmployeeAction就包含处理员工的CRUD等方法.

Action中多个Action方法会造成<action>配置的臃肿(右图).

解决方案:

方案1: DMI:动态方法调用 :官方不推荐.

      格式: action!方法名

      比如: emp!edit    emp!list

Struts2新的版本中,默认的关闭了DMI.若我们需要使用DMI,就需要配置常量,启用动态方法调用.此时:<action/>元素不需要指定method属性值.

访问路径:/namespace/actionName!methodName

		  <constantname="struts.enable.DynamicMethodInvocation"value="true"/>
		  <action name="user" class="cn.com.my.UserAction">
		  	<result name="insert">/insertUser.jsp</result>
		  	<result name="update">/updateUser.jsp</result>
		  	<result name="delete">/deleteUser.jsp</result>
		  	<result name="select">/selectUser.jsp</result>
		  	<result >/index.jsp</result>
		  </action>

-----------------------------------------------------------------------------

方案2: 使用通配符的方式类配置:  通配符:*

 访问路径:/namespace/actionName     actionName为约定格式

	 <!-- 
			action的name属性中使用*替代方法的名称
			其他属性中可使用{数字} 表示第几个*号的位置是方法的名称,从1开始
			http://127.0.0.1:8080/struts2/user/UserAction_delete
	 -->
    <package name="hell" extends="struts-default" namespace="/user">
    	<action name="*_*" class="cn.com.my.{1}" method="{2}">
    		<result name="{2}" type="dispatcher">/{1}_{2}.jsp</result>
    	</action>
    </package>

 

Action获取请求参数三种方式,归功于拦截器(ParametersIntercepter)类型转换:


第一种:Action本身作为Model对象,通过setter方法封装(属性注入)

第二种:创建独立Model对象,页面通过ognl表达式封装(属性注入)

第三种:使用ModelDriven接口,对请求数据进行封装(模型驱动)了解

Action获取请求参数三种方式如何选择? 1.2必须提供Getter/Setter方法

从操作便捷性来分析,首选使用方式2.   

   也可以使用:方式1+方式2.或者方式1+方式3.

   不推荐使用方式3.

 

基本类型正常接收,数组类型的参数的接收:

*List类型参数的封装

页面中的OGNL表达式的书写:单引号

users[0].name = xxx

users[0].age = 19

users[1].name = ooo

users[1].age = 20

Action中的属性的定义:

private List<User> users = newArrayList<>();

Getter/Setter方法

 

*Map类型参数的封装

页面中的OGNL表达式的书写:

map [a].name = xxx

map [a].age = 19

map [b].name = “ooo”

map [b].age = 20

Action中的属性的定义:

private Map<String, User> map = newHashMap<>();

Getter/Setter方法

 

有参考其他文章

猜你喜欢

转载自blog.csdn.net/qq_42402854/article/details/80957023