Struts2标签库和OGNL

学习内容

 Struts 2标签库

 OGNL

能力目标

 熟练使用Struts 2常用标签

 熟练使用OGNL

 


本章简介

前面我们编写的案例使用的都是HTML标签,这些标签并不能很好的与Struts 2框架结合,Struts 2Struts 1一样都自带了功能强大、成熟完善的标签库供我们使用,通过使用这些标签库可以大大提高开发效率和代码的可维护性。

其实Struts 2的标签库是建立在OGNL基础上的,OGNL是一种功能强大的表达式语言,通过简单的语法即可存取对象的属性、调用对象的方法、遍历等功能。

本章将学习OGNLStruts 2标签库,包括数据访问标签、控制标签

核心技能部分

6.1 OGNL

6.1.1 ActionContext

Struts 2中的ActionContextValueStackStackContext对象与OGNL密切相关,理解这三个对象时学习OGNL的前提。

在前面的学习中,我们已经在使用ActionContextValueStackStackContext对象了,这三个对象的作用及其之间的关系如图6.1.1所示。

Struts2标签库和OGNL_第1张图片

图6.1.1 ActionContext

1. ActionContext对象

ActionContextcom.opensymphony.xwork.ActionContext)是Action执行时的上下文。我们可以把上下文看作是一个容器,用于存放Action执行时需要使用的对象信息,例如请求的参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)等。在每次请求执行Action之前都会创建新的ActionContext。保存到ActionContext对象中的数据可以通过Struts2标签和OGNL表达式语言进行访问。

2. StackContext对象

StackContext对象是ActionContext上下文中的一个类型为java.utiI.Stack的实例。上面提到的请求参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)等对象,实际上都存储在ActionContext上下文中的StackContext对象中。

3. ValueStack对象

Struts2会为每一次Action的请求创建与之对应的ValueStack,并将所有Action属性数据存储到ValueStack中,再将ValueStack 暴露给视图页面,这样页面就可以直接访问Action中的属性值。

 

6.1.2 使用OGNL

OGNL即(Object-Graph Navigation Language),是对象图导航语言的缩写,它是一个开源项目,工作在视图层,用来取代页面中的Java脚本,简化数据访问操作。

OGNL一种EL功能强大的表达式语言。通过其简单一致的表达式语法,可以存取对象的属性、调用对象的方法、遍历以及进行类型转换等功能。Struts 2框架默认使用OGNL作为表达式语言。

1. 访问上下文中的数据

ActionContextStruts 2OGNL的上下文环境,即ActionContext中的数据(实际存储在StackContext中)都可以通过OGNL来访问。而ActionContext又包括RequestSessionValueStack等对象,所以通过OGNL也可以访问存储在这些对象中的数据。

ValueStackOGNL的根,同时由于OGNL上下文中的根对象可以直接访问,所以通过OGNL访问ValueStack中的数据时,不需要使用任何特殊的标记,而访问ActionConext中的其他对象时则需要使用#标记。Struts 2中提供了标签来显示OGNL上下文中的数据,在实际应用中通常分为以下四种情况:

1>Struts2会在ValueStack中查找名为uid的项,并输出其值。

2”#uid”>Struts2会在StackContext中查找名为uid的项,并输出其值。

3”#session.uid”>Struts2会在StackContcxt中的Session作用域中查找名为uid的项,并输出其值。这里的session也可以更换为requestapplication,以便在RequestApplication作用域中查找指定的项。

4”#attr.uid”/>Struts2会依次在StackContextPageRequestSessionApplication作用域内查找对应的uid中的值。

2. 访问JavaBean属性

通过OGNL可以非常方便的访问JavaBean,假设现在ValueStack中存在StudentAction,该Action的属性有nameage等。

(1) />Struts2会执行StudentAction对象的getName()方法来获得并输出name属性的值

(2) />Struts2会执行StudentAction对象的getAge()方法来获得并输出age属性的值

