用户注册



邮箱:

密码:

用户登录


邮箱:

密码:
记住登录一个月忘记密码?

发表随想


还能输入:200字

jun    -  云代码空间

—— 相信 ,梦

strut2(4)

2014-08-12|1504阅||

摘要:1.ognl与valueStack(重点) 2.struts2标签库(了解) 3.关于表单重复提交(次重点) 4.json插件.(了解)



-------------------------------------------------------------------
1.ognl与valueStack

1.ognl 
Object Graphic Navigation Language(对象图导航语言)
ognl是一个开源项目

2.valueStack
我们学习它的目的:为了在视图上获取信息.

ValueStack本质上是一个接口.它的一个实现类OgnlValueStack。

每一次请求会创建一个Action,每一个Action有对应的一个valueStack。
valueStack会被存储在request中,名称叫  "struts.valueStack"

内部结构:
Map:context
CompoundRoot: root  CompoundRoot本质上是一个ArrayList。


context中存储的是:web常见对象
parameters: 该 Map 中包含当前请求的请求参数
request: 该 Map 中包含当前 request 对象中的所有属性
session: 该 Map 中包含当前 session 对象中的所有属性
application:该 Map 中包含当前 application  对象中的所有属性
attr: 该 Map 按如下顺序来检索某个属性: request, session, application

root中存储的是Action相关的信息

ValueStack与ActionContext关系

在ActionContext中持有ValueStack的引用.

怎样获取ValueStack
1.从request获取
ServletActionContext.getRequest().getAttribute("struts.valueStack");
2.从ActionContext获取
ActionContext.getContext().getValueStack();

向valueStack中存储(主要针对于root)

push()   list.add(0,obj);
set(String name,Object value) list.add(0,new HashMap());

获取root中数据,不使用#号.

[0].name  得到从第一个开始的一个子集,依次查找是否有name属性
[1].name  得到从第二个开始的子集,依次查找是否有name属性
[0].top.name  得到从第一个开始栈顶的元素是否有name属性
[1].top.name  得到从第二个开始的栈顶元素,是否有name属性.

--------------------------------------------------------------------------------
在jsp中获取值栈信息
<s:property value="#request.username"/><br>
  <s:property value="#session.username"/><br>
  <s:property value="#application.username"/><br>
  
  <s:property value="#attr.username"/>
  
================================================================================================
Action 向JSP 传递数据处理结果 ,结果数据有两种形式

1.消息数据
addFieldError();存储校验错误信息
addActionError(); 存储Action操作中的逻辑上错误信息
addActionMessage();Action中的信息.

在页面上可以通过
<s:fielderror/>  对于这个标签可以通过指定name属性来得到指定的信息
<s:actionerror/>
<s:actionmessage />

2.复杂数据
哪些数据默认会放入到值栈 ??? 
1.Action会被装入到值栈中.
2.对于Action中的属性,它们会在值栈中存在
3.使用modeldriven实现,对象也会被装入到valuestack中.

简单说:关于Action的相关信息都会被装入到ValueStack的root中。


为什么通过el可以获取root中的值?

${username}  page  request

在struts2框架中,对request对象进行了增强.当通过request对象去获取数据  getAttribute()如果得到不到,会从valueStack中查找.

StrutsPreparedAndExecuteFilter的doFilter代码中 request = prepare.wrapRequest(request);
* 对Request对象进行了包装 ,StrutsRequestWrapper 
* 重写request的 getAttribute 
Object attribute = super.getAttribute(s);
if (attribute == null) {
  attribute = stack.findValue(s);
}
 访问request范围的数据时,如果数据找不到,去值栈中找 
? request对象 具备访问值栈数据的能力 (查找root的数据)

------------------------------------------------------------------------------
ognl常见使用
#、 % 、$ 符号使用

#使用
root中数据获取不需要使用#。不是root中的数据获取使用#

<s:property value="#request.username">


#request.username----->ActionContext.getContext().getRequest().get("username");


所#就相当于ActionContext.getContext();

进行投影映射 (结合复杂对象遍历 )


1)集合的投影(只输出部分属性
  <h1>遍历集合只要name属性</h1>
<s:iterator value="products.{name}" var="pname"> 
<s:property value="#pname"/>
</s:iterator>
  2)遍历时,对数据设置条件 
<h1>遍历集合只要price大于1500商品</h1>
<s:iterator value="products.{?#this.price>1500}" var="product"> 
<s:property value="#product.name"/> --- <s:property value="#product.price"/>
</s:iterator>
  3)综合
  <h1>只显示价格大于1500 商品名称</h1>
<s:iterator value="products.{?#this.price>1500}.{name}" var="pname"> 
<s:property value="#pname"/>
</s:iterator>   


用法四: 使用#构造map集合 
经常结合 struts2 标签用来生成 select、checkbox、radio
<h1>使用#构造map集合 遍历</h1>
<s:iterator value="#{'name':'aaa','age':'20', 'hobby':'sport' }" var="entry">
key : <s:property value="#entry.key"/> , value:  <s:property value="#entry.value"/> <br/>
</s:iterator>
--------------------------------------------------------------------------
%用法
就是通知当前是否是一个ognl表达式.

%{表达式} 那么将表达式做为ognl表达式处理.

%{'表达式'} 将表达式以原样输出,就是不当它为ognl表达式.

对于struts2中的表单标签,它的value值,默认都是文本,如果想要通过ognl表达式来赋值,必须使用%{};

<s:property>它不是表单标签.

