struts基础2
Result配置详解
说明:在前面的许多案例中我们所用到的Action基本都继承自ActionSupport这个类,而在这个类中我们定义了五个字段:SUCCESS,NONE,ERROR,INPUT,LOGING。我们可以直接返回这些字段值,这些字段值实质是被定义成:String SUCCESS=”success”这样的形式,所以我们只要在Result元素中用它们的小写即可。
<result>标准完整形式如下:
<result name="success" type="dispatcher">
<param name="location">/default.jsp</param>
</result>
如果我们都采用默认的形式,最终可以简写成:<result>/default.jsp</result>
探讨type类型:
Type类型值 作用说明 对应类
chain 用来处理Action链 com.opensymphony.xwork2.ActionChainResult
dispatcher 用来转向页面,通常处理JSP org.apache.struts2.dispatcher.ServletDispatcherResult
redirect 重定向到一个URL org.apache.struts2.dispatcher.ServletRedirectResult
redirectAction 重定向到一个Action org.apache.struts2.dispatcher.ServletActionRedirectResult
plainText 显示源文件内容,如文件源码 org.apache.struts2.dispatcher.PlainTextResult
freemarker 处理FreeMarker模板 org.apache.struts2.views.freemarker.FreemarkerResult
httpheader 控制特殊http行为的结果类型 org.apache.struts2.dispatcher.HttpHeaderResult
stream 向浏览器发送InputSream对象,通 org.apache.struts2.dispatcher.StreamResult
常用来处理文件下载,还可用于返回AJAX数据。
velocity 处理Velocity模板 org.apache.struts2.dispatcher.VelocityResult
xslt 处理XML/XLST模板 org.apache.struts2.views.xslt.XSLTResult
以上对type类型作简要的说明,下面来看实例:当一个Action处理后要返回的Result是另一个Action时,作如何配置,关键就是配置type类型。下面建立struts2result项目说明 步骤一:建立两个Action:TestAction、Test2Action
步骤二:web.xml配置省略。struts.xml主要配置内容如下:
<struts> <package name="resultTest" extends="struts-default"> <action name="test" class="com.asm.TestAction"> <result name="success" type="chain">
<param name="actionName">test2</param>
</result>
</action>
<action name="test2" class="com.asm.Test2Action">
<result name="success">/test2Suc.jsp</result>
</action>
</package>
</struts>
说明:在名为“test”的action中,我们配置result元素的type类型值为chain,意为将继续把Action传递到下一个名为test2的Action中去,在test2.action中会把页面转向到test2Suc.jsp中去。在type类型为chain时,它的param有4个值可配,除了这里用到的name=”actionName”外(必须配置,否则报错),还有name=namespace|method|skipActions。其中namespace指定要转向到action的名字空间,由于此处是转到Action位于同一个namespace下,而namesapace的默认值the current namespace,所以可以省略不写(需要说明的是如果要跳到别的名称空间的action中去,除了使用namespace指定外,还可以用:/要跳去action所在名称空间的值/要跳去的action的name值)。Method用于指定转向到一个目标action所调用的方法,默认是调用下一个action的execute方法,所以此处仍可以省略。SkipActions是一个可选的属性,一般不用。具体可以参看chain所对应类的api帮助。
在本实例中,我们还在TestAction中设定一个username字段,并在execute方法执行为它赋了值,并在test2Suc.jsp中引用了此值。其实这种做法在web开发中还是很有用处,比如可以代替隐藏域。需要注意的是之所以在action的传递中能把设定的这个值保存下去,主要是因为转向都是服务器跳转。如果我们跳转时采取了客户端跳转,比如在test2 action的result中指定type类型为redirect,要想传递参数可以在result指向的jsp页面中附加参数即可,我们可以在test2 action的result中写成:
<result name="success" type="redirect">
/test2Suc.jsp?username=${username}
</result> 随后在test2Suc.jsp页面中引用时会出现三个问题:1.EL表达式引用失效,(EL表达式
应该使用${param.username}形式)。我们也可以使用<%=request.getParameter("username")%>获取参数值。 2.由于在前面的TestAction中设定的值为中文,而附加到这里的uri请求的参数后面时会出现乱码问题。(可以使用URI编码再解码解决此问题)3.值栈取值失效:因为每一次request共享同一个值栈,所以服务器端的forward跳转也是能共享同一值栈得。但是着当test action执行后把请求交由test2 action时,test2 action采取的是redirect重定向到test2Suc.jsp页面,这时其实就是重发的一次request,所以在test action保存的值栈内容全部失效。这也就是为什么我们要附加参数的原因。而参数是保存在actionContext中,所以采用了#的方式来取出值。图示说明:
步骤三,编写链接页面index.jsp。发布测试:
全局result:
如果我们所有的action均有可能跳到相同的页面,则不防使用全局result。为了方便引用我们专门建立一个package来存放公共的result。在会用到个全局的跳转时,只需要把继承自这个公共的package即可。 建立公共包,代码如下:
<package name="pubResult" extends="struts-default" abstract="true"> <global-results>
<result name="error">/error.jsp</result>
</global-results>
</package>
由于它下面没的action配置,所以我们可以像默认的struts-default包一样,声明abstract=true,这样声明表示此packgage下不会有action,它一般是用来让别的package继承。随后再在要用到全局result中引用这个公共的package。代码如下:
<package name="testGlobal" extends="pubResult" > <action name="error" class="com.asm.ErrorAction"></action>
<action name="error2" class="com.asm.Error2Action"></action>
</package>这样操作相当于把全局的result加到了此package下的所有action中去。
异常处理
步骤一、建立struts2exception项目下,在该项目下建立登录页面login.jsp。主要代码如下:
<form action="<%=request.getContextPath() %>/login.action"> username:<input type="username" name="username"><br>
<input type="submit" value="login">
</form>
步骤二、建立LoginAction,代码如下:
package com.asm;
public class LoginAction extends ActionSupport { private String username;
public String execute() throws Exception { if (username.equals("exception")) {
throw new ClassNotFoundException("类未被找到"); } else if (username.equals("global")) { throw new Exception("全局异常"); } else { return SUCCESS;
}
}
...省力get/set方法 }
步骤三、struts.xml配置文件如下:
<struts> <package name="ex" extends="def"> <action name="login" class="com.asm.LoginAction"> <exception-mapping result="myException"
exception="java.lang.ClassNotFoundException"> </exception-mapping>
<result name="myException">/exception.jsp</result>
<result name="success">/main.jsp</result>
</action>
</package>
<package name="def" extends="struts-default" abstract="true"> <global-results>
<result name="myGlobal">/globalException.jsp</result>
</global-results>
<global-exception-mappings> <exception-mapping result="myGlobal"
exception="java.lang.Exception">
</exception-mapping>
</global-exception-mappings>
</package>
</struts>
分析:异常处理机制较为简单,所以在此只略作说明。当登录时输入“exception”时,在LoginAction中会抛出会一个ClassNotFoundException异常,此异常我们采取的局部异常处理的方式,如果登录时输入“globla”,则会抛出Exception异常,此异常我们采取的是全局异常的处理方式,在ex包中我们继承了全局异常所在的包。提示:<exception-mapping>中的result属性的值来源于<result>元素中的name属性的值。从实例可以看出,我们一般把这种全局性的异常放在一个抽象包中供其实包继承。
在Action获取Scope对象
引言:在前面的Action操作中,关键就是Action中的exectue方法,但是此方法并没有request、session、application等对象作为参数,自然就不能利用这些对象来操作。下面我们建立struts2scope项目,并用四种方式来获取这些对象:
方式一、与Servlet解耦合的非IOC方式
获取的scope对象与容器无关,通过ActionContext获取。 LoginAction代码如下:
package com.asm;
public class LoginAction extends ActionSupport { private String username; ActionContext context; Map request; Map session; Map application;
public String execute() throws Exception { context=ActionContext.getContext(); request=(Map) context.get("request"); session=context.getSession();
application=context.getApplication();
request.put("req", "requst属性"); session.put("ses", "sesion属性");
application.put("app", "application属性"); return SUCCESS;
}
...省略username的get/set方法 }
struts.xml配置如下:
<struts> <package name="scope" extends="struts-default"> <action name="login" class="com.asm.LoginAction">
<result>/loginSuc.jsp</result>
</action> </package>
</struts>
login.jsp内容如下:
<form action="<%=request.getContextPath() %>/login.action"> 用户名:<input type="text" name="username"><br>
<input type="submit" value="login">
</form>
loginSuc.jsp的主要内容如下:
${requestScope.req} ${sessionScope.ses} ${applicationScope.app}
<h4>以下使用scope.getAttribute的形式来接受</h4> request: <%=request.getAttribute("req") %><br>
session: <%=session.getAttribute("ses") %><br>
application:<%=application.getAttribute("app") %><br>
分析:通过ActionContext的getContext静态方法得到ActionContext对象,然后ActionContext对象调用get方法来获取一个存储在request范围中的对象。我们使用el或通过request.getAttribute这样的方式
均可以获取对象值,这说明了这些Map request对象实际是存储在request范围内的对象。 方式二、与Servlet解耦合的IOC方式 我们建立Login2Action,主要代码如下:
package com.asm;
public class Login2Action extends ActionSupport implements RequestAware,SessionAware,ApplicationAware { private String username; Map request; Map session; Map application;
public String execute() throws Exception { request.put("req", "requst属性"); session.put("ses", "sesion属性");
application.put("app", "application属性"); return SUCCESS;
}
public void setRequest(Map<String, Object> request) { this.request=request;
}
public void setSession(Map<String, Object> session) { this.session=session; }
public void setApplication(Map<String, Object> application) { this.application=application;
}
...省略username的get/set方法 }
注册此Action的name为login2,随后修改登录提交为.../login2.action。便可以发布测试。说明:此方法其实和方式一很相似,只是在方式一中我们需要手动的为Map request赋值,但是在方式二中它是通过实现接口,在重写接口中的方法中完成对Map requset的赋值,所以称之IOC方式。借助此例,略谈下依赖注入与控制反转:所谓依赖注入就是一个对象自己本身的初始化是依赖其它对象。比如这里Map request这些对象会依赖struts2来给其初始化,称为依赖注入,而依赖注入的就表示,这些对象的控制权不再由此类本身掌握,而是交给了别的对象,即是控制权反转了。 强调:方式二是开发中主要用的方式,应重点掌握
方式三、与Servlet耦合的非IOC方式 建立Login3Action,代码如下:
package com.asm;
public class Login3Action extends ActionSupport { private String username; HttpServletRequest request; HttpSession session;
ServletContext application;
public String execute() throws Exception { request = ServletActionContext.getRequest(); session = request.getSession();
application = ServletActionContext.getServletContext();
request.setAttribute("req", "requst属性"); session.setAttribute("ses", "sesion属性");
application.setAttribute("app", "application属性"); return SUCCESS;
}
...省略username的get/set方法。 }
此方法获取的纯粹的Scope对象,它与容器相关,这些Scope对象操作更强。同样只需要注册此Action并修改登录页面便可进行测试。 方式四、与Servlet耦合的IOC方式 建立Login4Action,代码如下:
package com.asm;
public class Login4Action extends ActionSupport implements ServletRequestAware,ServletContextAware{ private String username; ActionContext context; HttpServletRequest request; HttpSession session;
ServletContext application;
public String execute() throws Exception { context=ActionContext.getContext(); session=request.getSession();
request.setAttribute("req", "requst属性"); session.setAttribute("ses", "sesion属性");
application.setAttribute("app", "application属性"); return SUCCESS;
}
public void setServletRequest(HttpServletRequest request) { System.out.println("测试:"+request); this.request=request;
}
public void setServletContext(ServletContext application) { System.out.println("测试:"+application); this.application=application;
}
...省略username的get/set方法 }
同样只需要注册此Action并修改登录页面便可发布测试
OGNL与ValueStack(VS)
1.值栈入门
下面我们建立struts2ognl项目来练习ognl的使用。 步骤一、搭建strust2的开发环境
步骤二、建立LoginAction,主要代码如下:
package com.asm;
public class LoginAction extends ActionSupport{
private User user;
public String execute() throws Exception {
return SUCCESS;
}
...省略user的get/set方法 }
步骤三、配置此Action,struts.xml的主要内容如下:
<struts> <constant name="struts.devMode" value="true"></constant> <package name="ognl" extends="struts-default"> <action name="login" class="com.asm.LoginAction">
<result>/loginSuc.jsp</result>
</action>
</package>
</struts>
步骤四、编写login.jsp页面,主要代码如下:
<body> <form action="<%=request.getContextPath()%>/login.action" method="get"> 用户名:<input type="text" name="user.username"><br> 密 码:<input type="password" name="user.password"><br>
<input type="submit" value="login">
</form>
</body>
步骤五、编写loginSuc.jsp页面,主要代码如下:
<body>
调试:<s:debug></s:debug>
获取值栈中的username属性:<s:property value="user.username"/> <br> </body>
步骤六、发布测试及说明
当我们输入用户名并成功跳到logSuc.jsp页面后,会得到登录时输入的用户名信息。下面简要说明这一过程:
(1).login.jsp登录提交登录信息给login.action
(2).struts2监听到客户端的login.action请求,按配置文件要求,把此请求交给LoginAction处理。这表示会去new LoginAction(), 当struts2 new出此Action对象后会把这个对象放在context map中,只是这个Action非常特殊,所以放在值栈中,而放在值栈中的对象是可以直接引用的,放在其它context map中的对象引用时会要求加#。
(3).当new LoginAction时,表示它也会初始化此类中的对象,比如这里会去初始化User对象,但是要注意的是如果我们在用户名和密码什么都不输,再来用debug来看值栈中的user是,发现它仍会new此对象,因为尽管我们没用输入值,但是后台的set方法还是要被调用,所以会new出此对象,但是如果我们直接输入.../struts2ognl/login.action时我们会发现跳转到loginSuc.jsp页面时,用debug来看值栈中此User user,发现它的值为null。第二点要注意的是我们必须为User类提供默认的构造方法,否则将会出现如下错误: java.lang.InstantiationException: com.asm.vo.User 总结:1.Action会在请求时被创建,且会把创建的对象放到值栈中。
2.Action中的对象字段只有在需要时才会以new 的形式初始化,而且这些对象字段必须提供默认的构造方法。
3.ValueStack对象贯穿整个Action的生命周期(每个Action类的对象实例会拥有一个ValueStack对象)。当Struts 2接收到一个.action的请求后,会先建立Action类的对象实例,但并不会调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点(vs对象相当于一个栈)。
补充:值栈(根)对象也可以直接使用EL表达式访问,比如这里可以直接通过${user.username}来获取username的值,我们知道el表达式只能访问四种scope范围内的对象,那为什么这里能访问到值栈对象呢?原因是struts2对HttpServletRequet进行了一次封装,封装的代码主要是重写了getAttribute方法,简述重写此方法的核心代码:首先在原始的HttpServletRequest对象中查找el表达式中的属性,如果找不到再通过ActionContext获取值栈对象,进而再从值栈对象中查找el表达式中要访问的属性。 2.OGNL入门
下面我们在com.asm.vo.User类中增加一个字段private Address addres;,并提供此字段的get/set方法,随后再在login.jsp中增加如下代码:
城 市:<input type="text" name="user.addres.city"><br> 然后再在loginSuc.jsp中增加如下代码:
获取城市属性:<s:property value="user.addres.city"/><br>
然后测试,会得到登录时输入的城市信息(中文会有乱码)。下面借助此例谈ognl的定义:在这个例子中,我们的LoginAction中有一个User对象,而在User对象中又有一个Address对象,这些对象之间依靠这种类的字段进行关联,或者说是依靠字段属性进行导航,这也就是OGNL的定义:Object Graph Navigation Language:对象图导航图语言,它是建立在值栈技术之上的一种全新语言。
补充:用%{}可以取出存在值堆栈中的Action对象,直接调用它的方法.我们在loginSuc.jsp中增加如下内容调用LoginAction中的get方法:
调用值栈对象中的方法:<s:property value="%{get()}"/>
LoginACtion中增加的get方法如下:
public String get(){ return "这是User中的get方法";
}
3.普通方法访问
首先在User中增加一个成员方法,代码如下:
public String get(){ return "这是User中的get方法";
}
在LoginAction中也有类似的get方法,随后再在loginSuc.jsp中增加如下代码:
调用值栈对象中的普通方法(2):<s:property value="user.username.length()"/><br> 调用值栈对象中的普通方法(1):<s:property value="user.get()"/><br> 调用LoginAction中的普通方法:<s:property value="get()"/><br>
最后测试,发现这些方法都可以访问到。 4.静态方法访问
在LoginAction中增加如下方法:
public static String getSta() { return "这是LoginAction中的静态方法";
}
然后在loginSuc.jsp中增加如下代码:
调用Action中的静态方法:<s:property value="@com.asm.LoginAction@getSta()"/><br> 调用LoginAction中的静态方_方式(2):<s:property value="@vs@getSta()"/><br>
说明:我们在方式二中用到@vs,只有那些值栈中的对象才可以这样写。 然后访问,发现访问不到,因为在struts2.1.6的版本中,struts.ognl.allowStaticMethodAccess的默认值为false,我们只需在struts.xml中增加如下内容:
<constant name="struts.ognl.allowStaticMethodAccess" value="true"/> 再来访问时便可以访问到。
struts基础2的更多相关文章
- java学习-struts基础(一)
struts发展 struts是Apache软件基金会赞助的一个开源项目,是一个基于Java EE的MVC开源实现. 它为Servlet/JSP技术的应用提供技术框架2001.7--Struts1正式 ...
- Struts基础详解
1.web.xml配置: <filter> <filter-name>Struts2</filter-name> <filter-class> org. ...
- struts基础3-把数据写入页面
一.OGNL(Object-Groph Navigation Language) 是一种强大的表达式语言,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能. 1)与 ...
- struts基础
六个基本包 struts2-core-2.1.6.jar :开发的核心类库 freemarker-2.3.13.jar :struts2的UI标签的模板使用freemarker编写 commons-l ...
- 【Struts 基础案例】
LoginAction package k.action; import k.form.UserForm; import org.apache.struts.action.*; import java ...
- 【Web】Eclipse + Maven + Struts搭建服务器
一.环境 系统:Windows7 IDE:Eclipse-Kepler Service Release 2 使用插件:Maven(请预先在电脑上安装Maven) 二.搭建 在Eclipse中新建一个M ...
- 在Apache Struts中利用OGNL注入
前言 本文简要介绍了Apache Struts的OGNL注入缺陷,文章中介绍使用简单的应用程序复现OGNL注入.深入研究针对公共漏洞,并理解这类漏洞. 内容 安装Apache Tomcat服务器(入门 ...
- SSH框架的简单示例(执行流程)
本文转自一篇博文,感觉通俗易懂,适用于初学j2ee者,与大家一起分享 (一)struts框架部分 1.打开Myeclipse,创建一个web project,项目名称为TestSSH. 2.在web的 ...
- SSH入门简单搭建例子
因为公司涉及项目使用SSH,为了解SSH搭建方式和运作原理,就自己搭建了一个. 采用尽量以最少的JAR包,搭建一个简单的struts2+spring+hibernate环境,希望像我这样的入门者都能理 ...
随机推荐
- java中子类继承父类程序执行顺序
java中子类继承父类程序执行顺序 FatherTest.java public class FatherTest { private String name; public FatherTest() ...
- MySQL高级学习笔记(七):MySql主从复制
文章目录 复制的基本原理 slave会从master读取binlog来进行数据同步 三步骤+原理图 复制的基本原则 复制的最大问题 一主一从常见配置 mysql版本一致且后台以服务运行(双方能够pin ...
- yum安装apache
一.查询是否已经安装apache rpm -qa httpd 注:Apache在linux系统里的名字是httpd 如果有返回的信息,则会显示已经安装的软件.如果没有则不会显示其它的信息.如下图是 ...
- java.lang
package cn.sxt; import java.lang.*; public class BooleanDemo { public static void main(Stri ...
- Android/IOS APP界面设计之尺寸规范
1.尺寸以及分辨率 iPhone的界面尺寸不用多说,640*960是基本OK的,也可以是适应5S的640*1136,马上iPhone 6也快来了(随便吐槽一下网上曝的真机谍照,真是丑到离谱...),只 ...
- 厉害了,Spring团队又开源 nohttp 项目!
作者:h4cd 来源:https://www.oschina.net/news/107377/spring-opensource-nohttp Spring 团队开源 nohttp 项目,用以查找.替 ...
- USACO 2014 US Open Dueling GPS's /// SPFA
题目大意: 给定n个点m条边的有向图 有两个GPS 分别认为 A[i]到B[i] 的一条边的花费是P[i].Q[i] 当当前走的边不是GPS认为的最短路上的边就会被警告 即两个GPS都不认为是最短路上 ...
- Java的枚举类型使用方法详解
1.背景在java语言中还没有引入枚举类型之前,表示枚举类型的常用模式是声明一组具有int常量.之前我们通常利用public final static 方法定义的代码如下,分别用1 表示春天,2表示夏 ...
- RK3288 控制usb摄像头补光GPIO
正常可以通过添加dts配置,再从设备树中读取gpio号,在这里为了简单,直接使用GPIO号,先通过终端测试gpio, 系统自带GPIO控制驱动: 内核已经自带了通用GPIO驱动,可以直接在用户空间操作 ...
- SVN版本管理与大型代码上线方案(一)
SVN版本管理与大型代码上线方案(一) 链接:https://pan.baidu.com/s/1A3Iq3gGkGS27L_Gt37_I0g 提取码:ncy2 复制这段内容后打开百度网盘手机App,操 ...