由于ValueStackOGNL的根,所以此时在使用标签时无需“#”标记。

3.  执行JavaBean方法

OGNL不仅可以自动执行getter方法,而且能够执行JavaBean的其他方法。更重要的是,还能够在执行方法的时候传入参数,OGNL执行的方法可以是静态方法和非静态方法。执行静态方法的格式为:@类的全类名@方法名(参数)。为了能够让OGNL执行静态方法,还必须在struts.xml配置文件中配置常量参数,才可以开启OGNL调用静态方法的功能,配置代码如下:

示例6.1演示了使用OGNL执行JavaBean方法。

示例6.1

(1)创建JavaBean ,命名为“OgnlInfo.java”。

public class OgnlInfo { 
//定义静态方法
public static String sayBye(String name)
{
return name + "再见!";
}
//定义非静态方法
public String sayHello(String name)
{
return name + "你好!";
}
}

(2)创建index.jsp

 


    <%
    	//实例化ognl对象
    	OgnlInfo ognlInfo = new OgnlInfo();
    	//将ognlinfo对象存入request作用域内
    	request.setAttribute("ognlInfo",ognlInfo);  
    
    
    %>
    
    
    
    
 
  

4.   OGNL操作符

OGNL表达式中能使用的操作符基本与Java中的操作符相同,除了能使用+、—、*/==!==等操作符之外,还能使用mod(取余)、innot in等操作符。

5. “%”号

%”号用于对属性为字符串类型的OGNL表达式的值进行计算,“%”符号在OGNL中的使用方法如下:

<%

String value="确定";

pageContext.setAttribute("val", value);

%>

不使用%符号,会按原样显示


使用%符号,会计算OGNL表达式的值

运行结果如图6.1.2所示。

Struts2标签库和OGNL_第2张图片 

6.1.2 %的使用

6. OGNL的集合操作

1)生成List类型的集合。具体语法为{e1,e2,e3,...}。此语法将直接生成一个list类型集合,该集合包含3个元素:e1,e2,e3。如果需要更多的元素,则多个元素之间以英文逗号隔开。

2)生成Map类型的集合。具体语法为#{key1,key2,key3...}。此语法将直接生成一个Map类型集合,该Map中每个key-value对象之间以英文冒号隔开,如果需要更多的元素,则多个元素之间以英文逗号隔开。

3)使用innot in 运算符。对于集合,OGNL提供元素符innot in。其中,in用于判断某个元素是否在指定集合内;not in 则用于判断某个元素是否不在指定的集合中。Innot in 的用法如下:

存在

不存在

(4)   获取集合的子集。OGNL允许通过某个规则取得集合的子集,取得子集时有以下三种操作符:

1)“?”操作符:取出所有符合选择逻辑的元素。

2)“^”操作符:取出符合选择逻辑的第一个元素。

3)“$”操作符:取出符合选择逻辑的最后一个元素。

假设现在Session中存在名为StudentList的集合,该集合存储了多个Student对象。Student类中存在一个age属性,这三种操作的语法如下:

#session.StudentList.{?#this.age>20}用于取出年龄大于20的子集合。

#session.StudentList.{^#this.age>20}用于取出第一个年龄大于20Student对象。

#session.StudentList.{$#this.age>20}用于取出最后一个年龄大于20Student对象。

6.2 Struts 2的标签库

Struts 2作为一个优秀的MVC框架,它为开发人员提供了一个功能强大、支持广泛、高扩展性的标签库,完全能满足Web页面复杂、多变的需求。

Struts 2的标签库大大简化了视图页面的代码编辑工作,提高了视图页面的维护效率。与Struts 1的标签库相比,Struts 2的标签库不但功能强大,而且更加简单易用。

