Struts2 请求响应流程及创建步骤

最近在对Struts2框架的项目进行源代码业务逻辑漏洞分析,趁机把之前学的struts2、自己对struts的简单理解整理一下。有不对的地方还请各位看官大神多指教。

对于新项目开发,不建议使用Struts2框架,其含有太多的漏洞,如Struts2-045远程命令执行、S2-057远程命令执行等高危漏洞。

一、简介

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互,Struts2在Struts1融合webwork。

ONGL表达式:就是对象图形化导航语言,在前端页面中,访问action的属性、方法;类似于对JSP的封装,使得编程更加方便。

工作流程: 
(1)客户端浏览器发送HTTP请求到Web应用 
(2)Web容器将请求传递到标准ActionContextCleanUp过滤器以消除属性,而不让后续过滤器清楚,以延长Action中属性(包括自定义属性)的生命周期。
(3)再经过如StiMesh等其他过滤器后,请求传递给StrutsPrepareAndExecuteFilter核心控制器 
(4)StrutsPrepareAndExecuteFilter调用ActionMapper(Action映射器)确定调用哪个Action,再将控制权转移给ActionProxy代理 
(5)ActionProxy代理调用配置管理器ConfigurationManager从配置文件struts.xml中读取配置信息,然后创建ActionInvocation对象 
(6)ActionInvocation在调用拦截器链中的拦截器后再调用Action,根据Action返回的结果字符串查找对应的Result 
(7)Result调用视图模板,再以相反的顺序执行拦截器链,返回HTTP响应 
(8)HTTP响应以相反的顺序返回给核心控制器StrutsPrepareAndExecuteFilter以及其他web.xml中定义的过滤器,最终返回给客户端。

二、创建过程

(一)创建Dynamic Web Project,记得选择“Generate web.xml deployment descriptor”

(二)拷贝相关struts2的jar包,加入项目中

(三)web.xml中配置struts2,即配置filter和filter-mapping

 <filter>
  	<filter-name>Struts2</filter-name>
  	<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
  	<init-param>
  		<param-name>encoding</param-name>
  		<param-value>UTF-8</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>Struts2</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>

(四)创建struts2.xml文件(非注解,传统方式)

struts2.xml文件头配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">

根据下文实际情况,配置Action、interceptor等。

(五)创建Action,继承ActionSupport,如果涉及参数传递,建议通过实现ModelDriven<T>,封装对象实现。

创建用户操作Action:UserAction

public class UserAction extends ActionSupport implements ModelDriven<User> {
	public User user = new User();
	public String login() throws Exception {
		// 封装User
		// 调用UserService中的判断用户是否存在的方法
		UserService userService = new UserService();
		boolean isSuccess = userService.findUser(user);
		// 拿到返回值
		if (isSuccess) {
			// 成功 跳转到获取所有帖子的请求 在session域中放置user对象
			ActionContext.getContext().getSession().put("user", user);
			return "getAllPaste";
		} else {
			// 失败 添加错误信息 转发到登录界面login.jsp
			ActionContext.getContext().put("error", "用户名或者密码错误!!");
			return "login";
		}
	}

	@Override
	public User getModel() {
		// TODO Auto-generated method stub
		return user;
	}
}

创建帖子操作Action:PasteAction

public class PasteAction extends ActionSupport {
	public String getAllPaste() throws Exception {
		PasteService pasteService = new PasteService();
		List<Paste> pasteList = pasteService.findAllPaste();
		ActionContext.getContext().put("pasteList", pasteList);
		return "paste";
	}	
}

(六)在struts2.xml文件中,配置上述两个Action(采用“动态方法”调用)

1、开启动态方法调用:

<constant name="struts.devMode" value="true" />
<constant name="struts.enable.DynamicMethodInvocation" value="true" />

2、允许动态方法调用的方法设置:

package下设置:<global-allowed-methods>regex:.*</global-allowed-methods>,代表所有方法均允许动态调用。

一个响应后,有四种处理方式:转发、重定向、转发到Action、重定向到Action

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<constant name="struts.devMode" value="true" />
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />
	<package name="fourm" namespace="/" extends="struts-default">
		<global-allowed-methods>regex:.*</global-allowed-methods>
		<action name="UserAction_*" class="com.xm.web.UserAction" method="{1}">
			<!-- 转发到Action -->
			<!-- <result name="getAllPaste" type="chain">PasteAction_getAllPaste</result> -->
			<!-- 重定向到Action -->
			<result name="getAllPaste" type="redirectAction">PasteAction_getAllPaste</result>
			<!-- 转发 -->
			<result name="login">/login.jsp</result>
		</action>
		
		<action name="PasteAction_*" class="com.xm.web.PasteAction" method="{1}">
			<result name="paste">/paste.jsp</result>
		</action>
	</package>