------------------------------------------------------------------------------
$用法
1.国际化文件中可以使用
username=${#request.username} 可以    $将数据从request中获取到username
username=%{#request.username} 可以    %它的作用是将内容以ognl表达进行解析

在页面上
<%
request.setAttribute("username", "llllll");
%>


<s:i18n name="cn.itcast.action.message">
<s:text name="username"></s:text>
</s:i18n>



2.在配置文件中使用

<result type="stream">
<param name="contentType">${contentType}</param>
<param name="contentDisposition">attachement;filename=${filename}</param>
<param name="inputStream">${inputStream}</param>
</result>

当访问action时,action会被压入到valueStack。在action中的getXxx方法在root中有对应的值.
getContentType();
getFilename()
getInputStream();

当使用${contentType}时会在valueStack 中查找contentType,就会调用action中的getContentType方法.


结论: #用于写ognl表达式获取数据,% 控制ognl表达式是否解析 ,$ 用于配置文件获取值栈的数据


-------------------------------------------------------------------------------------------
struts2的标签库(了解)
使用struts2标签必须先在web.xml文件配置filter

struts2分成两部分
1.generic Tag
ctrl tag


1.if  else if else
注意在使用时要对属性test赋值(boolean值)

2.iterator 遍历集合
<s:iterator value="集合" var="迭代的元素名称">

注意:var的值它在root中不存在。要想获取必须使用#来获取.

3.url
<s:url action="" namespace="" method="" var="" value="">
action代表要访问的action的name值
namespace代表要访问的struts.xml文件中namespace值

var起个名称
method代表的是访问的方法名称
value:如果有这个值,我们可以不用action与namespace,value的值直接就是namespace+action的name值就可以。
4.a
<s:a href="">
href值可以直接引入一个<s:url>的值.

<s:a action="" method="" namespace="">


注意:对于url与a标签都可以使用<s:param>这个标签来带参数.
<s:param name="" value="">  对于value属性,它的值,默认是ognl,如果只是一个常量 ,可以通过%{'值'}来控制.


5.set
<s:set var="username" scope="request" value="%{'李四'}"></s:set>
相当于
request.setAttribute("username","李四");

注意:对于这些非表单标签,它的value值,一般都会认为是ognl。



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

2.ui tag
form tag

对于struts2表单标签,它默认情况下是使用table对格式进行了控制.

在<s:form>这个标签中有一个属性 theme这个属性默认值为xhtml,它采用的是struts-core jar包下的template下的xhtml模板.

对theme这个属性,如果只在<s:form>上使用,它代表的是只对当前这个表单有效.

还可以在表单的标签上使用

还可以在struts.xml文件中通过常量来配置
<constant name="struts.ui.theme" value="simple"></constant>

对于<s:password>这个标签,它默认情况下是不回显的。

struts标签优点:回显方便

-------------------------------------------------------------------------------------------------
表单重复提交
表单防止重复提交 
表单重复提交 危害: 刷票、 重复注册、带来服务器访问压力(拒绝服务)

怎样防止表单重复提交:采用令牌技术
jsp:
页面:生成一个随机字符串(uuid)
将生成的uuid存储到session中.
表单在提交时,将uuid值也带到了服务器端<input type="hidden">

服务器:
从request中获取uuid,在从session中获取uuid。
对比一样,完成操作. 从session中将uuid删除。

当重复提交表单时,session中的uuid已经没有了,那么我们就知道,它在做重复提交.


struts2:


页面:
在表单中添加一个struts2的标签  <s:token/>

服务器端
action类中不用做特殊处理.

在struts.xml文件中配置.

因为struts2的表单重复提交是通过tokenInterceptor拦截器完成。

<action name="login" class="cn.itcast.action.LoginAction">
<result>/tag/2.jsp</result>
<result name="invalid.token">/index.jsp</result>
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="token"/>
</action>

在页面上可以通过<s:actionerror>得到错误信息.
国际化:在Action所在的包下创建一个properties文件
struts.messages.invalid.token=您已经重复提交表单,请刷新后重试

---------------------------------------------------------------------------------------------------
struts2对ajax支持

1.使用ajax向action发送请求,action返回一个字符串.

页面:
//1.得到XMLHttpRequest对象


var xmlhttp = createXMLHttpRequest();


//2.设置回调函数


xmlhttp.onreadystatechange = function() {


//5.处理操作
if (xmlhttp.status == 200 && xmlhttp.readyState == 4) {


alert(xmlhttp.responseText);


}


};


//3.open
xmlhttp.open("GET", "${pageContext.request.contextPath}/ajax1");


//4.send
xmlhttp.send();



action处理
ServletActionContext.getResponse().getWriter().write("hello world");


-------------------------------------------------------------------------------------------------
struts2与ajax整合时它提供一个json插件包
struts2-json-plugin-2.3.15.1.jar包
将这个jar包复制到lib下.

在这个jar下有一个struts-plugin.xml文件,这个xml文件会在我们的struts.xml文件之间加载 。

如果使用这个jar包,两个注意事项:
1.在自己的struts.xml文件中 <package name="default" namespace="/" extends="json-default">
2.在<result>中它的type值必须是json  <result type="json"></result>

通过示例发现:action中的属性,会被默认的封装成json数据响应到浏览器端.



如果想对action中的属性,不封装到json中可以通过   @JSON(serialize=false)添加到getXxx方法上.

示例1:判断用户名是否重复
顶 0踩 0收藏
文章评论
    发表评论

    个人资料

    • 昵称: jun
    • 等级: 资深程序员
    • 积分: 1523
    • 代码: 94 个
    • 文章: 24 篇
    • 随想: 0 条
    • 访问: 7 次
    • 关注

    最新提问

      站长推荐