struts中有两个<s:property >,分别输出每一位数字两个值,但是输出却是封装数据的地

Struts2中&Result类型配置详解
一个result代表了一个可能的输出。当Action类的方法执行完成时,它返回一个字符串类型的结果码,框架根据这个结果码选择对应的result,向用户输出。
在com.opensymphony.xwork2.Action接口中定义了一组标准的结果代码,可供开发人员使用,当然了只有我们的action继承ActionSupport
这个类才可以使用下面的结果代码,如下所示:
public interface Action
&&& public
static final String SUCCESS = “success”;
&&& public
static final String NONE = “none”;
&&& public
static final String ERROR = “error”;
&&& public
static final String INPUT = “input”;
&&& public
static final String LOGIN = “login”;
&& 其中 Struts2应用在运行过程中若发现addFieldError()中有信息或者类型转换失败或着输入校验失败等情况
那么它会自动跳转到name为input的&result/&,然后转到INPUT所对应的页面
若JSP页面中表单是用普通&form&编写的,发生错误而返回该页面时,则原数据将消失
若JSP页面中表单是用&s:form/&编写的,发生错误而返回该页面时,则原数据仍存在
若没有提供name值为input的&result/&,那么发生错误时,将直接在浏览器中提示404错误&
& 除了这些预定义的结果码外,开发人员也可以定义其它的结果码来满足自身应用程序的需
Result配置由两部分组成:一部分是result映射,另一部分是result类型。下面我们分别对
这两部分进行介绍。
一、配置 result映射
在result映射的配置中,在指定实际资源的位置时,可以使用绝对路径,也可以使用相对路径。
绝对路径以斜杠(/)开头,相对于当前的Web应用程序的上下文路径;
相对路径不以斜杠(/)开头,相对于当前执行的action的路径,也就是namespace指定的路径。
& &package name="default"
extends="struts-default" namespace="/admin"&
&action name="login"
class="com.ibm.LoginAction"&
&result&success.jsp&/result&
name="error"&/error.jsp&/result&
&&/package&
如果当前Web应用程序的上下文路径是/Shop,那么请求/Shop/admin/login.action,执行成功后,转向的页面路径为:/Shop/admin/success.执行失败后,转向的页面路径为/Shop/error.jsp.
二、result结果类型详解
type 所有类型 :(在struts2-core.jar/struts-default.xml中可以找到)
用来处理Action 链
com.opensymphony.xwork2.ActionChainResult
dispatcher(默认值)
用来转向页面,通常处理 JSP
org.apache.struts2.dispatcher.ServletDispatcherResult
重定向到一个URL
org.apache.struts2.dispatcher.ServletRedirectResult
redirectAction
重定向到一个 Action
org.apache.struts2.dispatcher.ServletActionRedirectResult
显示源文件内容,如文件源码
org.apache.struts2.dispatcher.PlainTextResult
freemarker
处理 FreeMarker 模板
org.apache.struts2.views.freemarker.FreemarkerResult
httpheader
控制特殊 http 行为的结果类型
org.apache.struts2.dispatcher.HttpHeaderResult
向浏览器发送 InputSream 对象,通常用来处理文件下载,还可用于返回 AJAX 数据。
org.apache.struts2.dispatcher.StreamResult
处理 Velocity 模板
org.apache.struts2.dispatcher.VelocityResult
处理 XML/XLST 模板
&org.apache.struts2.views.xslt.XSLTResult
&& <font STYLE="font-size: 24" COLOR="#、dispatcher结果类型
&& Struts2在后台使用Servlet API
的RequestDispatcher来转发请求,因此在用户的整个请求/响应过程中,目标Servlet/JSP接收到的request/response对象,与最初的Servlet/JSP相同。
&& Dispatcher结果类型的实现是org.apache.struts2.dispatcher.ServletDispatcherResult,该类的二个属性(property):location和parse,这两个属性可以通过struts.xml配置文件中的result元素的param子元素来设置。param元素的name属性指定结果类型实现类的属性名,param元素的内容是属性的值。例如:
name=“success”&
type=“dispatcher”&
&param name=“location”
&/success.jsp&/param&
&&param name=“parse”
&true&/param&
&& A、location参数用于指定action执行完毕后要转向的目标资源,parse属性是一个布尔类型的值,如果为true,则解析location参数中的OGNL表达式;如果为false,则不解析。parse属性的默认值就是true.
location参数是默认的参数,在所有的Result实现类中,都定义了一个字符串类型的DEFAULT_PARAM静态常量,专门用于指定默认的参数名。
DEFAULT_PARAM常量的定义:public static final String
DEFAULT_PARAM=“location”;
& B、在设置location参数时,可以在参数值中使用OGNL表达式。
&action name=“viewNews”
class=“com.ibm.ViewNewsAction”
&result name=“success”&
type=“dispatcher”&
&!--如果参数是中文:请参看最底部例子--&
&&& &param name=“location”
&/viewNews.jsp?id=${id}&/param&
&&param name=“parse”
&true&/param&
&/action&&&&
考虑到默认值的使用(dispatcher和location都是默认值),上述可以简化为:
&action name=“viewNews”
class=“com.ibm.ViewNewsAction”&
&result name=“success”
&viewNews.jsp?id=${id}&/result&
&2、redirect结果类型(重定向到一个Url,也可以是Action或一个页面)
Redirect结果类型在后台使用HttpServletResponse的sendRedirect方法将请求重定向到指定的URL,它的实现类是org.apache.struts2.dispatcher.ServletRedirectResult.该类同样有二个属性(property):location和parse,在使用redirect结果类型的场景中,用户要完成一次与服务器之间的交互,浏览器需要完成两次请求,因此第一次请求中的数据在第二次请求中是不可用的,这意味在目标资源中是不能访问action实例、action错误以及错误等。
如果有某些数据需要在目标资源中访问,
& i、一种方式是将数据保存到Session中,
& ii、另一种方式是通过请求参数来传递数据。
示例(1)、&result name="success" type="redirect"&&&
&&&&&&&&&&&&
name="location"&foo.jsp&/param&
&&&&&&&&&&&&
name="parse"&false&/param&&!--不解析OGNL--&
示例(2)、
&& &package
name="passingRequestParameters"extends="struts-default"namespace="/passingRequestParameters"&&&
&& &-- Passparameters (reportType, width
and height),重定向到Url并且传参 ,如果参数是中文:请参看最底部例子--&&&
The redirect-action url generated will be
/genReport/generateReport.jsp?reportType=pie&width=100&height=100&&
&actionname="gatherReportInfo"
class="..."&&&
&resultname="showReportResult"
type="redirect"&&&
name="location"&generateReport.jsp&/param&&&
name="namespace"&/genReport&/param&&&
name="reportType"&pie&/param&&&
name="width"&100&/param&&
name="height"&100&/param&&
&/result&&&
&/action&&&
&/package&&
3、redirectAction结果类型(重定向到一个Action)
他经常用于防止表单重复提交,比方说在增加完用户之后要显示列表&
&redirectAction结果类型的实现类是org.apache.struts2.dispatcher.ServletActionRedirectResult,该类是ServletRedirectResult的子类,因此我们也就可以判断出redirectAction结果类型和redirect结果类型的后台工作原理是一样的,即都是利用HttpServletResponse的sendRedirect方法将请求重定向到指定的URL。
& &package
name="public"extends="struts-default"&&&
name="login"class="..."&&&
&!--Redirect to another
重定向到不同命名空间下的&&&
action --&&
type="redirectAction"&&&
&&&&&&&&&&
&param name="actionName"&dashboard&/param&&
&&&&&&&&&&
&param name="namespace"&/secure&/param&&
&/result&&
&/action&&
&/package&&
&package name="secure"extends="struts-default"
namespace="/secure"&&&
&&& &-- Redirectto an action in the same
namespace,重定向到同一命名空间下的action --&
&action name="dashboard"
class="..."&&&
&result&dashboard.jsp&/result&&
name="error"type="redirectAction"&error&/result&&
&/action&&
&action name="error"
class="..."&&&
&result&error.jsp&/result&
&/action&&
&/package&&
name="passingRequestParameters"extends="struts-default"namespace="/passingRequestParameters"&&&
&-- Passparameters (reportType, width and
height),重定向到Action并且传参,如果参数是中文:请参看最底部例子
&& TheredirectAction url
generated will be
/genReport/generateReport.action?reportType=pie&width=100&height=100&
&& &action
name="gatherReportInfo"
class="..."&&&
name="showReportResult" type="redirectAction"&&&
name="actionName"&generateReport&/param&&
name="namespace"&/genReport&/param&&
name="reportType"&pie&/param&&
name="width"&100&/param&
name="height"&100&/param&
name="empty"&&/param&
name="supressEmptyParameters"&true&/param&&
&/result&&
&/action&&
&/package&
4、链接类型&
result:chain(从一个Action转发到另一个Action)
& chain结果类型有4个属性,分别是:
actionName (default) - the name of the action that will be
chained to
namespace - used to determine which namespace the Action is
in that we're chaining. If namespace is null, this defaults to the
current namespace
method - used to specify another method on target action to
be invoked. If null, this defaults to execute method
skipActions - (optional) the list of comma separated action
names for the actions that could be chained to
name="public"extends="struts-default"&&&
&&& &!-- Chain
creatAccount to login, using the default parameter
,链接到同一命名空间下的Action,--&&
&action name="createAccount"
class="..."&&&
type="chain"&login&/result&
&/action&&
&actionname="login"
class="..."&&&
&!--Chain to another
namespace --&&
type="chain"&&&
&&&&&&&&&&
name="actionName"&dashboard&/param&&
&&&&&&&&&&
name="namespace"&/secure&/param&&
&/result&&
&/action&&
&/package&&
&package name="secure"
extends="struts-default"namespace="/secure"&&&
&actionname="dashboard"
class="..."&&&
&result&dashboard.jsp&/result&&
&/action&&
&/package&
5、HttpHeader
Result:HttpHeader(用来控制特殊的Http行为)
& httpheader结果类型很少使用到,它实际上是返回一个HTTP响应的头信息
&示例:&result
name="success"type="httpheader"&&&
&paramname="status"&204&/param&
&paramname="headers.a"&a custom
value&/param&&&&&&
&paramname="headers.b"&another custom
value&/param&&
&/result&&
name="proxyRequired"type="httpheader"&&&
&paramname="error"&305&/param&
&paramname="errorMessage"&this action
must be accessed through
aprozy&/param&&
&/result&&
Result(向浏览器发送InputSream对象,通常用来处理文件下载)
name="success"type="stream"&&&
name="contentType"&image/jpeg&/param&&
name="inputName"&imageStream&/param&&
name="contentDisposition"&filename="document.pdf"&/param&&&
name="bufferSize"&1024&/param&&
7、PlainText
Result(显示原始文件内容,例如文件源代码)
name="displayJspRawContent"&&
type="plaintext"&/myJspFile.jsp&/result&&
&/action&&&
name="displayJspRawContent"&&
type="plaintext"&&&
name="location"&/myJspFile.jsp&/param&&
name="charSet"&UTF-8&/param&
&/result&&
&/action&&
若仅设置type="plainText"的话,页面中显示中文时会乱码,这时就可以借助它的charSet属性以解决中文显示时的乱码问题,如果不设置charSet属性,反而去配置struts.i18n.encoding全局属性,是不能解决问题的
设置charSet属性的目的就是让JSP页面的编码与明文显示时的编码一致
8、Velocity
Result(处理Velocity模板)
name="success"type="velocity"&&&
&paramname="location"&foo.vm&/param&&
&/result&&
Result(处理XML/XLST模板)& &result
name="success"
type="xslt"&&&
&paramname="location"&foo.xslt&/param&&
&paramname="matchingPattern"&^/result/[^/*]$&/param&&
&paramname="excludingPattern"&.*(hugeCollection).*&/param&&
&/result&&
FreeMarkerResult&
(处理FreeMarker模板)
name="success"type="freemarker"&foo.ftl&/result&
附、另外第三方的Result类型还包括JasperReportsPlugin,专门用来处理JasperReport类型的报表输出。
&%@ tagliburi="http://tiles.apache.org/tags-tiles"
prefix="tiles"%&&
&%@ taglib prefix="s"uri="/struts-tags"
& &%-- S Used in Header
&tiles:importAttribute
name="title"scope="request"/&&&
&head&&title&&tiles:getAsStringname="title"/&&/title&&/head&&&
&tiles:insertAttribute
name="header"/&&&
&pid="body"&&&
&tiles:insertAttributename="body"/&&&
&p&Noticethat this is a layout made
in JSP&/p&
注意!!!!.传递中文
记住永远不要在浏览器的地址栏中传递中文。在传递中文前先进行编码
A.action中
public class User extends
ActionSupport{
&private S
&public String getUsername() {
&public void setUsername(String username) {
&&this.username =
&@Override
&public String execute() throws Exception {
&&// TODO Auto-generated method
&&username=URLEncoder.encode("郭蕾","utf-8");//先进行编码&&System.out.println(username);
&&return "redirect";
B.struts.xml中
&&action name="redirect"
class="action.User"&
&&result type="redirect"
name="redirect"&
&/redirect.jsp?username=${username}//如果要传递两个参数,中间用&代替&
&&/action&
在这里使用了类似于el表达式的方式传值,${username}其中username为action中定义的
C.redirect.jsp中
&& &%String
s=request.getParameter("username");
String(s.getBytes("iso8859-1"),"utf-8");
&s=URLDecoder.decode(s,"utf-8");
&out.println(s);
重定向中传递中文先进行编码,在jsp页面中先接受参数,然后对其进行字节分解,然后进行解码。
参考博文连接:
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。ValueStack对象相当于一个栈,它贯穿整个Action的生命周期,每个Action类的对象实例都会拥有一个ValueStack对象
当Struts2接收到一个*.action请求后,并不是直接调用Action方法,而是先将Action类的相应属性放到ValueStack对象的顶层节点
值栈也位于内存中,它也是和parameters、request、session、application、attr对象放在一起的
值栈属于ONGL Context里面的根对象。也就是说它位于整个内存中最最重要的地方,所以叫根对象
根对象和另外五个对象是有区别的,根对象可以省写#号,比如&s:property value="user.username"/&
值栈的生命周期与request请求相关,每次请求产生一个值栈。默认所有的Action会被自动放到值栈里
服务器跳转时共用值栈
假设从一个Action11通过服务器跳转到Action22的话,就意味着这两个Action是共享一个值栈的,因为一次请求只使用一个值栈
这时内存中情况是这样的:首先接收到Action11请求后,会产生一个值栈,在栈顶存放Action11对象以及它所有的属性
然后经过服务器跳转到Action22,这时就会把Action22对象压入值栈的栈顶位置,此时Action11对象以及它的所有属性就位于栈底了
栈的特征是后进先出。于是首先到栈顶的对象里查找是否存在这个属性,如果栈顶的Action22对象中不存在这个属性的话
它就会继续向下寻找直至栈底对象,一直查找是否存在这个属性
如果最后找到该属性的话,那么就会在JSP页面中通过&s:property value="username"/&输出属性值
如果在Action22和Action11都有一个同名的同类型的username属性的话,那么将输出Action22中的属性值
因为它是先从栈顶开始寻找属性的,值栈的特征就是后进先出,但有个前提:请求过程是通过服务器跳转的
假设此时想要获取Action11中的username属性的话,就可以使用值栈的Top语法或者N语法
使用Top语法获取值栈中的第二个对象的属性:&s:property value="[1].top.username"/&
使用 N 语法获取值栈中的第二个对象的属性:&s:property value="[1].username"/&
另外值栈还有一个@语法,例如使用@语法调用Action中的静态方法:&s:property value="@vs@getVOMethod()"/&
@vs@get()等价于@vs1@getVOMethod(),指的是栈顶对象的静态getVOMethod()方法
同理@vs2@getVOMethod()就是取值栈中第二个对象的静态getVOMethod()方法
客户端跳转时使用各自的值栈
假如中间某一个步骤中出现了客户端跳转的话,那么两个Action所使用的就是两个不同的值栈了
所以在Action22中就不能再使用Action11中的属性了,在最后跳转到的JSP页面中也就无法获取Action11的属性了
也即从Action22跳转到JSP页面时使用的是redirect的话,那么最后值栈中是没有任何的Action对象的
这个时候我们可以通过链接传参,比如&result type="redirect"&test.jsp?netname=${username}&/result&
意思就是取出Action22中的username属性作为参数,通过浏览器地址栏传递到JSP页面中
然后使用OGNL中的#号获取Paraments对象的属性,即&s:property value="#parameters.netname"/&就可以取到值了
辅助参考:
手工向值栈中压入对象
正常情况下值栈保存的是Action对象,而我们也可以直接往值栈中添加其它对象,这时可以在Action中添加如下代码
向值栈中添加对象:ActionContext.getContext.getValueStack().push(new Student("沈浪",22));
而且我们手工往值栈中添加的Student对象会位于栈顶。这是因为Struts2会首先初始化Action,然后才能调用它的方法
初始化Action的时候,便把Action放到值栈中了,然后在执行它的execute()方法时,就又往值栈中添加了Student对象
OGNL是Object-Graph Navigation Language的缩写,是一种功能强大的表达式语言
通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能
OGNL用得最多的地方就是和Struts2的标签绑定,也可以在配置文件中通过${}使用OGNL表达式
OGNL中$号的使用
1..在国际化资源文件中,引用OGNL表达式
2..在struts.xml文件中,引用OGNL表达式
OGNL中%号的使用
1..使用%{}可以取出保存在值堆栈中的Action对象,直接调用它的方法
2..如果Action继承了ActionSupport,那么在页面标签中可以使用%{getText('key')}获取国际化信息
辅助参考:
OGNL中#号的使用
OGNL中的#号可以取出堆栈上下文中存放的对象
用于按request&&session&&application顺序访问其属性
#attr.userName相当于按顺序从三个范围读取userName属性直到找到为止
包含当前HttpServletRequest的属性的Map
#request.userName相当于request.getAttribute("userName")
包含当前HttpSession的属性的Map
#session.userName相当于session.getAttribute("userName")
application
包含当前应用的ServletContext的属性的Map
#application.userName相当于application.getAttribute("userName")
parameters
包含当前HTTP请求参数的Map
#parameters.id[0]相当于request.getParameter("id")
获取Action中的属性值或者Action中的对象的某某属性值
利用&s:property/&标签可以直接获取Action中的引用类型user里面的username属性
同样可以通过user.address.addr获取user中引用类型address中的addr属性的值
像这种一层一层往下传递的访问方式,即所谓的导航,也就是一步步的往下调用
调用Action的对象里面的普通方法
默认的会把Action放到值栈里面,而值栈在访问的时候,并不需要值栈的名字
当我们调用&s:property value="user.getVOMethod()"/&的时候
它会自动到值栈里面查找Action对象里面有没有user对象,然后它就发现有user
然后它就再找user里面有没有getVOMethod()方法,然后它发现有,于是调用getVOMethod()
实际上调用User中的getVOMethod()方法的过程与获取表单中的姓名密码的方式都是相同的
都是到值栈里面查找,找是否存在user对象,如果存在,接着查找user中是否存在某某属性或方法
调用Action中的静态方法
同样我们也可以在JSP页面中写一个OGNL表达式调用Action中的静态方法
调用Action中的静态方法时,与调用user对象的getVOMethod()方法的过程,是截然不同的
此时value的写法是固定的,以@开头,后面跟上具体的包名,然后@加上静态方法
比如&s:property value="@com.jadyer.action.LoginAction@getStatic()"/&
另外user对象是LoginAction中的一个属性,这个属性会自动的放到值栈里面
而值栈调用的时候,不用加上@或者包名等等,所以直接user.getVOMethod()就可以了
调用JDK类中的静态方法
可以使用&s:property value="@@floor(46.58)"/&输出floor()的执行结果
这就意味着如果不在@@中指定类的话,默认的就表示java.lang.Math类
当前大多数情况下,我们都不会省略这个类,都会写全了的,然后在后面加上静态方法
集合的伪属性
OGNL能够引用集合的一些特殊的属性,这些属性并不是JavaBean模式,例如size()、length()
当表达式引用这些属性时,OGNL会调用相应的方法,这就是伪属性
比如获取List的大小:&s:property value="testList.size"/&
&&&&& List的伪属性:size、isEmpty、iterator
&&&&&& Set的伪属性:size、isEmpty、iterator
&&&&&& Map的伪属性:size、isEmpty、keys、values
& Iterator的伪属性:next、hasNext
Enumeration伪属性:next、hasNext、nextElement、hasMoreElements
获取集合中元素的实质就是调用它的toString()方法
它还可以直接获取集合中的元素,事实上是在调用集合的toString()方法
所以我们可以根据实际情况通过重写集合的toString()方法来实现个性& 化输出
甚至它还可以像访问数组那样,直接testList[2]获取集合中的元素
但这种方法只适用于List,不适用于Map。因为Map的索引是key,不是数值
另外,由于HashSet中的元素是没有顺序的,所以也不能用下标获取单个元素
Lambda表达式
补充一下:使用Lambda表达式可以在OGNL中书写递归式子,在帮助中对它有很详细的说明
打开帮助中的//struts-2.0.14-all//struts-2.0.14//docs//index.html页面
在左侧的Documentation下面点击Guides链接,然后在这个页面中点击OGNL
最后跳转到//struts-2.0.14-all//struts-2.0.14//docs//docs//ognl.html
将这个页面右侧的下拉条拖放到最下面,就会看到它的说明了,它举的例子如下所示
&s:property value="#fib =:[#this==0 ? 0 : #this==1 ? 1 : #fib(#this-2)+#fib(#this-1)], #fib(11)" /&
Lambda表达式的语法是:[...] ,中括号前面有一个冒号,所有东西都在中括号里面写
也就是说我们只要看到一个冒号跟着一个中括号,就表示这里使用的是Lambda表达式
#this指的是表达式的参数
所以这个例子可以这样理解:先判断这个参数是否等于零,如果等于零,那么它的值最后就是零
如果参数不等于零,就再判断它是否等于壹。如果参数等于壹,那么它的值最后就是壹
如果参数不等于壹,就继续调用#fib。注意这里已经用中括号将整体的值赋给了fib
实际上很少能够用得到Lambda表达式
利用投影获取属性
利用投影获取List中对象的username属性时,其中{}表示的是一个集合
stus.{username}就表示将suts中所有的username属性取出组成一个新的列表
利用选择获取属性
OGNL表达式是很灵活的,可以同时使用选择技术与投影技术获取属性
使用选择技术时,#this代表当前元素,问号?是把所有满足条件的元素都取出来
上箭头^是开始的意思,所以stus.{^#this.grade&=60}.{username}输出的是[张三]
注意,此时输出文本中包含中括号,这表示它是一个列表
而stus.{?#this.grade&=60}.{username}[0]输出的是张三,是字符串,二者是不同的
美元符号$是结束的意思,所以stus.{$#this.grade&=60}.{username}输出的是[王五]
这三个符合:问号、上箭头、美元符所返回的都是List
1..当OGNL取不到值的时候,它不会报错,而是什么都不显示
2..&s:property value="[0]"/&返回的是ValueStack中从上至下的所有的Object
&&& &s:property value="[1]"/&返回的是ValueStack中从上至下的第二个Object
3..&s:property value="[0].username"/&返回的是成员变量username的值
&&& 假设ValueStack中存在两个Action的话,如果第一个Action如果没有username变量
&&& 那么它会继续找第二个Action。那么在什么情况下ValueStack中会存在两个Action呢
&&& 答案是在struts.xml中配置的是从一个Action通过&result type="chain"&跳转到另一个Action
4..&constant name="struts.ognl.allowStaticMethodAccess" value="true"/&
&&& 在Struts2.1.6中必须设置struts.ognl.allowStaticMethodAccess为true之后
&&& 才允许使用OGNL访问静态方法。而在Struts2.0.11则无需设置,即可直接访问
下面是OGNL测试的工程代码,这是一个Struts2.0.11应用
首先是web.xml文件
version="1.0"encoding="UTF-8"&
version="2.5"&&
&&& xmlns="/xml/ns/javaee"&&
&&& xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&&
&&& xsi:schemaLocation="/xml/ns/javaee&&
&&& /xml/ns/javaee/web-app_2_5.xsd"&
&&&&&&& struts2&
&&&&&&& org.apache.struts2.dispatcher.FilterDispatcher&
&&&&&&& struts2&
&&&&&&& /*&
&&&&&&& login.jsp&
&version="1.0"&encoding="UTF-8"&&
&version="2.5"&&&
&&&&xmlns="/xml/ns/javaee"&&&
&&&&xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&&&
&&&&xsi:schemaLocation="/xml/ns/javaee&&&
&&&&/xml/ns/javaee/web-app_2_5.xsd"&&
&&&&&&&&struts2&&
&&&&&&&&org.apache.struts2.dispatcher.FilterDispatcher&&
&&&&&&&&struts2&&
&&&&&&&&/*&&
&&&&&&&&login.jsp&&
然后是用于输入用户名和密码等信息的测试页面login.jsp
%@ page language="java"pageEncoding="UTF-8"%&
这是测试OGNL使用的登录页面&
color="red"提示:程序设定的用户名和密码各为color="blue"admin和color="blue"jadyer&
color="red"注意:用户名和密码不正确时将停留在页面不动&
action="&%=request.getContextPath()%&/login.action"method="POST"&
&&& %--这里user.username匹配的是LoginAction中的引用类型user里面的username属性--%&
&&& %--查看标签库说明的话,就知道name中指定的是对象。这里它不是字符串,而是OGNL表达式--%&
&&& 姓名:type="text"name="user.username"&
&&& 密码:type="text"name="user.password"&
&&& 地址:type="text"name="user.address.addr"&
&&& type="submit"value="测试OGNL的输出"&
%@&page&language="java"&pageEncoding="UTF-8"%&&
这是测试OGNL使用的登录页面&&
&color="red"提示:程序设定的用户名和密码各为&color="blue"admin和&color="blue"jadyer&&
&color="red"注意:用户名和密码不正确时将停留在页面不动&&
&action="&%=request.getContextPath()%&/login.action"&method="POST"&&
&&&&%--这里user.username匹配的是LoginAction中的引用类型user里面的username属性--%&&
&&&&%--查看标签库说明的话,就知道name中指定的是对象。这里它不是字符串,而是OGNL表达式--%&&
&&&&姓名:&type="text"&name="user.username"&&
&&&&密码:&type="text"&name="user.password"&&
&&&&地址:&type="text"&name="user.address.addr"&&
&&&&&type="submit"&value="测试OGNL的输出"&&
然后是用于显示OGNL处理结果的loginSuc.jsp页面
%@ page language="java"pageEncoding="UTF-8"%&
%@ taglib prefix="s"uri="/struts-tags"%&
这是使用OGNL输出的结果页面&
border="9"&
&&&&&&& align="right"获取姓名属性:&
&&&&&&& align="left"value="user.username"&
&&&&&&& %-- 另外还有两种写法也是可以正常输出值栈中对象的普通属性的 --%&
&&&&&&& %-- value="user['username']"
&&&&&&& %-- value="user[/"username/"]"
&&&&&&& %-- 但是如果写成下面这种形式的话,就什么都不会输出了 --%&
&&&&&&& %-- value="user[username]"
&&&&&&& align="right"获取地址属性:&
&&&&&&& align="left"value="user.address.addr"&
&&&&&&& align="right"调用值栈中的对象的普通方法:&
&&&&&&& align="left"value="user.getVOMethod()"&
&&&&&&& align="right"调用值栈中Action的普通方法:&
&&&&&&& align="left"value="getCommon()"&
border="9"&
&&&&&&& align="right"获取普通类的静态属性:&
&&&&&&& align="left"value="@com.jadyer.vo.Address@TIPS"&
&&&&&&& align="right"访问普通类的构造方法:&
&&&&&&& align="left"value="new
com.jadyer.vo.Student('张小三',22).username"&
&&&&&&& align="right"调用Action中的静态方法:&
&&&&&&& align="left"value="@com.jadyer.action.LoginAction@getStatic()"&
&&&&&&& align="right"调用JDK中的类的静态方法:&
&&&&&&& align="left"value="@java.util.Calendar@getInstance().time"&
&&&&&&& align="right"调用JDK中的类的静态方法:&
&&&&&&& align="left"value="@java.lang.Math@floor(46.58)"&
&&&&&&& align="right"调用JDK中的类的静态方法:&
&&&&&&& align="left"value="@@floor(46.58)"&
border="9"&
&&&&&&& align="right"获取List中的所有元素:&
&&&&&&& align="left"value="testList"&
&&&&&&& align="right"获取Set中的所有元素:&
&&&&&&& align="left"value="testSet"&
&&&&&&& align="right"获取Map中的所有元素:&
&&&&&&& align="left"value="testMap"&
&&&&&&& align="right"获取Map中的某个元素:&
&&&&&&& align="left"value="testMap['m22']"&
&&&&&&& %-- 另外还有两种写法也是可以正常获取Map中的某个具体元素的 --%&
&&&&&&& %-- value="testMap.m22"
&&&&&&& %-- value="testMap[/"m22/"]"
&&&&&&& align="right"获取Set中的某个元素:&
&&&&&&& %-- 由于Set中的元素是无顺序的,所以不能使用下标获取数据,所以这里什么也得不到 --%&
&&&&&&& align="left"value="testSet[2]"&
&&&&&&& align="right"获取List中的某个元素:&
&&&&&&& align="left"value="testList[2]"&
border="9"&
&&&&&&& align="right"获取List的大小:&
&&&&&&& align="left"value="testList.size"&
&&&&&&& align="right"获取Set的大小:&
&&&&&&& align="left"value="testSet.size"&
&&&&&&& align="right"获取Map的大小:&
&&&&&&& align="left"value="testMap.size"&
&&&&&&& align="right"获取Map中所有的键:&
&&&&&&& align="left"value="testMap.keys"&
&&&&&&& align="right"获取Map中所有的值:&
&&&&&&& align="left"value="testMap.values"&
&&&&&&& align="right"Lambda计算4的阶乘:&
&&&&&&& align="left"value="#f=
:[#this==1?1 : #this*#f(#this-1)],#f(4)"&
border="9"&
&&&&&&& align="right"获取List中的所有对象:&
&&&&&&& align="left"value="stus"&
&&&&&&& align="right"利用投影获取List中对象的名字:&
&&&&&&& align="left"value="stus.{username}"&
&&&&&&& align="right"利用投影获取List中第二个对象的名字:&
&&&&&&& %-- 使用value="stus[1].{username}"获取到的值为:[李四]
&&&&&&& %-- 二者的区别在于:后者比前者多了一个中括号 --%&
&&&&&&& align="left"&
&&&&&&&&&&& value="stus.{username}[1]"&&&&&&&
&&&&&&&&&&& value="stus[1].{username}"&
&&&&&&& align="right"利用选择获取List中成绩及格的所有对象:&
&&&&&&& align="left"value="stus.{?#this.grade&=60}"&
&&&&&&& align="right"利用选择获取List中成绩及格的第一个对象:&
&&&&&&& align="left"value="stus.{^#this.grade&=60}"&
&&&&&&& align="right"利用选择获取List中成绩及格的最后一个对象:&
&&&&&&& align="left"value="stus.{$#this.grade&=60}"&
border="9"&
&&&&&&& align="right"利用选择获取List中成绩及格的所有对象的名字:&
&&&&&&& align="left"value="stus.{?#this.grade&=60}.{username}"&
&&&&&&& align="right"利用选择获取List中成绩及格的第二个对象的名字:&
&&&&&&& align="left"value="stus.{?#this.grade&=60}.{username}[1]"&
&&&&&&& align="right"利用选择获取List中成绩及格的第一个对象的名字:&
&&&&&&& align="left"value="stus.{^#this.grade&=60}.{username}"&
&&&&&&& align="right"利用选择获取List中成绩及格的最后一个对象的名字:&
&&&&&&& align="left"value="stus.{$#this.grade&=60}.{username}"&
&&&&&&& align="right"利用选择获取List中成绩及格的第一个对象然后求大小:&
&&&&&&& align="left"value="stus.{^#this.grade&=60}.{username}.size"&
border="9"&
&&&&&&& align="right"利用OGNL中的#号获取attr中的属性:&
&&&&&&& align="left"value="#attr.BB"&
&&&&&&& align="right"利用OGNL中的#号获取request范围中的属性:&
&&&&&&& align="left"value="#request.req"&
&&&&&&& align="right"利用OGNL中的#号获取session范围中的属性:&
&&&&&&& align="left"value="#session.ses"&
&&&&&&& align="right"利用OGNL中的#号获取Paraments对象的属性:&
&&&&&&& align="left"value="#parameters.netname"&
&&&&&&& align="right"使用&#60;&#37;=request.getParameter&#40;""&#41;&#37;&#62;或者&#36;&#123;param.name&#125;获取链接参数值:&
&&&&&&& align="left"&
&&&&&&&&&&& ${param.netname}&&&&&&&
&&&&&&&&&&& %=request.getParameter("netname")%&
&&&&&&& align="right"查看值栈中的信息:&
&&&&&&& align="left"&
%@&page&language="java"&pageEncoding="UTF-8"%&&
%@&taglib&prefix="s"&uri="/struts-tags"%&&
这是使用OGNL输出的结果页面&&
&border="9"&&
&&&&&&&&&align="right"获取姓名属性:&&
&&&&&&&&&align="left"&value="user.username"&&
&&&&&&&&%--&另外还有两种写法也是可以正常输出值栈中对象的普通属性的&--%&&
&&&&&&&&%--&&value="user['username']"&--%&&
&&&&&&&&%--&&value="user[/"username/"]"&--%&&
&&&&&&&&%--&但是如果写成下面这种形式的话,就什么都不会输出了&--%&&
&&&&&&&&%--&&value="user[username]"&--%&&
&&&&&&&&&align="right"获取地址属性:&&
&&&&&&&&&align="left"&value="user.address.addr"&&
&&&&&&&&&align="right"调用值栈中的对象的普通方法:&&
&&&&&&&&&align="left"&value="user.getVOMethod()"&&
&&&&&&&&&align="right"调用值栈中Action的普通方法:&&
&&&&&&&&&align="left"&value="getCommon()"&&
&border="9"&&
&&&&&&&&&align="right"获取普通类的静态属性:&&
&&&&&&&&&align="left"&value="@com.jadyer.vo.Address@TIPS"&&
&&&&&&&&&align="right"访问普通类的构造方法:&&
&&&&&&&&&align="left"&value="new&com.jadyer.vo.Student('张小三',22).username"&&
&&&&&&&&&align="right"调用Action中的静态方法:&&
&&&&&&&&&align="left"&value="@com.jadyer.action.LoginAction@getStatic()"&&
&&&&&&&&&align="right"调用JDK中的类的静态方法:&&
&&&&&&&&&align="left"&value="@java.util.Calendar@getInstance().time"&&
&&&&&&&&&align="right"调用JDK中的类的静态方法:&&
&&&&&&&&&align="left"&value="@java.lang.Math@floor(46.58)"&&
&&&&&&&&&align="right"调用JDK中的类的静态方法:&&
&&&&&&&&&align="left"&value="@@floor(46.58)"&&
&border="9"&&
&&&&&&&&&align="right"获取List中的所有元素:&&
&&&&&&&&&align="left"&value="testList"&&
&&&&&&&&&align="right"获取Set中的所有元素:&&
&&&&&&&&&align="left"&value="testSet"&&
&&&&&&&&&align="right"获取Map中的所有元素:&&
&&&&&&&&&align="left"&value="testMap"&&
&&&&&&&&&align="right"获取Map中的某个元素:&&
&&&&&&&&&align="left"&value="testMap['m22']"&&
&&&&&&&&%--&另外还有两种写法也是可以正常获取Map中的某个具体元素的&--%&&
&&&&&&&&%--&&value="testMap.m22"&--%&&
&&&&&&&&%--&&value="testMap[/"m22/"]"&--%&&
&&&&&&&&&align="right"获取Set中的某个元素:&&
&&&&&&&&%--&由于Set中的元素是无顺序的,所以不能使用下标获取数据,所以这里什么也得不到&--%&&
&&&&&&&&&align="left"&value="testSet[2]"&&
&&&&&&&&&align="right"获取List中的某个元素:&&
&&&&&&&&&align="left"&value="testList[2]"&&
&border="9"&&
&&&&&&&&&align="right"获取List的大小:&&
&&&&&&&&&align="left"&value="testList.size"&&
&&&&&&&&&align="right"获取Set的大小:&&
&&&&&&&&&align="left"&value="testSet.size"&&
&&&&&&&&&align="right"获取Map的大小:&&
&&&&&&&&&align="left"&value="testMap.size"&&
&&&&&&&&&align="right"获取Map中所有的键:&&
&&&&&&&&&align="left"&value="testMap.keys"&&
&&&&&&&&&align="right"获取Map中所有的值:&&
&&&&&&&&&align="left"&value="testMap.values"&&
&&&&&&&&&align="right"Lambda计算4的阶乘:&&
&&&&&&&&&align="left"&value="#f=&:[#this==1?1&:&#this*#f(#this-1)],#f(4)"&&
&border="9"&&
&&&&&&&&&align="right"获取List中的所有对象:&&
&&&&&&&&&align="left"&value="stus"&&
&&&&&&&&&align="right"利用投影获取List中对象的名字:&&
&&&&&&&&&align="left"&value="stus.{username}"&&
&&&&&&&&&align="right"利用投影获取List中第二个对象的名字:&&
&&&&&&&&%--&使用&value="stus[1].{username}"获取到的值为:[李四]&--%&&
&&&&&&&&%--&二者的区别在于:后者比前者多了一个中括号&--%&&
&&&&&&&&&align="left"&&
&&&&&&&&&&&&&value="stus.{username}[1]"&&&&&&&&
&&&&&&&&&&&&&value="stus[1].{username}"&&
&&&&&&&&&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的所有对象:&&
&&&&&&&&&align="left"&value="stus.{?#this.grade&=60}"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的第一个对象:&&
&&&&&&&&&align="left"&value="stus.{^#this.grade&=60}"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的最后一个对象:&&
&&&&&&&&&align="left"&value="stus.{$#this.grade&=60}"&&
&border="9"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的所有对象的名字:&&
&&&&&&&&&align="left"&value="stus.{?#this.grade&=60}.{username}"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的第二个对象的名字:&&
&&&&&&&&&align="left"&value="stus.{?#this.grade&=60}.{username}[1]"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的第一个对象的名字:&&
&&&&&&&&&align="left"&value="stus.{^#this.grade&=60}.{username}"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的最后一个对象的名字:&&
&&&&&&&&&align="left"&value="stus.{$#this.grade&=60}.{username}"&&
&&&&&&&&&align="right"利用选择获取List中成绩及格的第一个对象然后求大小:&&
&&&&&&&&&align="left"&value="stus.{^#this.grade&=60}.{username}.size"&&
&border="9"&&
&&&&&&&&&align="right"利用OGNL中的#号获取attr中的属性:&&
&&&&&&&&&align="left"&value="#attr.BB"&&
&&&&&&&&&align="right"利用OGNL中的#号获取request范围中的属性:&&
&&&&&&&&&align="left"&value="#request.req"&&
&&&&&&&&&align="right"利用OGNL中的#号获取session范围中的属性:&&
&&&&&&&&&align="left"&value="#session.ses"&&
&&&&&&&&&align="right"利用OGNL中的#号获取Paraments对象的属性:&&
&&&&&&&&&align="left"&value="#parameters.netname"&&
&&&&&&&&&align="right"使用&#60;&#37;=request.getParameter&#40;""&#41;&#37;&#62;或者&#36;&#123;param.name&#125;获取链接参数值:&&
&&&&&&&&&align="left"&&
&&&&&&&&&&&&${param.netname}&&&&&&&&
&&&&&&&&&&&&%=request.getParameter("netname")%&&
&&&&&&&&&&
&&&&&&&&&align="right"查看值栈中的信息:&&
&&&&&&&&&align="left"&&
然后是struts.xml文件
version="1.0"encoding="UTF-8"&
&!DOCTYPE struts PUBLIC&
&&& "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"&
&&& "http://struts.apache.org/dtds/struts-2.0.dtd"&
&&& name="ognl"extends="struts-default"&
&&&&&&& name="login"class="com.jadyer.action.LoginAction"&
&&&&&&&&&&& name="input"/login.jsp&
&&&&&&&&&&& name="success"/loginSuc.jsp?netname=hongyu&
&&&&&&&&&&& &!--&
&&&&&&&&&&& name="success"type="redirect"/loginSuc.jsp?netname=hongyu&
&&&&&&&&&&& name="success"type="redirect"/loginSuc.jsp?netname=${user.username}&&
&&&&&&&&&&&& --&
&version="1.0"&encoding="UTF-8"&&
&!DOCTYPE&struts&PUBLIC&&
&&&&"-//Apache&Software&Foundation//DTD&Struts&Configuration&2.0//EN"&&
&&&&"http://struts.apache.org/dtds/struts-2.0.dtd"&&
&&&&&name="ognl"&extends="struts-default"&&
&&&&&&&&&name="login"&class="com.jadyer.action.LoginAction"&&
&&&&&&&&&&&&&name="input"/login.jsp&&
&&&&&&&&&&&&&name="success"/loginSuc.jsp?netname=hongyu&&
&&&&&&&&&&&&&!--&&
&&&&&&&&&&&&&name="success"&type="redirect"/loginSuc.jsp?netname=hongyu&&
&&&&&&&&&&&&&name="success"&type="redirect"/loginSuc.jsp?netname=${user.username}&&&
&&&&&&&&&&&&&--&&
&&&&&&&&&&
接着是用到的三个VO类
package com.jadyer.&
publicclass User {&
&&& private S&
&&& private S&
&&& private A&
&&& public String getVOMethod(){&
&&&&&&& return"这是User类中的一个普通方法";&
package com.jadyer.&
publicclass Address {&
&&& publicstaticfinal String TIPS =
"玄玉加油!!";&
&&& private S&
package com.jadyer.&
publicclass Student {&
&&& private S&
&&& privateint&
&&& public Student(){};&
&&& public Student(String username,int grade){&
&&&&&&& this.username =&
&&&&&&& this.grade =&
&&& @Override&
&&& public String toString() {&
&&&&&&& return"{学生姓名:" + username +",成绩:" + grade +
package&com.jadyer.&&
public&class&User&{&&
&&&&private&String&&&
&&&&private&String&&&
&&&&private&Address&&&
&&&&public&String&getVOMethod(){&&
&&&&&&&&return&"这是User类中的一个普通方法";&&
package&com.jadyer.&&
public&class&Address&{&&
&&&&public&static&final&String&TIPS&=&"玄玉加油!!";&&
&&&&private&String&&&
package&com.jadyer.&&
public&class&Student&{&&
&&&&private&String&&&
&&&&private&int&&&
&&&&public&Student(){};&&
&&&&public&Student(String&username,int&grade){&&
&&&&&&&&this.username&=&&&
&&&&&&&&this.grade&=&&&
&&&&@Override&&
&&&&public&String&toString()&{&&
&&&&&&&&&&
&&&&&&&&return&"{学生姓名:"&+&username&+&",成绩:"&+&grade&+&"}";&&
最后是用来提供OGNL测试的数据的LoginAction.java
package com.jadyer.&
import java.util.ArrayL&
import java.util.HashM&
import java.util.HashS&
import java.util.L&
import java.util.M&
import java.util.S&
import org.apache.struts2.interceptor.RequestA&
import org.apache.struts2.interceptor.SessionA&
import com.jadyer.vo.S&
import com.jadyer.vo.U&
import com.opensymphony.xwork2.ActionS&
@SuppressWarnings({"serial","unchecked"})&
publicclass LoginActionextends ActionSupport
implements RequestAware,SessionAware {&
&&& private U&
&&& private List testList = new ArrayList();&
&&& private Set testSet =new HashSet();&
&&& private Map testMap = new HashMap();&
&&& private List stus =
new ArrayList();&
&&& private M&
&&& private M&
&&& publicvoid setRequest(Map request) {&
&&&&&&& this.request =&
&&& publicvoid setSession(Map session) {&
&&&&&&& this.session =&
&&& publicstatic String getStatic(){&
&&&&&&& return"这是LoginAction中的一个静态方法";&
&&& public String getCommon(){&
&&&&&&& return"这是LoginAction中的一个普通方法";&
&&& @Override&
&&& public String execute() throws Exception {&
&&&&&&& if(user.getUsername().trim().equalsIgnoreCase("admin") && user.getPassword().equals("jadyer")){&
&&&&&&&&&&& testList.add("list11");&
&&&&&&&&&&& testList.add("list22");&
&&&&&&&&&&& testList.add("list33");&
&&&&&&&&&&& testList.add("list44");&
&&&&&&&&&&& testList.add("list55");&
&&&&&&&&&&&&&
&&&&&&&&&&& testSet.add("set11");&
&&&&&&&&&&& testSet.add("set22");&
&&&&&&&&&&& testSet.add("set33");&
&&&&&&&&&&& testSet.add("set22");&
&&&&&&&&&&& testSet.add("set11");&
&&&&&&&&&&&&&
&&&&&&&&&&& testMap.put("m11",
"map11");&
&&&&&&&&&&& testMap.put("m22","map22");&
&&&&&&&&&&& testMap.put("m33",
"map33");&
&&&&&&&&&&& testMap.put("m44","map44");&
&&&&&&&&&&& testMap.put("m55",
"map55");&
&&&&&&&&&&&&&
&&&&&&&&&&& stus.add(new Student("张三",88));&
&&&&&&&&&&& stus.add(new Student("李四",77));&
&&&&&&&&&&& stus.add(new Student("王五",66));&
&&&&&&&&&&& stus.add(new Student("马六",55));&
&&&&&&&&&&&&&
&&&&&&&&&&& request.put("req","这是通过OGNL中的#号获取的request属性范围的值");&
&&&&&&&&&&& session.put("ses",
"这是通过OGNL中的#号获取的session属性范围的值");&
&&&&&&&&&&& request.put("BB","这是通过OGNL中的#号获取的request属性范围的BB");&
&&&&&&&&&&& session.put("BB",
"这是通过OGNL中的#号获取的session属性范围的BB");&
&&&&&&&&&&& return SUCCESS;&
&&&&&&& }else{&
&&&&&&&&&&& return INPUT;&
&&&&&&& }&
阅读(...) 评论()}

我要回帖

更多关于 电脑 声音 分别 输出 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信