</struts>

(七)创建拦截器,继承MethodFilterInterceptor,实现doIntercept方法

public class UserIntercept extends MethodFilterInterceptor {
	@Override
	protected String doIntercept(ActionInvocation invocation) throws Exception {
		// 获取session
		Map<String, Object> session = ActionContext.getContext().getSession();
		// 判断session域中是否有user
		Object object = session.get("user");
		if (object == null) {
			// 没有-->重定向到login.jsp
			return "toLogin";
		} else {// 如果有-->放行
			return invocation.invoke();
		}
	}
}

(八)在struts2.xml文件中,配置上述拦截器,在package中

1) 配置拦截器:<interceptors>...</interceptors>

2)注册拦截器:<interceptor...></interceptor>

3)注册拦截器栈:<interceptor-stack name="myStack">...</interceptor-stack>

4)指定拦截器:<default-interceptor-ref name="myStack"></default-interceptor-ref>

5) 配置全局结果集,避免对每个Action都配置。<global-results>...</global-results>

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
	"http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
	<constant name="struts.devMode" value="true" />
	<constant name="struts.enable.DynamicMethodInvocation" value="true" />
	<package name="fourm" namespace="/" extends="struts-default">
		<!-- 配置拦截器 --> 
		<interceptors>
			<!-- 注册拦截器 -->
			<interceptor name="UserIntercept" class="com.xm.web.intercept.UserIntercept"></interceptor>
			<!-- 注册拦截器栈 -->
			<interceptor-stack name="myStack">
				<!-- 引入自己的拦截器 -->
				<interceptor-ref name="UserIntercept">
					<param name="excludeMethods">login</param><!-- 不拦截该请求 -->
				</interceptor-ref>
				<!-- 引入struts自带的拦截器 -->
				<interceptor-ref name="defaultStack"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		<!-- 指定默认拦截器栈 -->
		<default-interceptor-ref name="myStack"></default-interceptor-ref>
		<!-- 配置全局结果集 -->
		<global-results>
			<!-- 重定向 -->
			<result name="toLogin" type="redirect">/login.jsp</result>
		</global-results>
		
		<global-allowed-methods>regex:.*</global-allowed-methods>
		<action name="UserAction_*" class="com.xm.web.UserAction" method="{1}">
			<!-- 转发到Action -->
			<!-- <result name="getAllPaste" type="chain">PasteAction_getAllPaste</result> -->
			<!-- 重定向到Action -->
			<result name="getAllPaste" type="redirectAction">PasteAction_getAllPaste</result>
			<!-- 转发 -->
			<result name="login">/login.jsp</result>
		</action>
		<action name="PasteAction_*" class="com.xm.web.PasteAction" method="{1}">
			<result name="index">/index.jsp</result>
		</action>
	</package>
</struts>

三、其他内容

(一)Struts2注解开发(现阶段主流)

1. xml文件与注解互换

@Namespace来代替<package  namespace=””>

@ParentPackage来代替<package extends=””>

@Action来描述关于<action>配置

value属性<action name=””>

使用@Action的results来描述关于结果类型的配置<result>

<result name=”” type=””>

@Action(results={@Result(name=””,type=””,location=””)})

2. 其他注解

@Actions

作用:可以通过多个映射来访问同一个action;

@Results

类似于全局的结果视图;

@InterceptorRef

它是用于处理拦截器的。

(二)OGNL表达式

OGNL是Object-Graph Navigation Language(对象图导航语言)的缩写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。

Struts2框架内置了OGNL,OGNL本身也是一个项目,它是可以单独使用。

OGNL作用:

支持对象的操作,调用对象的方法;

支持静态成员访问;

支持赋值操作与表达串联;

访问OGNL上下文,访问ActionContext;

操作集合对象。

Strtus2框架中如何使用ognl表达式

在struts2框架中我们使用ognl表达式的作用是从valueStack中获取数据,在struts2框架中可以使用ognl+valueStack达到在页面(jsp)上来获取相关的数据,要想在jsp页面上使用ognl表达式,就需要结合struts2框架的标签<s:property value=”表达式”>来使用。 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值