前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SSH框架之Struts2第三篇

SSH框架之Struts2第三篇

作者头像
海仔
发布2019-09-18 14:43:39
3470
发布2019-09-18 14:43:39
举报
文章被收录于专栏:海仔技术驿站

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://cloud.tencent.com/developer/article/1508660

代码语言:javascript
复制
1.3相关知识点 :
		1.3.1 OGNL的表达式 :
			1.3.1.1 什么是OGNL
				OGNL是Object-Graph Navigation Language的编写,它是一种功能强大的表达式语言,通过它简单一致的表达式语法,可以存取对象的
				任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能.它使用相同的表达式去存取对象的属性.
				
				OGNL : 对象导航语言,是一门功能强大的表达式语言(功能比EL强大很多倍).Struts2将OGNL引入到自身,作为Struts2的表达式语言.
				struts2的默认表达式语言就是 : ognl
			1.3.1.2 OGNL的作用 :
				1 : 获取对象的方法;
				2 : 获取类的静态属性;
				3 : 获取类的静态方法;
				
				ognl快速入门 : 
					<!-- ognl简单使用 -->
					<!-- 1 获取对象的方法(了解)-->
					字符串hello的长度是: <s:property value="'hello'.length()"/><br/>
					<!-- 2 获取类的静态属性(了解)  要求:@类的全限定名@静态属性 -->
					π的值是:<s:property value="@java.lang.Math@PI"/><br/>
					<!-- 3 获取类的静态方法(了解)  要求: 1 @类的全限定名@静态方法   2 需要开启允许获取类的静态方法-->
					获取一个随机数:<s:property value="@java.lang.Math@random()" /><br/>
				
			1.3.2.1 在Java环境中使用
					public class OgnlDemo1 {

					@Test
					/**
					 * OGNL调用对象的方法:
					 */
					public void demo1() throws OgnlException{
						OgnlContext context = new OgnlContext();
						Object value = Ognl.getValue("'helloworld'.length()", context, context.getRoot());
						System.out.println(value);
					}
					
					@Test
					/**
					 * OGNL调用对象的静态方法:
					 * @包名.类名@属性/方法
					 */
					public void demo2() throws OgnlException{
						OgnlContext context = new OgnlContext();
						Object value = Ognl.getValue("@java.lang.Math@random()", context, context.getRoot());
						System.out.println(value);
					}
					
					@Test
					/**
					 * 获得Root中的数据:获取root中的数据不需要加#
					 */
					public void demo3() throws OgnlException{
						OgnlContext context = new OgnlContext();
						User user = new User();
						user.setUsername("aaa");
						user.setPassword("123");
						// 向root中存入数据
						context.setRoot(user);
						
						// 获取root中的数据:
						Object username = Ognl.getValue("username", context, context.getRoot());
						Object password = Ognl.getValue("password", context, context.getRoot());
						System.out.println(username +"   "+password);
					}
					
					@Test
					/**
					 * 获取context中的数据:获取context中的数据需要加#
					 */
					public void demo4() throws OgnlException{
						OgnlContext context = new OgnlContext();
						context.put("name", "张三");
						Object value = Ognl.getValue("#name", context, context.getRoot());
						System.out.println(value);
					}
				}
				
				4 : 通过它获取值栈中的数据;
				
		1.3.3.1 值栈内容 : 后进先出
			值栈 : ValueStack
			
			是struts2提供的一个容器,用来存储数据的,这个容器的底层结果是栈结构,数据的特点 : 后进先出.
			当客户端每次发送请求到action,都会被前端控制器拦截,会在里面创建ValueStack(特点 : 访问一次创建一次,在action之前创建)
			创建完ValueStack后,会将页面的参数数据,request,session,servletContext域中的数据放在ValueStack中一份(注意 : 不是将域对象放进去,而是将域的数据放进去)
			所以 : ValueStack是伴随action一生的.
			
			ValueStack是一个接口,我们玩的是它的实现类 : ognlValueStack
		ValueStack的结构 :
			root区域 : list
			
			context区域 : map<String,Object>
				如下数据  	key  			   value
						request 		request域中的数据(request域对象对应的map--地址引用)
						session 		session域中的数据(session域对象对应的map--地址引用)
						application 	ServletContext域中的数据(servletContext域对象对应的map--地址引用)
						parameters 		页面的所有参数数据(map)--request.getParameterMap();
						attr			(排好序的四个域的内容)
						
						root 			root区的地址引用
						
						Map=ActionContext.getParameters();
						Map=ActionContext.getSession();
						Map=ActionContext.application();
						
			ActionContext和valueStack有什么联系?
				当客户端每次发送请求到action,都会被前端控制器拦截,会创建ActionContext
				然后再创建ValueStack,并且会把创建封装好的ValueStack放在ActionContext中
			
		获取ValueStack
			1 : 通过ActionContext对象获取 :
				ActionContext.getContext.getValueStack();
			2 : 通过request域获取 :
				执行Action的过程中,将ValueStack存入到request域中,key是struts.valueStack.相当于request.setAttribute("struts.valueStack",valueStack);
					通过request对象获取 :
					ValueStack valueStack2 = (ValueStack)ServletActionContext.getRequest().getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY);
				
			
				
		操作ValueStack
			往ValueStack的root区域存数据 :
				默认会将你当前访问的action装进list中.
				
				1 : API的方式 :
					push(Object obj) push对象
						push(user) ---直接将user放在了list里面
					set(String key,Object value) set集合
						底层会创建一个map集合,将set的key和value给map的key和value
						最后把这个map集合放在list里面
						// 往值栈的root区域set数据  底层会创建一个map集合,将set的key和value放在map的key和value上,然后将整个map给list(root区域)
						//但是在DeBug里面会显示这个map集合为空,因为在root底层的list没有get方法,所以在DeBug显示不出来map集合里面的值.
					在jsp页面通过ognl的方式获取值栈中root区域的数据 :
						<h2>获取push到root区域的数据</h2>
						<s:property value="username"/><br/>
						<s:property value="age"/><br/>
						<s:property value="age123"/><br/>
						<hr/>
						<h2>获取set到root区域的数据</h2>
						<s:property value="list[0]"/><br/>
						<s:property value="list[1]"/><br/>
						<s:property value="list[2]"/><br/>
						<s:property value="list[111]"/><br/>
					
					根据root区域的属性从上到下获取,如果获取到了直接返回,如果获取不到,会去context区域里面找
				2 : action的属性方式 :
					默认action的成员属性数据都会在root区域中.
					因为默认会将你的当前访问action整个装进list中.
					
			往ValueStack的context区域存数据 :
				获取到context区域 : 只要获取actionContext对象就相当于获取context区域 :
					actionContext acon = actionContext.getContext();
				怎么往session域中放数据?
					Map map = acon.getSession();
					map.put("msg1","session");
					map.put("msg1","session");
				怎么往servletContext域中放数据?
					Map map=acon.getApplication();
					map.put("msg2","servletContext中的数据");
					
				怎么往request域中放数据?
					acon.put("msg3","request域数据);
						相当于往整个context(大map集合)中存key和value
						当然,key为request的对应的value也会有一份.
				在页面通过ognl获取context区域数据 : 
					条件 : 要想直接获取context区域的数据,ognl表达式必须加#
					<S:property value="#session.msg1"/>
	
		ognl中的三个特殊符号 :	#	%	$
			#的作用 :
				1 : 获取context区域中的数据 
				2 : 可以手动构建一个集合
					<!-- 手动构建的list集合 -->
					<s:iterator value="{'aa','bb','cc'}" var="ll" >
						<s:property value='#ll'/>
					</s:iterator>
					<!-- 手动构建的map集合 -->
					<s:iterator value="#{'aa':'111','bb':'222','cc':'333'}" var="mm">
						<s:property value="#mm.key" />	---> <s:property value="#mm.value"/><br/>
					</s:iterator>
			% 的作用 :
				强制转换成ognl表达式 :
					<s:property value="list[0]" /><br/>
					
			$ 的作用:
				可以在配置文件中获取值栈的数据
				在Struts2的配置文件中使用OGNL表达式
			例如 :
				文件下载
				<action name=”download” class=””>
					<result name=”” type=”stream”>
						<param name=”Content-Dispostion”>attachment;filename=${fileName}</param>
				</result>
				</action>
				国际化
				message_zh_CN.properties
				welcome=您好:${#session.user.name}
				message_en_US.properties
				welcome=Hello:${#session.user.name}
1.1 Struts2的拦截器基本概念 :
		拦截器 : Interceptor
			只要客户端访问action.都会被前端控制器给过滤,在前端控制器中会执行一组拦截器,这些拦截器会帮助我们完成属性的封装,对象封装,上传的功能.
		拦截器链 : 就是将拦截器按一定的顺序联结成一条链.在访问被拦截的方法或字段时,拦截器链中的拦截器就会按之前定义的顺序被调用.
		
		拦截器和filter类似,区别 :
			1 : filter可以拦截所有的资源,是javaweb的内容..
			2 : Interceptor只能拦截action,是struts2的组成部分.
		拦截器的作用位置 : 
			在action执行之前和之后都拦截.
		拦截器还是AOP编程思想的具体体现形式 : AOP简单的说就是 :
			在不修改源码的基础上,已有的方法进行动态增强.
			在struts2中,拦截器它就是对我们的动作方法进行增强.(其实就是把重复性的代码提取出来,然后放到拦截器中,统一管理,统一调用)
	1.1.2
		struts2的执行流程 :
			简化版本 : 请求 ---> strutsPrepareAndExecuteFilte ---> 执行一组默认的拦截器 --- 自己的action ---> 根据结果逻辑视图找到对应的页面
			详细版本 :
			请求 --> StrutsPrepareAndExecuteFilter(doFilter) --> 判断访问的是否是action
					若是 : 往struts的核心走.
					若不是 : 直接放行.
			若是action --> 创建action的代理对象 --> actionInvocation(action执行类 : 真正干货的对象) --> 递归调用一组拦截器 --> 我们自己编写action
			
	1.2 自定义拦截器 : 看看struts2提供的默认拦截器
		步骤 :
			1 : 创建一个javabean,继承AbstractInterceptor;
			2 : 重点关注intercept方法,核心拦截方法;
			3 : struts.xml里面配置拦截器.
				<!-- 配置拦截器 -->
				<interceptors>
					<interceptor name="myInterceptor1" class="com.baidu.interceptor.MyInterceptor"></interceptor>
					<interceptor-stack name="myInterceptors">
						<interceptor-ref name="myInterceptor1"></interceptor-ref>
					</interceptor-stack>
				/interceptors>
				<default-interceptor-ref name="myInterceptors"></default-interceptor-ref>
				
			1 : 可以去继承AbstractInterceptor,也可以去实现Interceptor
				(重点)
				但是在工作中 : 我们一般是玩继承MethodFilterInterceptor
					好处 : 可以指定到某个方法上了
					<param name="excludeMethods">execute,save</param> 不拦截execute,save
					<param name="includeMethods">execute,save</param>拦截execute,save
					
	1.3 注解 
		1 : 导入struts2-convention-plugin-2.3.24这个包
		2 : 需要做注解的action,要在带有action,actions,struts2,struts名称包内.
		
	2.2 常用注解
		2.2.1 @NameSpace
			出现的位置 : 它只能出现在package上或者Action类上.一般情况下都是写在Action类上.
			作用 : 指定当前Action中所有动作方法的名称空间.
			属性 : 
				value : 指定名称空间的名称.写法和xml配置时一致.不指定的话,默认名称空间是"";
			例如 : @Namespace(value = "/")
				
		2.2.2 @ParentPackage
			出现的位置 :
				它只能出现在package上或者Action类上.一般情况下都是写在Action类上.
			作用 :
				指定当前动作类所在包的父包.由于我们已经是在类中配置了,所以无需指定包名了.
			属性 :
				value : 指定父包的名称.
			示例 : @ParentPackage("struts-default")
		
		2.2.3 @Action
			出现的位置 :	它只能出现在Action类上或者动作方法上.一般情况下都是写在动作方法上.
			作用 : 
				指定当前动作方法的动作名称.也就是xml配置时action标签的name属性.
			属性 :
				value : 指定动作名称.
				results[] : 它是一个数组,数据类型是注解.用于指定结果视图.此属性可以没有,当没有该属性时,表示不返回任何结果视图.即使用response输出响应正文.
				interceptorRefs[] : 它是一个数组,数据类型是注解.用于指定引用的拦截器.
			示例 :
				@Action(value="addUICustomer",results={
					@Result(name="addUICustomer",location="/jsp/customer/add.jsp")
				})
		
		2.2.4 @Result
			出现的位置 : 它可以出现在动作类上,也可以出现在Action注解中.
			作用 : 出现在类上,表示当前动作类中所有动作方法都可以用此视图.
			出现在Action注解中,表示当前Action可用此视图.
			属性 :
				name : 指定逻辑结构视图名称.
				type : 指定前往视图的方式 . 例如 : 请求转发,重定向,重定向到另外的动作.
				location : 指定前往的地址.可以是一个页面,也可以是一个动作.
			示例 : 
			@Action(value="addCustomer",results={
				@Result={name="addCustomer",type="rediect",location="/jsp/success.jsp"}
			})
				
		2.2.5 @Result
			出现的位置 :
				它可以出现在动作类上,也可以出现在Action注解中.
			作用 :
				用于配置多个结果视图.
			属性 :
				value : 它是一个数组,数据类型是result注解.
			示例 : 
				@Results({@Result{name="login",location="/login.jsp"},
						  @Result{name="error",location="/error.jsp"}
				})
		
		2.2.6 @InterceptorRef
			出现的位置 :
				它可以出现动作类上或者Action注解中.
			作用 :
				用于配置要引用的拦截器或者拦截器栈.
			属性 :
				value : 用于指定拦截器或者拦截器栈
			示例 :
				出现在动作方法上.
			@Action(vlue="findAllCustomer",results={
				@Result(name="findAllCustomer",location="/jsp/customer/list.jsp")
			},interceptorRefs={
					@InterceptorRef("myDefaultStack")
			})
		
		<FORM id=form1 name=form1 action="/day59_demo/user_find" method=post target="_parent">
		其中: target = "_blank" : 相当于另外创建一个; 默认的是target="_self" ; target="_parent" : 父类,表示回到以前的或者说是父页面.				
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年09月14日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档