Struts 1的标签库中,它分别提供了htmlbeanlogic等几个标签库。Struts 2标签库并没有严格的对标签进行分类,而是把所有标签整合到了一个标签库中。为了使初学者对Struts 2标签库能有更加清晰的认识,我们可以将Struts 2的标签库分成三大类(如图6.1.3所示):

 UI标签:主要用于生成HTML页面元素。

 UI标签:主要用于逻辑控制、数据访问等操作。

 Ajax标签:主要用于支持Ajax访问。

其中又可以把UI标签分为如下两类:

表单标签:主要用于生成HTML中的表单元素。

 非表单标签:主要包含一些常用的功能标签,例如显示日期或树形菜单。

对于非UI标签,也可以再细分为如下两类:

 数据访问标签:主要用于获得或输出ValueStack中的值。

 逻辑控制标签:主要用于数据访问中的条件分支、循环等流程控制。Struts2标签库和OGNL_第3张图片

6.1.3 标签库分类

使用Struts2标签库之前,也需要在JSP页面中导入。现在的Web应用一般都使用Servlet 2.4以上的规范,因此我们就无须在web.xml文件中对标签库进行配置,因为Servlet 2.4以上的规范可以直接读取标签库定义文件(TLD文件),在JSP页面中直接通过下面一行代码就可以导入Struts 2标签库。

<%@ taglib prefix="s" uri="/struts-tags" %>

 

6.2.1 数据访问标签

数据访问标签主要用来获得或输出各种数据的功能,常应用于显示Action中的属性以及国际化输出等场合。常见的数据标签主要包含以下几个:

 action标签:该标签用于在JSP页面中直接调用一个Action

include标签:该标签用于在JSP页面中包含其他页面资源。

 param标签:该标签用于设置一个参数,通常用作beanurl标签的子标签。

 property标签:该标签用于输出某个值。

 set标签:该标签用于设置一个新变量。

 text标签:该标签用于输出国际化消息。

 url标签:该标签用于生成一个URL地址。

 date标签:该标签用于格式化输出一个日期。

1. action标签

该标签可以在JSP页面中直接调用Action,并可以把执行的结果包含在标签的位置,这时需要指定Actionnamenamespace等属性。下面是该标签的几个主要属性:

 id属性:该属性用来指定被调用的Action的引用ID

 name属性:该属性用来指定被调用的Action的名字。

 namespace属性:该属性用来指定被调用的Action所在的namespace

 executeResult属性:该属性用来指定是否将Action的处理结果包含到当前页面中,该

属性的默认值是false,即不包含。

示例6.2

下面我们通过一个实例来介绍action标签的具体应用,首先编写一个简单的Action类,代码如下所示。

public class TagAction

{

private String name;

//省略getter和setter方法

public String exec()

{

return "ok";

}

}

通过上述代码可以看到该Action只包含了一个exec业务方法。下面是该Actionstruts.xml文件中的配置:


          

succ.jsp

    

下面是succ.jsp视图文件的代码:


调用Action!!

下面是使用action标签的s-action_Tag.jsp文件,代码如下所示:

下面调用Action,并将结果包含到本页面中。

上述代码使用标签调用了名字为tag1的逻辑action,并通过设置executeResult属性为true将结果包含到了本页面中。

Struts2标签库和OGNL_第4张图片 

6.1.4  action标签的应用

2. property标签

该标签的作用就是输出ActionContext中对象的值或者ActionJavaBean的属性值,通常结合OGNL使用。该标签有如下几个属性:

Ø value,该属性用来指定要输出的属性或OGNL表达式。

Ø default,该属性用来指定当value指定的属性值为null时输出的值。

Ø escape,该属性用来指定是否生成HTML代码,默认为true,表示在浏览器上输出表达式的值;如果为false,则把表达式的值作为HTML代码嵌入。

示例6.3

下面是应用property标签的简单示例。

    <%

     String url="超链接";

     pageContext.setAttribute("su",url);

     %>

     


     


     

运行效果如图6.1.5所示。

Struts2标签库和OGNL_第5张图片 

