1. struts2中获取servletapi, 获取servletactioncontext.getrequest();
2 .采用注入的方式: java类实现servletrequestaware 接口, 可获取request对象.
执行流程, 请求被拦截器拦截,有一个默认的servletcofig拦截器,这个拦截器中可以动态的判断action类
哪个实现了servlet...aware接口, 然后注入给他的setservlet...(传一个对象的引用);
3.OGNL表达式: 三要素,表达式 ,上下文,根
1.获取上下文对象 new OgnlContext, 2 . 获取根1.getroot(); 3 Ognl.getvalue("对象",1,2);
4.静态成员访问: 1.getvalue("@java.lang.Math@静态方法或属性",1,2);
4.访问OGNL上下文:
1 -- 向上下文中存数据 3.1.put("username","tom");
2. Ognl.getvalue("#username",3.1,3.2); 这个地方如果不加#号,就是从根中获取, 你要把map或user对象
setroot(map)才能获取,否则就要加#号
3.操作集合 Ognl.getvalue("{1,2,3,4}",1,2);相当于创建list集合 #{'username':'tom'}创建了map集合
getvalue("username='sfds',age=34")注意这是root,要先setroot(),支持赋值和串联,
5.struts2用OGNL表达式获取valuestack中获取数据,从而达到在页面(jsp)上获取相关的数据.
要想在jsp使用OGNL表达式, 导入标签库, uri="/struts-tags" prefix="s"
然后<s:property value="字符串.length()">
6.栈: 先进后出 valueStack 值栈 ,是一个容器,将数据带到jsp页面上. 设计成一个接口了.
实现类为Ognlvaluestack,
1.struts2中的action是一个多例的,每一次请求都是一个新的action,所以不存在线程安全问题,
每一个valuestack对应一个action, 贯穿整个action声明周期. 从request域中获取valuestack.
7.valuestack 内部结构: 有两部分
1. root 是一个list集合 : 存储action相关数据,
2. context 是一个map集合 :存储为web开发相关对象. parameters request, session ,aplication,
里面是map集合等
3.OGNL如果使用#就从Ognlcontext中获取,没有使用从root中获取.
8.获取valuestack的方式: 他存储在actioncontext中,actioncontext是通过getcontext在线程池里获取的.
1.request.getattribute(servletactioncontext.str...);
2.通过actioncontext来获取, actioncontext.getcontext().getvaluestack()
actioncontext是绑定到线程中, 是每一次请求都会重新创建的
valuestack中分两部分,他的context部分,每次都会 ctx = new ActionContext(stack.getContext());
valuestack.getcontext(): 注意在context中持有root的引用.
9.一个request --- action - -- actioncontext---- valuestack(context(root(action))) stack.push(action);
ActionContext它是action上下文,strtus2框架它使用actionContext来保存Action在执行过程中所需要的一些对象
例如 session, application…
为什么会有这写对象呢?因为它里面有valustack,valuestack中context存储的是对象的map
ActionContext的获取 是通过它的静态方法getContext()得到。
Struts2会根据每一次的http请求来创建对应的ActionContext,它是与当前线程绑定的。getcontext方法是从线程池 里面来获取ActionContext对象的
每一次请求,就是一个线程,对应着一个request,每一次请求,会创建一个Action,每一个action对应一个 ActionContext.每一次请求也对应着一个valueStack.
request---ActionContext----Action-----ValueStaci它们都对应着一次请求(一个线程).
valueStack与ActionContext本质上是可以获取
10.valuestack 存储数据
1.手动存储.向root中存储
stack.push("Object o"); 向root中存储
stack.set("",""); 底层会创建一个hashmap,保存数据,把集合存储到root中.
2.自动向root中存储. 每次请求,都会把action放入到stack.push中;
a. 会将当前的action对象存储到valuestack中 stack.push(action);在defaultactioninvocation.init方法内
b.如果action实现了modeldriven接口(模型驱动),他会把模型对象存进valuestack中
11. 在jsp页面获取数据
1. 手动存的数据:
<s:debug> 可以作为调试用. 取出set里面的数据,set的是map集合直接 <s:property value="map的key">
而取出push()里面的数据,要清楚他是在栈空间内
怎么存的,先存的在底部,最底部是一个action, 坐标是从上往下变大的. 要去 某个值 直接[坐标].top
2.自动存的数据:
他是调用get方法, 直接value="get后面的小写属性";也是存储在root中
3.实现modeldriven接口的模型类;
在execute()方法中重新new user();这里不会有模型驱动或者属性驱动,因为这两种驱动只是封装属性的,
而现在在那个方法内直接用set属性的方式,所以他不会有驱动的事情,只会走个getModel方法.
而第二个对象取值要jsp页面中value="model.成员属性" 这里model只是在action类中,有一个
getmodel方法内是得到user对象的, 所以用model.成员属性;
4.EL表达式可以从valuestack中获取数据
struts2对request方法进行增强了.如果在request域中获取不到,就在valuestack中获取
attribute = stack.findValue(key);
5.debug中为什么自己设置的user对象是存储在actionstack中的,是因为通过model方法获取的,model方法是在
action中的.
12. OGNL中 #是从不是root中获取数据 , % 和 $符号;
1. #parameters.username 获取地址栏请求参数
2. %号用法: value=" %{会解析OGNL}" value=" %{'不会解析'}"
3.$ 号用法: ${model.username} 可以在值栈中获取值. 注意是:在struts.xml中!!!! 有中文限制
13.在开发中一般继承actionsupprot类, 可以使用父类提供对于错误操作的处理方法,
addactionError("密码错误"); addfielderror();进行错误信息的校验
addactionmessage();同时配置了,只会取出最后一个;
在jsp页面可以使用对应的标签 <s:actionerror/>
14.展示商品集合信息:
1. 在动作类中,可以提供getproduct(),和setproduct()方法,会自动存储到valuestack中
2. 在动作类中,手动存到值栈中
在jsp页面中:
1. <s:iterator value="存的集合名" var="每一个数值"> 每一个数值存在context里面,下面要用# ?
2. <s:iterator value="存的集合名" > 直接写属性名;
15.自定义interceptor拦截器
1. 实现interceptor接口
2.在配置文件中配置自己的在package标签中<interceptors>
<interceptor name class>
<interceptor-stack name="mystack">
<interceptor -ref name "自己定义的">
<interceptor- ref name="defaultstack">
3.在action配置中<action><interceptor- ref name="mystack">
4.注意:当我们显示的引入了一个自定义的Interceptor,那么默认的defaultStack就不会在导入,需要手动 导入。
5.如果登陆放行: return invocation.invoke()
在拦截器中,获取action invocation.getaction();
获取到实现actionsupport接口, 然后就可存储错误信息.
6.使用通配符可以拦截多个方法,但如果只拦截一个方法,自定义需要继承methodfilterinterceptor;
在配置时<interceptors>
<interceptor name class> <Param name="includemethods" >放行的方法名
<Param name="excludemethods" >不放行的方法
<default-interceptor-ref name="mystack">
16.存储数据在valuestack中就三个地方: 1.在root中存储 2.在context中存储 3.在action类中的get方法中
相对应取值的三种方法 root直接取, context加#号取, 类中的加方法名.取值
17. 拦截器拦截请求后,会创建一个action的代理对象,代理会调用execute()方法,会调用invocation的invoke方法,
在invoke方法内,会遍历所有的拦截器,然后去执行intercept方法,在方法内又会执行invocation.invoke.这样就会
不断的递归调用拦截器,而请求拦截一遍,响应又拦截一遍.
例如: params拦截器,当请求参数被拦截器拦截的时候,他就会获得所有的参数,然后,他是被action代理对象调用的
然后就会知道action对象,然后就会封装了参数.
1.文件上传: 浏览器三要素, 服务器端: commons-fileupload.jar fileuploadinterceptor拦截器
1. 继承模型驱动类, 创建 file, contenttype , filename, 成员属性, 在execute方法内将文件copy就可上传.
2.命名规范: file 属性命名: jsp页面name, jsp name+Contenttype , jsp name+FileName ; 这里name自定义的
3.为以上属性提供get,set方法.
在方法内, io工具类:fileutiles.copyfile(upload,new file(servletcontext.getrealpath(/upload));
4.注意事项: 文件上传有限制大小,在default.properties中,有一个struts.multipart.maxsize=2M;
1.在struts2 中配置常量,改变值就可以了.这是对整个工程设置
2. 针对某个action设置 在action下,设置拦截器标签<interceptor-ref name="fileUpload">
<param name="maximumsize"> <param name="allowedextensions">设置类型, 还要引入默认的拦截器;
3.上传时如何允许上传多个: 可以在action类中,把三个成员属性设置成集合或数组.在方法内循环数组,完成文件 上传 , 还有就是在jsp中name名称一致;
2. 如果拦截器出现问题,会把错误信息存在action, 然后跳到指定的input视图.可以自定义一个error.jsp,
然后在struts.xml中配置 result标签的name="input";就会把错误信息显示到.
将.jsp中两个标签,<s:fielderror> ,<s:actionerror>
<interceptor-ref name="workflow">
<param name="excludeMethods">input,back,cancel,browse</param>
</interceptor-ref>
3. json数据格式: 对象和数组可以互相嵌套.
* 1.fastjson json工具在json和java之间转换, JSONobjct.toJSONString(对象); JSONArray.toJSONString(集合);
1. 以上解决日期格式: 注解@JSONField(format="yyyy-mm-dd"); 阿里独有的注解
2. 处理不想要的属性JSONobjct.toJSONString(对象,new propertyfilter(
重写 apply(要转换成json的对象,属性名称,属性值){
if属性名称.equal() return false;
}));
2. 另一种jackson 工具类, 导入jar包,new ObjectMapper.writevalueasstring(对象或数组);重载的方法特别多
mapper.writeValue(ServletActionContext.getResponse().getWriter(), 对象或数组);
1. 解决日期: mapper.setDateFormat(new Simpledatformat());设置日期格式器;
2. 过滤属性: 注解@JsonIgnoreproperties({"属性1","属性2"})在类上面;这是使用这个类的全部过滤
处理一个类的过滤属性 mapper.setfilter(new simplefilterprovider.addfilter(
注解的自定名 ,simplebeanpropertyfilter.serializeallexcept(不想要的属性1,...)));
在类上加注解@JsonFilter("自定义名")
4.当出现死循环转换时候, 例如订单关联客户,客户关联订单, 当转客户为json格式时候,
1.除了fastjson,都会内存溢出;
如果关闭fastJson,JSON.toJSONString(customer,SerializerFeature.DisableCircularReferenceDetect)
不想用哪个属性, @JSONField(serialize=false) 在这个属性上面private Customer c;
2.其他工具内存溢出解决,直接不要那个属性了,加注解@JsonIgnore
5.struts.xml分文件, <include file="..xml"/>
6.struts2处理ajax请求.创建一个result类, 两个属性: 描述是否可用,错误信息; 把result类转换为json
mapper.writervalue( response.getwriter,result);注意解决乱码;
js代码中eval("("+data+")")将data转为js对象;括号一定要加;
7. struts2框架的json插件. 导入jar包,将struts.xml <package extends="json-defalut">
action的返回视图<result type="json"> , struts2框架就会将valuestack的"栈顶"元素转为json格式.
响应到浏览器,所以不用response转为json了,只需要把集合或对象压入栈顶就可以了.
8.关于响应json的处理, 忽略属性 : 在jsonresult类中有两个属性; includeproperties包含 不包含exclude....
在struts.xml中 的result标签下,设置root,<param name="root">ps 这样会把ps后面的[]取出来;
<param name="excludeproperties">\[\d+\]\.属性名 要把[] 转义 所以 \[\]
javascript:void(0); 相当于#;
9.注解开发;
导入convention-plugin-2.3.24.jar包, 2.1版本以后才能
1.在类上面@Namespace("/") 相当于namspace="/" @parentPackage("struts-defult")
2.在方法上面@action(value="hello",results={@result(name="" ,type="",location=".jsp")})
10.在类上面:actions: 可以用过多个映射来访问同一个action. results : 全局返回视图
他默认只会扫描包名为action,actions,sturts,staurts2. 类名: Action结尾:
如果别的名字,就需要在xml中配置常量 name="struts.convention.package.locators" action.suffix类名
struts2进阶
最新推荐文章于 2019-05-01 02:15:29 发布