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" : 父类,表示回到以前的或者说是父页面.

SSH框架之Struts2第三篇的更多相关文章

  1. SSH框架之Spring第三篇

    1.1 AOP概述 1.1.1 什么是AOP? AOP : 全称是Aspect Oriented Progamming既 : 面向切面编程.通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技 ...

  2. SSH框架之Hibernate第三篇

    1.1 多表关系分析和创建. 1.1.1 表关系分析和创建 表数据和表数据之间可以存在的关系? 一对多的关系 客户和联系人 建立关系原则: 在多的一方创建一个字段,这个字段作为外键指向一的一方的主键 ...

  3. SSH框架之Struts2第一篇

    1.2 Struts2的概述 : Struts2是一个基于MVC设计模式的WEB层的框架. 1.2.1 常见web层框架 Struts1,Struts2,WebWork,SpringMVC Strut ...

  4. 搭建SSH框架整合Struts2和Spring时,使用@Autowired注解无法自动注入

    © 版权声明:本文为博主原创文章,转载请注明出处 1.问题描述: 搭建SSH框架,在进行Struts2和Spring整合时,使用Spring的@Autowired自动注入失败,运行报错java.lan ...

  5. 吴裕雄--天生自然JAVA SPRING框架开发学习笔记:SSH框架(Struts2+Spring+Hibernate)搭建整合详细步骤

    在实际项目的开发中,为了充分利用各个框架的优点,通常都会把 Spring 与其他框架整合在一起使用. 整合就是将不同的框架放在一个项目中,共同使用它们的技术,发挥它们的优点,并形成互补.一般而言,在进 ...

  6. SSH框架之Struts2第二篇

    1.2 知识点 1.2.1 Struts2的Servlet的API的访问 1.2.1.1 方式一 : 通过ActionContext实现 页面: <h1>Servlet的API的访问方式一 ...

  7. J2EE进阶(十二)SSH框架整合常见问题汇总(三)

    在挂失用户时,发现userid值为空,但是在前台输入处理账号22时,通过后台输出可以看出,后台根据前端输入在数据库中查询到结果对象并输出该对象的userid,而且Guashi对象也获取到了其值. 解决 ...

  8. SSH开发模式——Struts2(第三小节)

    struts2框架的知识点,虽然分了几个小节,感觉内容还是挺多的,但是你仅仅是入门了而已,想要进一步地提升自己,你得有一颗持之以恒的学习的心,最后的内容我都将在这篇博客中讲到,所以篇幅可能会有点长,希 ...

  9. Struts2第三篇【Action开发方式、通配符、Struts常量、跳转全局视图、action节点默认配置】

    前言 上篇Struts博文已经讲解了Struts的开发步骤以及执行流程了-..对Struts的配置文件有了了解-..本博文继续讲解Struts在配置的时候一些值得要学习的细节- Action开发的三种 ...

随机推荐

  1. java之线程(线程的创建方式、java中的Thread类、线程的同步、线程的生命周期、线程之间的通信)

    CPU:10核 主频100MHz 1核  主频    3GHz 那么哪一个CPU比较好呢? CPU核不是越多越好吗?并不一定.主频用于衡量GPU处理速度的快慢,举个例子10头牛运送货物快还是1架飞机运 ...

  2. Openstack简述

    1.Openstack项目发展概况: Nova 计算服务 Swift 对象存储服务 Glance   镜像服务 Neturon 网络服务 Keystone   身份认证服务 Celimeter   计 ...

  3. 记MAC地址、磁盘序列号的获取

    import java.io.*; import java.net.Inet4Address; import java.net.InetAddress; import java.net.Network ...

  4. 【CV现状-1】磨染的初心——计算机视觉的现状:缘起

    #磨染的初心--计算机视觉的现状 [这一系列文章是关于计算机视觉的反思,希望能引起一些人的共鸣.可以随意传播,随意喷.所涉及的内容过多,将按如下内容划分章节.已经完成的会逐渐加上链接.] 缘起 三维感 ...

  5. Gradle-构建脚本

    构建语言 Gradle提供了一种领域特定语言,目前同时支持 Groovy 和 Kotlin . 在 Groovy 构建脚本中(.gradle) 你可以使用任何 Groovy 元素. 在 Kotlin ...

  6. JavaEE初学笔记之Servlet与Tomcat

    JavaEE开发,本质上就是开发一个个Servlet,然后部署到Servlet容器(如Tomcat)里运行.   1. Servlet是什么? Servlet就是一个普通的接口(Interface), ...

  7. 2019年腾讯PHP程序员面试题目分享

    有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群​jq.qq.com 1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除 ...

  8. .netcore3.0 System.Text.Json 日期格式化

    .netcore3.0 的json格式化不再默认使用Newtonsoft.Json,而是使用自带的System.Text.Json来处理. 理由是System.Text.Json 依赖更少,效率更高. ...

  9. 在 .NET Core 3.0 中支持 Newtonsoft.Json 的使用

    .NET Core 3.0 已经使用了一整套内置的 Josn 序列化/反序列化方案,而且看上去效率还不错.但对于某些项目必须使用到 Newtonsoft.Json 的时候,就会抛出如下异常: Syst ...

  10. SpringCloud之Feign 负载均衡请求超时时间

    版本声明: SpringCloud:Greenwich.SR4 SpringBoot:2.1.9.RELEASE Feign调用服务的默认时长是1秒钟,也就是如果超过1秒没连接上或者超过1秒没响应,那 ...