6.1.5 property标签

3. include标签

该标签用来将一个JSPServlet等资源包含到当前页面中,使用起来非常简单。该标签主要包含value属性,用来指定被包含的JSPServlet等资源文件。

示例6.4

接下来通过一个简单的例子来介绍include标签的具体应用,首先是被包含的include-file.jsp页面的代码:

<%@ page contentType="text/html; charset=GBK" language="java"%>
<%@taglib prefix="s" uri="/struts-tags"%>




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

这是被包含的页面

下面是包含include-file.jsp这个页面的s-include_Tag.jsp文件,代码如下所示: <%@ page contentType="text/html; charset=utf-8" language="java"%> <%@taglib prefix="s" uri="/struts-tags"%> 使用include标签来包含目标页面

使用include标签来包含目标页面



上述代码通过使用include标签包含了include-file.jsp页面,运行效果如图6.1.6所示。

Struts2标签库和OGNL_第6张图片 

6.1.6 include标签

4. set标签

该标签用来定义一个变量,并把这个变量放到指定的范围内,例如application范围、session范围等。该标签有以下一些常用属性:

Ø id属性:该属性用来定义变量的名字。

Ø scope属性:该属性用来定义变量被放置的范围,可选的值有applicationsessionrequestresponsepageStackContext

Ø value属性:该属性用来定义将要赋给变量的固定值或者另一个已经定义的变量。

示例6.5

下面我们通过一个示例来介绍set标签的具体应用,首先我们定义一个变量p,并把“小样儿”这个字符串赋值给它,然后定义另一个变量user,并把p赋值给user。代码如下所示:

使用set标签设置一个新变量


将p变量赋值给user变量并放入session范围内


运行效果如图6.1.7所示。

Struts2标签库和OGNL_第7张图片 

6.1.7 set标签的应用

5. url标签

该标签用来生成一个URL地址,我们也可以通过嵌套param标签来为URL指定发送参数。该标签主要有以下一些常用属性:

Ø includeParams属性:该属性用来指定是否在生成的URL参数中追加本页面接收到的请求参数,有3个值可供选择,none getall,分别代表“不包含”、“包含get方法传递的参数”和“所有的参数”。

Ø value属性:该属性用来指定要生成的URL的地址值。

Ø action属性:该属性用来指定一个Action作为URL地址值。

Ø namespace属性:该属性用来指定命名空间。

Ø method属性:该属性用来指定调用Action的方法名。

Ø includeContext属性:该属性用来指定是否把当前上下文包含在URL地址值中。

在上述属性中,actionvalue属性只需指定其一即可,如果两个都未指定,就以当前页面作为URL地址值。下面是一个应用URL标签的示例。

示例6.6


使用url标签


指定action属性,且使用param标签传入参数。

指定value属性,且使用param标签传入参数。


该页面的运行效果如图6.1.8所示。

 Struts2标签库和OGNL_第8张图片

6.1.8 URL标签的应用

6. date标签

date标签用来按指定的格式输出一个日期,还可以计算指定日期到当前时间的时差。该标签主要有如下一些属性:

Ø format属性:该属性用来指定日期输出的格式,例如“yyyy-MM-dd”。

Ø name属性:该属性用来指定要被格式化输出的日期值。

示例6.7

我们看下面的实例代码,用“年//日”的完整格式显示当前日期:


date标签的使用

<% java.util.Date now = new java.util.Date(); pageContext.setAttribute("now" , now); %>



该页面的运行效果如图6.1.9所示。

Struts2标签库和OGNL_第9张图片 

6.1.9 date标签的使用

7. 标签

用来创建JavaBean实例,创建JavaBean实例的时候,可以在该标签内部使用标签为该JavaBean实例传入属性。其常见属性如下:

Ø Id:指定创建JavaBean的引用id.

Ø name:指定需要实例化的JavaBean的实现类

标签用法的如下:

(1) 创建JavaBean,命名为Book.java

public class Book { 
private String isbn;
private String name;
private double price;
public Book() {
super();
}
public Book(String isbn, String name, double price) {
super();
this.isbn = isbn;
this.name = name;
this.price = price;
}
public String[] getAllBooks()
{
String[] books = {"JAVA","JSP","ASP.NET","C#"};
return books;
}
}

(2) 创建Jsp页面.

book对象属性值:

isbn:

name:

调用book对象的getAllBooks方法获取全部书籍列表:

${book }






book对象属性值:
isbn:
name:
调用book对象的getAllBooks方法获取全部书籍列表:
${book }


6.2.2 逻辑控制标签

Struts 2的逻辑控制标签主要用于程序流程的逻辑控制,例如选择、分支、循环等操作,常见的逻辑控制标签主要有以下五个标签:

Ø if标签:用于控制选择流程的标签。

Ø elseif标签:与if标签结合使用。

Ø else标签:与if标签结合使用。

Ø generator标签,用于将一个字符串解析成一个集合。

Ø iterator标签:这是一个迭代器,用于将集合进行循环输出。

 

1. if/elseif/else标签

if/elseif/else这三个标签通常结合使用,都是用于进行程序分支逻辑控制,跟多数编程语言中的if/elseif/else语句的功能相似,test属性用来设置比较表达式,具体语法如下所示:

标签体

标签体

标签体

下面是一个实例的代码片段:

示例6.8



    成绩优秀


    成绩良好


成绩合格


    成绩不合格


上述代码先通过set标签定义了一个名为dengji的属性并赋值为85,然后通过if/elseif/else标签根据dengji属性的值的范围来控制输出成绩的评价是“优秀”、“良好”、“合格”或“不合格”。运行效果如图6.1.10所示。

Struts2标签库和OGNL_第10张图片 

6.1.10 if/elseif/else标签的应用

 

2. iterator标签

该标签主要用于对集合类型的变量进行迭代输出,这里的集合类型包括ListSet、数组和Map等。该标签主要有三个属性:

Ø value属性:该属性用来指定被迭代输出的集合,被迭代的集合可以由OGNL表达式指

定也可以通过Action返回一个集合类型的变量。

Ø id属性:该属性用来指定集合中元素的ID属性。

Ø status属性:该属性可以实现一些附加功能,详见后面讲解。

下面是一个实例的代码片段:

示例6.9

iterator的用法

 <%

  List bookList=new ArrayList();

  bookList.add("Spring3.0技术宝典");

  bookList.add("Struts2权威指南");

  bookList.add("JavaScript技术大全");

  bookList.add("JSP技术详解");

  bookList.add("Ajax实战");

  pageContext.setAttribute("bookList",bookList);

  %>

 

 

  •  

    上述代码通过iterator标签的value属性指定了一个集合,并指定它的id属性为bookname,然后就可以通过输出集合中每个元素的值。该页面的运行效果如图6.1.11所示。

    Struts2标签库和OGNL_第11张图片 

    6.1.11 iterator标签的应用

    iterator标签的status属性很有用,利用它可以实现一些很实用的功能。指定该属性后,每次迭代都会以此属性为名称创建一个IteratorStatus的实例对象,该实例对象包含了以下几个属性:

    Ø count:返回当前迭代了几个元素。

    Ø index:返回当前迭代元素在集合中的索引值。

    Ø even:返回当前迭代元素的索引值是否为偶数。

    Ø odd:返回当前迭代元素的索引值是否为奇数。

    Ø first:返回当前迭代元素是否是第一个元素。

    Ø last:返回当前迭代元素是否是最后一个元素。

    我们看下面的代码片段:

     

    style="background-color:#bbbbbb">

     

    上述代码以表格的形式输出了集合中的每个元素和元素的索引值,并通过iterator标签的status属性控制奇数行的背景色,运行效果如图6.1.12所示。

    Struts2标签库和OGNL_第12张图片 

    6.1.12 status属性的应用

     

     

    3. generator标签

     

    该标签可以将一个字符串按指定的分隔符分隔成多个子串,新生成的多个子串可以使用iterator标签进行迭代输出。generator标签常见的属性如下:

    Ø count属性:该属性用来指定所生成集合中元素的总数。

    Ø separator属性:该属性用来指定分隔符。

    Ø converter属性:该属性指定了一个转换器,该转换器负责将集合中的每个字符串转换成

    对象。

    Ø id属性:如果指定了该属性,则新生成的集合会以此为名称,被放在pageContext中。

    我们来看下面的代码片段:

    示例6.10

     

     

    迭代输出由generator标签产生的集合

    上述代码使用generator标签把一个字符串按逗号进行了分割,并把产生的集合按照指定的“generList”为id保存在pageContext中,接下来使用iterator标签迭代输出generList集合中的元素,运行效果如图6.1.13所示。

    Struts2标签库和OGNL_第13张图片 

    6.1.13 generator标签的应用

     

     


    本章总结

    Ø ActionContext对象。ActionContextcom.opensymphony.xwork.ActionContext)是Action执行时的上下文。我们可以把上下文看作是一个容器,用于存放Action执行时需要使用的对象信息。

    Ø StackContext对象。请求参数(Parameter)、会话(Session)、Servlet上下文(ServletContext)等对象,实际上都存储在ActionContext上下文中的StackContext对象中。

    Ø ValueStack对象。Struts2会为每一次Action的请求创建与之对应的ValueStack,并将所有Action属性数据存储到ValueStack中,再将ValueStack 暴露给视图页面,这样页面就可以直接访问Action中的属性值。

    Ø OGNL即(Object-Graph Navigation Language),是对象图导航语言的缩写,它是一个开源项目,工作在视图层,用来取代页面中的Java脚本,简化数据访问操作。

    1访问上下文中的数据。ValueStackOGNL的根,同时由于OGNL上下文中的根对象可以直接访问,所以通过OGNL访问ValueStack中的数据时,不需要使用任何特殊的标记,而访问ActionConext中的其他对象时则需要使用#标记

    2)执行JavaBean方法。OGNL不仅可以自动执行getter方法,而且能够执行JavaBean的其他方法。更重要的是,还能够在执行方法的时候传入参数,OGNL执行的方法可以是静态方法和非静态方法。

    Ø Struts 2的标签库

    1Struts2标签库的分类。我们可以将Struts 2的标签库分成三大类:UI、非UIajax标签,其中UI标签又可分为表单 、非表单标签,非UI标签可分为数据访问、逻辑控制标签。

    2)数据访问标签。常见的数据标签主要包含action、includeparam propertysettexturldate等。

    3)逻辑控制标签。逻辑控制标签主要用于程序流程的逻辑控制,例如选择、分支、循环等操作,常见的逻辑控制标签主要有五个标签:if elseifelse generator iterator


    任务实训部分

    1:查询管理员

    训练技能点

    Ø OGNL

    Ø property标签

    Ø iterator标签

      需求说明

    在前面章节的任务实训部分,我们实现了管理员的增、删、改、查等功能,现在要求在查询管理员时,使用OGNLiteratorproperty等标签显示查询到的管理员列表,并且只显示密码长度小于3的管理员信息。

      关键代码

      

        

        

        

      

    2:查询图书

    训练技能点

    Ø OGNL

    Ø property标签

    Ø iterator标签

      需求说明

    在前面章节的任务实训部分,我们实现了查询图书的案例,现在要求使用OGNLiteratorproperty等标签显示查询到的图书列表,并且设置偶数行的背景色为灰色。

    3:查找客户信息

    训练技能点

    Ø OGNL

    Ø 数据访问标签

    Ø 控制标签

      需求说明

    实现输入客户编号时,查找对应的客户是否存在,若不存在,则输出无法查找到此客户的提示;若存在,则进一步显示客户的订单信息。

     

     

      实现思路

    (1) 创建用于描述订单的实体类,命名为Order.java

     

    public class Order implements Serializable{

    //订单Id

    private String orderId;

    //订单日期

    private Date orderDtm;

    //订单状态 0:禁用 1:启用

    private int state;

    //无参构造函数

    public Order() {

    super();

    // TODO Auto-generated constructor stub

    }

    //有参构造函数

    public Order(String orderId, Date orderDtm, int state) {

    super();

    this.orderId = orderId;

    this.orderDtm = orderDtm;

    this.state = state;

    }

    //getter setter省略......

    }

    (2) 创建用于描述客户的实体类,命名为Cust.java

    public class Cust implements Serializable{

    //客户编号

    private String custId;

    //客户名称

    private String custName;

    //电话

    private String tel;

    //订单集合

    private List orders = new ArrayList();

    //无参构造函数

    public Cust() {

    super();

    // TODO Auto-generated constructor stub

    }

    //有参构造函数

    public Cust(String custId, String custName, String tel) {

    super();

    this.custId = custId;

    this.custName = custName;

    this.tel = tel;

    }

    //getter setter省略......

    }

    (3) 创建用于处理业务逻辑的JavaBean,命名为CustService.java

    public class CustService {

    //定义客户列表

    private static List custList = new ArrayList();

    //静态构造器,初始化客户和订单信息

    static{

    try {

    //用于格式化日期

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    //创建客户c1

    Cust c1 = new Cust("c001", "张三", "110");

    Order c1Order1  = new Order("OR001", sdf.parse("2012-01-01"), 0);

    Order c1Order2  = new Order("OR002", sdf.parse("2012-01-02"), 0);

    Order c1Order3  = new Order("OR003", sdf.parse("2012-01-03"), 1);

    //添加订单到c1客户

    c1.getOrders().add(c1Order1);

    c1.getOrders().add(c1Order2);

    c1.getOrders().add(c1Order3);

    //创建客户c2

    Cust c2 = new Cust("c002", "李四", "114");

    Order c2Order1  = new Order("OR004", sdf.parse("2012-01-04"), 0);

    Order c2Order2  = new Order("OR005", sdf.parse("2012-01-05"), 0);

    Order c2Order3  = new Order("OR006", sdf.parse("2012-01-06"), 1);

    //添加订单到c2客户

    c2.getOrders().add(c2Order1);

    c2.getOrders().add(c2Order2);

    c2.getOrders().add(c2Order3);

    //创建客户c3

    Cust c3 = new Cust("c003", "王五", "119");

    Order c3Order1  = new Order("OR007", sdf.parse("2012-01-07"), 0);

    Order c3Order2  = new Order("OR008", sdf.parse("2012-01-08"), 0);

    Order c3Order3  = new Order("OR009", sdf.parse("2012-01-09"), 1);

    //添加订单到c3客户

    c3.getOrders().add(c3Order1);

    c3.getOrders().add(c3Order2);

    c3.getOrders().add(c3Order3);

    //把客户添加到List列表中

    custList.add(c1);

    custList.add(c2);

    custList.add(c3);

    } catch (ParseException e) {

    // TODO Auto-generated catch block

    e.printStackTrace();

    }

    }

    //

    public static Cust findCustById(String custId){

    //循环每个客户

    for (Cust cust : custList) {

    //循环每个客户

    if(cust.getCustId().equals(custId)){

    return cust;

    }

    }

    //如果找不到则返回空

    return null;

    }

    //

    public static List getCustOrders(String custId){

    //循环每个客户

    for (Cust cust : custList) {

    //循环每个客户

    if(cust.getCustId().equals(custId)){

    //返回对应客户的订单

    return cust.getOrders();

    }

    }

    //如果找不到则返回空

    return null;

    }

    }

    (4) 创建用于处理业务逻辑的控制器Action,命名为CustAction.java

    public class CustAction extends ActionSupport {

    //封装用户的id

    private String custId;

    //查找订单

    public String findOrder()throws Exception{

    //调用业务层

    List orderList = CustService.getCustOrders(custId);

    //将订单放到request

    ServletActionContext.getRequest().setAttribute("orderList", orderList);

    //返回input逻辑视图

    return SUCCESS;

    }

    /**

     * @return

     */

    public String findCust() {

    // TODO Auto-generated method stub

    //调用业务逻辑

    Cust cust = CustService.findCustById(custId);

    if(cust!=null){

    //cust存储到session

    ServletActionContext.getRequest().getSession().setAttribute("cust", cust);

    }

    else{

    //否则给msg赋值,准备弹出对话框。

    ServletActionContext.getRequest().setAttribute("msg","");

    }

    //返回input逻辑视图

    return SUCCESS;

    }

    //getter setter方法

    public String getCustId() {

    return custId;

    }

    public void setCustId(String custId) {

    this.custId = custId;

    }

    }

    (5) 创建Jsp页面,命名为jd1.jsp

    <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

    <%@ taglib uri="/struts-tags" prefix="s" %>

    <%

    String path = request.getContextPath();

    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

    %>

     

      

       

        My JSP 'jd1.jsp' starting page

        

      

      

      

       

       

        完成客户查找功能:


        客户编号:

        查找">

       

       

       


        编号:${cust.custId}

        姓名:${cust.custName}

        联系方式:${cust.tel}
    查看订单

       


       

       

       

       


       

       

       

       

       

       

       

       

       

       

       

       

       

       

       

    订单编号 订单日期 订单状态
    ${row.orderId } MMdd"/> ${row.state==0?"禁用""启用" }

       

       

       

       

       

       

        ${msg }

      

    (6) 配置Struts.xml文件。

    /jd1.jsp

    (7) 运行jd1.jsp页面,效果如图6.2.1所示。

    Struts2标签库和OGNL_第14张图片 

    6.2.1 运行jd1.jsp

    在图6.2.1中输入需要查找的客户编号。

    若编号不存在,系统将会显示提示消息。 如图6.2.2所示。

     Struts2标签库和OGNL_第15张图片

    6.2.2 用户不存在

    若编号存在,系统将显示该客户对应的详细信息,如图图6.2.3所示。

     Struts2标签库和OGNL_第16张图片

    6.2.3 查找客户并显示详细信息

    在图6.2.3中单击“查看订单”按钮,系统将显示客户对应的订单信息,如图6.2.4所示。

     Struts2标签库和OGNL_第17张图片

    6.2.4显示客户的订单信息


    巩固练习

    一、选择题

    1. 以下关于OGNL的说法正确的是()。

    A. ActionContextOGNL的上下文环境

    B. ValueStackOGNL的根

    C. StackContextOGNL的上下文环境

    D. ActionContextOGNL的根

    2. 假设session中存在名为uid的属性,通过OGNL访问该属性的代码是()。

    A. #uid

    E. uid

    F. #session.uid

    G. ${session.uid}

    3. 关于“#session.users.{?#this.age>20}”的OGNL代码所表示的意思是()。

    A. users集合中取出第一个年龄大于20的对象

    H. users集合中取出所有年龄大于20的对象

    I. users集合中取出最后一个年龄大于20的对象

    J. 该代码有语法错误

    4. 假设页面中存在这样一行代码“”,则下面说法正确的是()。

    A. 编译错误

    K. 页面不显示任何内容

    L. 输出ValueStack中最上面的对象

    M. 以上说法都不正确

    5. 以下()不属于Struts 2的数据访问标签。

    A. set

    B. date

    C. text

    D. textfield 

    你可能感兴趣的:(基础框架,道本自然)