Java ee 企业应用开发:第4章 注册、登录和注销_第1页
Java ee 企业应用开发:第4章 注册、登录和注销_第2页
Java ee 企业应用开发:第4章 注册、登录和注销_第3页
Java ee 企业应用开发:第4章 注册、登录和注销_第4页
Java ee 企业应用开发:第4章 注册、登录和注销_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第4章 注册、登录和注销4.1开发步骤4.2 知识点:DAO模式4.3 知识点:Hibernate:Query接口4.4 知识点:Hibernate:Query接口4.5 知识点:Struts 2:Action 4.6 知识点:Struts 2:OGNL表达式 4.7 知识点:Struts 2:标签库第4章 注册、登录和注销用户注册是网上书店的基本功能之一。用户如果想从网上书店购买商品,必须有一个网上书店的账号,用户可以通过“注册”功能获得账号,注册页面效果如图4-1所示。当注册成功之后,会进入注册成功页面;如果注册信息不对,则显示注册失败。图4-1 用户注册界面第4章 注册、登录和注销当用户

2、购物完成离开网站的时候,应该让用户注销,关闭会话。在用户没有登录的时候,菜单栏目应该显示包含“登录”;当用户登录以后,菜单栏目显示包含“注销”。效果如图4-3、图4-4所示。图4-3 用户没有登录时的菜单图4-4 用户登录以后的菜单4.1开发步骤在J2EE的开发中,服务器端Web应用程序分为若干层。每层在处理程序上都有一项明确的责任。不应该将它们混合,并且每层都要与其它层分开,各个层之间通过通信接口联系。如图4-5所示。Spring容器客户端浏览器数据库Web服务器(Tomcat)ActionServiceDAO核心控制器JSP视图JavaBeans图4-5 J2EE的分层结构4.1开发步骤

3、DAO层DAO层完成连接数据库增删改等实现细节,例如SQL语句怎么写、怎样把对象放入数据库等等。DAO将底层数据访问操作和业务层逻辑分离开,对业务层提供面向对象的数据访问接口。而业务层调用DAO接口实现各种业务方法,如验证用户密码是否正确。 Service业务层业务层位于上层的表示层和控制层,依赖于下层的业务层的实现(DAO),而下层业务层不应该依赖于上层的表示层和控制器的实现。业务层提供了处理应用程序的业务逻辑和业务校验,如验证用户登录系统的密码是否正确;提供了管理事务,允许与其它层相互作用的接口。Servcie层是面向功能的,一个功能模块比如说银行等级并完成一次存款,把请求给Service

4、层,Service层将这个功能分解成许多步骤调用底层的DAO来实现这次存款。有时,会看到Servcie层和DAO层的方法是类似的,是因为Service层的需求不是很复杂,不用再对Service层完成太多包装或者处理就可以直接调用DAO的方法。 Action控制层 控制层的控制器Action接受用户的输入并调用业务层的业务方法和表示层的组件去完成用户的请求。当Web应用单击Web页面中的提交按钮来发送HTML表单时,控制器接受请求并调用相应的业务层方法去处理请求,然后调用相应的视图来显示业务层返回的数据。4.1开发步骤Struts中的控制器由ActionServlet类和Action类来实现,A

5、ctionServlet主要负责接受HTTP请求信息,根据配置文件struts-config.xml的配置信息,把请求转发给适当的Action对象。如果该Action对象不存在,ActionServlet会先创建这个Action对象,Action充当用户请求和业务逻辑处理之间的适配器,其功能是将请求与业务逻辑分开,Action根据用户请求调用相关的业务逻辑组件,Action类侧重控制应用程序的流程,而不是实现应用程序的逻辑。 Spring服务器各种组件的生成都是由Spring容器来控制,被看作是Spring中的一个Bean,它可享受Spring提供的所有服务(依赖注入、实例管理、事务管理等)。

6、 JSP视图层视图是用户看到并与之交互的界面,视图向用户显示相关的数据,并能接受用户的输入数据,但不能进行任何实际的业务处理。视图可以向业务层查询业务状态,但不能改变业务层,视图还可以接受模型发出的数据更新事件,从而对用户界面进行同步更新。视图其实就是一组JSP文件,在这些JSP文件中没有业务逻辑,也没有业务层信息,只有标签,这些标签可以是标准的JSP标签或客户端标签,如Struts标签库中的标签。使用框架的最大好处是不仅在于减少重复开发工作量,缩短开发时间,降低开发成本,同时,使程序设计更加合理,程序运行更加稳定等。基于这些原因,基本上现在开发中,都会选择某些合适的开发框架,从而达到快捷,高

7、效的目的。4.1.1 注册 开发为5个步骤:步骤1 DAO步骤2 Service步骤3 Action步骤4 Spring步骤5 JSP具体步骤如下:步骤1 DAODAO层所涉及的类,接口如图4-6所示。图4-6 DAO层主要类图4.1.1 注册其中,IUserDAO接口中的saveUser()用于将一个User对象保存到数据库中。UserDAO类中的saveUser()具体实现了这个方法。BaseDAO是将对数据库进行的操作进行封装,这样,在UserDAO中就可以直接使用Session。在这里使用了DAO模式。这三个类和接口在工程中的位置如图4-7所示。图4-7 文件在项目中的位置4.1.1

8、注册创建IUserDAO.java,代码如下:/包名为org.apex.bookstore.daopackage org.apex.bookstore.dao;/引入另一个包org.apex.bookstore.vo的User类import org.apex.bookstore.vo.User;/定义用户DAO的接口IUserDAOpublic interface IUserDAO /保存用户注册的信息public void saveUser(User user);4.1.1 注册创建BaseDAO.java,代码如下:/包名为org.apex.bookstore.daopackage org

9、.apex.bookstore.dao;/引入需要的类import org.hibernate.SessionFactory;import org.hibernate.classic.Session;/对一些基本操作进行封装,在它的子类中可以直接使用public class BaseDAO private SessionFactory sessionFactory;public SessionFactory getSessionFactory()return sessionFactory;public void setSessionFactory(SessionFactory sessionF

10、actory)this.sessionFactory=sessionFactory;public Session getSession()Session session=sessionFactory.openSession();return session;4.1.1 注册创建UserDAO.java,代码如下:/包名org.apex.bookstore.dao.impl;package org.apex.bookstore.dao.impl;/引入需要的类import java.util.List;import org.apex.bookstore.dao.BaseDAO;import or

11、g.apex.bookstore.dao.IUserDAO;import org.apex.bookstore.vo.User;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.Transaction;public class UserDAO extends BaseDAO implements IUserDAO /保存用户的信息到数据库中public void saveUser(User user)Session session=getSession(); /将user对象保存到数据库中T

12、ransaction tx=session.beginTransaction();session.save(user);mit();session.close();4.1.1 注册步骤2 ServiceService层主要用于处理各种业务。主要的类和接口是:IUserService,UserService,如图4-8所示。其中,IUserService是一个接口,定义了两个方法,saveUser()方法用于将User对象存储到数据库中。validateUser()方法用于验证用户输入的名称和密码是否正确。UserService实现IUserService接口,通过IUserDAO类,实现了这两

13、个方法。图4-8 Service层的主要类4.1.1 注册文件IUserService.java和UserService.java在项目中的位置如图4-9所示。图4-9 文件在项目中的位置4.1.1 注册IUserService.java代码如下:/包名org.apex.bookstore.servicepackage org.apex.bookstore.service;/引入需要的类import org.apex.bookstore.vo.User;public interface IUserService /用户注册时,保存用户的信息public void saveUser(User u

14、ser); /用户登陆时,验证用户的信息public User validateUser(String username,String password);UserService.java代码如下:/包名org.apex.bookstore.service.implpackage org.apex.bookstore.service.impl;/引入需要的类import org.apex.bookstore.dao.IUserDAO;import org.apex.bookstore.service.IUserService;import org.apex.bookstore.vo.User;

15、4.1.1 注册public class UserService implements IUserService /属性userDAO,service层调用DAO层完成相关操作private IUserDAO userDAO;/保存用户注册时的信息public void saveUser(User user)this.userDAO.saveUser(user); / 用户登录时,用于验证用户的信息public User validateUser(String username,String password)return null; /属性userDAO的get方法 public IUser

16、DAO getUserDAO()return userDAO; /属性userDAO的set方法public void setUserDAO(IUserDAO userDAO)this.userDAO=userDAO;4.1.1 注册步骤3 ActionUserAction类含有是三个方法,如图4-10所示。register()方法用于用户注册,execute()方法用于用户登录,logout()方法用于用户注销。这些方法的实现依赖于Service层,在属性中,有一个userService属性,它的类型是IUserServe。图4-10 Action类图4.1.1 注册UserAction.j

17、ava文件在项目中的位置如图4-11所示。图4-11 文件在项目中的位置4.1.1 注册UserAction.java代码如下:struts.xml文件中配置UserAction,struts.xml在项目中的位置如图4-12所示。图4-12 struts.xml在项目中的位置 /register_success.jsp 4.1.1 注册注意在上面代码中,对应名为register.action的动作,对应的类为userAction,方法为该类的register方法。但是,其实对应的类为org.apex.bookstore.action.UserAction。这里,主要是因为在后面将使用Spri

18、ng IoC功能,所以,这里为org.apex.bookstore.action.UserAction起了一个别名:userAction。步骤4 Spring各种组件的生成都是由Spring容器来控制。Spring的配置文件applicationContext.xml项目中的位置,如图4-13所示。图4-13 applicationContext.xml在项目中的位置4.1.1 注册applicationContext.xml代码如下: 步骤5 JSP层创建注册视图register.jsp,注册成功视图register_success.jsp。register.jsp、register_suc

19、cess.jsp文件所在的位置如图4-14所示。图4-14 文件在工程中的位置4.1.1 注册创建register.jsp文件,代码如下: 用户名*: 密码*: 性别: 年龄: 创建注册成功页面register_success.jsp文件,代码如下: 您好! 用户欢迎您注册成功 登录 4.1.2 登录开发为5个步骤:步骤1 DAO步骤2 Service步骤3 Action步骤4 Spring步骤5 JSP具体步骤如下: 步骤1 DAODAO层所设计的类和接口如图4-6所示。其中,IUserDAO接口的validateUser()用于验证用户,UserDAO类中的validateUser()实现

20、了这个方法。根据用户输入的用户名和密码到数据库中查找相关用户。如果找到,返回记录;如果没有找到,返回空记录。这两个类和接口在工程中的位置如图4-5所示。IUserDAO.java代码如下: package org.apex.bookstore.dao; /包名org.apex.bookstore.daoimport org.apex.bookstore.vo.User; /引入相关类public interface IUserDAO public void saveUser(User user); /用户注册时,保存用户信息public User validateUser(String use

21、rname,String password); /用户登录时,验证用户信息4.1.2 登录UserDAO.java代码如下: 步骤2 Service这一层主要涉及到IUserService接口和UserService类,如图4-8所示。在IUserServie接口中定义了validateUser()方法,用于用户登录验证。在类UserService类中具体实现了这个类。两个文件在工程中的位置如图4-9所示。创建IUserService.jsp文件,代码如下:package org.apex.bookstore.service; /包名org.bookstore.serviceimport or

22、g.apex.bookstore.vo.User; /引入相关类public interface IUserService public void saveUser(User user); /保存用户信息public User validateUser(String username,String password); /验证用户信息创建UserService.java文件,代码如下:4.1.2 登录 步骤3 ActionUserAction类 execute()方法用于用户登录,如图4-10所示。方法的实现依赖于Service层,在属性中,有一个userService属性,它的类型是IUse

23、rServe。类所在工程中的位置如图4-11所示。修改UserAction.java文件,增加execute()方法的实现,代码如下: 步骤4 Spring修改applicationContext.xml文件,Spring容器applicationContext.xml,前面已经配置好。4.1.2 登录 步骤5 JSP创建login.jsp文件,文件的位置如图4-14所示。 用户登录 用户名: 密码: 4.1.3 注销开发为3个步骤:步骤1 Action步骤2 Spring步骤3 JSP具体步骤如下: 步骤1 ActionUserAction类 logout()方法用于用户登录,如图4-10所

24、示。方法的实现依赖于Service层,在属性中,有一个userService属性,它的类型是IUserServe。类所在工程中的位置如图4-11所示。修改UserAction.java文件,添加logout()方法,用于注销,代码如下:public String logout() throws Exception/用户注销Map session=ActionContext.getContext().getSession();session.remove(user); return SUCCESS;配置struts.xml文件,代码片段如下/index.jsp/action4.1.3 注销 步骤

25、2 SpringSpring已经在前面章节配置好,applicaionContext.xml代码片段如下:4.1.3 注销 步骤3 JSPhead.jsp用于存放网页的头部信息,如菜单等。菜单根据用户是否登录有不同的显示。文件的位置如图4-14所示。修改head.jsp文件,代码片段如下:首页 登录 注销注册联系我们网站地图4.2 知识点:DAO模式 数据源不同数据访问也不同。根据存储的类型(关系数据库,面向对象数据库,文件等等)和供应商实现不同,持久性存储(比如数据库)的访问差别也很大。比如,在一个应用系统中使用JDBC API对Oracle数据库进行连接和数据访问,这些JDBC API与S

26、QL语句分散在系统各个程序文件中,当需要其他RDBMS(如INFORMIX)时,就面临重写数据库连接和访问数据的模块。一个软件模块(类,函数,代码块等)在扩展性方面应该是开放的,而在更改性方面应该是封闭的,这就是开闭原则。要实现这个原则,在软件面向对象设计时要精良考虑接口封装机制,抽象机制和多态技术。这里的关键就是将这个软件模块的功能部分和不同的实现细节清晰地分开来。在数据库访问对象中,应该运用这个原则。在数据库编程的时候,经常遇到这种情况,一个用户的数据访问对象,里面的操作方法有insert,delete,update,select等,对不同数据库其实现的细节是不相同的。因此,不太可能针对每

27、种类型的数据库做一个通用的对象来实现这些操作。但是,可以定义一个用户数据访问对象的接口IUserDAO,提供inser,delete,update,select等抽象方法。不同类型的数据库的用户访问对象实现这个接口就可以了。如图4-15所示。4.2 知识点:DAO模式MySqlImpSQLServerImpOracleMySqlImpClientIUserDAOinsert()delete()update()select()图4-15 DAO4.3 知识点:HIBERNATE:QUERY接口4.3.1 绑定参数1使用“?”指定参数通过Query接口可以先设定查询参数,然后通过setXXX()等

28、方法,将指定的参数值填入,而不用每次都编写完整的HQL。来看下面的例子Query query=session.createQuery(from Student s where s.age? and like ? )query.setInteger(0,25); /设置age?中的问号为整型25query.setString(1, %clus%); /设置name like ?中的问号为字符串%clus%2使用“:”后跟变量的方法设置参数可以使用命名参数来取代使用“? ”设置参数的方法,这可以不用依据特定的顺序来设定参数值,比如上面的代码可以写为:Query query=session.crea

29、teQuery(from Student s where s.age:minAge and like:likeName);query.setInteger(minAge,25); /设置:号后的minAge变量值query.setString String(ikeName,%clus%); /设置:号后的likeName变量值使用命名参数时,在建立Query时先使用“:”后跟着参数名,然后就可以在setXXX()方法中直接指定参数名来设定参数值。命名参数的好处如下: 命名参数不依赖于它们在查询字符串中出现的顺序 在同一个查询中可以使用多次 可读性好4.3.1 绑定参数 3setParamete

30、r()方法setParameter()方法的全称是setParameter(String paramName,实例,实例类型)。这个方法可以绑定任意类型的参数。在实际应用中,Hibernate可以根据类实例推断出绝大部分对应的映射类型,因此setParameter()中的第三个参数也可以不要。例子如下:String hql=from User u where u.username=? and u.password=?;Query query=session.createQuery(hql);query.setParameter(0,username);query.setParameter(1,

31、 password);4.3.2 LIST()方法4.3.2 list()方法Query的list()方法用于取得一个List类的示例,此示例中包括的可能是一个Object集合,也可能是Object数组集合。最常见的是使用list()取得一组符合条件实例对象,如下程序所示:Query query=session.createQuery(from Student s where s.age20;List list=query.list();for(int i=0;ilist.size();i+)Student stu=(Student)list.get(i); System.out.printl

32、n(stu.getName();4.4 知识点:HIBERNATE:QUERY接口在Hibernate中,数据查询与检索机制很完善。相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制。其中包括: Criteria Query(条件查询API) Hibernate Query Language(HQL) SQL传统的SQL语句采用的是结构化的查询方法,而这种方法对于查询以对象形式存在的数据却无能为力。Hibernate为用户提供了一种类似于SQL的语言,Hibernate查询语言(HQL)。和SQL不同的是,HQL是一种面向对象的查询语言,它可以查询以对象形式存在的数据。在Hib

33、ernate中不提倡使用SQL。虽然Criteria提供了更加符合面向对象编程模式的查询封装模式,但HQL提供了更加强大的功能。在官方开发手册中,也将HQL作为推荐的查询方式。这里,介绍HQL检索语言。4.4.1实体查询: 有关实体查询技术,如下面的例子:String hql=from User;Query query=session.createQuery(hql);List list=query.list();上面的hql=from User,将取出use表的所有对应记录,对应SQL为 select from user。也可以在hql中采用全路径名,如:”from com.apex.boo

34、kstore.vo.User”hql子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。如果需要取出名为Tom的用户的记录,可以通过hql语句加以限定:String hql=”from User as user where =Tom ”;Query query=session.createQuery(hql);List userList=query.list();这里引入两个子句“as”和“where”,as子句为类名创建了一个别名,而where子句指定了限定条件。其中as子句可忽略,如:”from User user where =Tom ”where子句中,可以通过比较操作符

35、指定甄选条件,如:=,=,20from User user where user.age between 20 and 30from User user where user.age in (18,28)from User user where is nullfrom User user where like T%与SQL相同,通过and、or等逻辑连接符组合各个逻辑表达式:from User user where (user.age20) and ( like T%)4.4.2 实体的更新和删除在Hibernate 2之前版本中,HQL仅用于数据查询。而在Hibernate 3中,HQL具备

36、了更加强大的功能。实体更新与删除就是其中的主要特性之一。delete和update子句是Hibernate 3中新引入的HQL子句。通过delete、update子句,数据的删除与更新操作可以以更加灵活的方式实现。在Hibernate 2中,完成用户年龄属性的更新,必须通过以下代码实现:/加载ID=1的用户记录User user=(User)session.get(User.class,new Integer(1);user.setAge(new Integer(18);/通过Session.save方法保存session.save(user);以上代码完成了ID=1的用户数据的更新。如果需要

37、将库表中所有的用户的年龄设置为18,该如何操作呢?别无他法,只能首先利用HQL“from User”查询出所有的实体,设置年龄属性后再逐一保存。Hibernate 3 HQL提供了更加灵活边界的实现方式(bulk delete/update):String hql=update User set age=18 wher id=1;Query query=session.createQuery(hql);query.executeUpdate();4.4.2 实体的更新和删除这段代码完成与上例同样的功能。对于单个对象的更新也许代码量并没有减少太多,但如果对于批量更新操作,其便捷性及性能的提高就相

38、当可观。以下代码将所有用户的年龄属性更新为18:String hql=update User set age=18;Query query=session.createQuery(hql);int ret=query.executeUpdate();Hibernate 3 HQL delete子句的使用同样非常简单。以下代码删除了所有年龄大于18的用户记录:String hql=delete User where age18;Query query=session.createQuery(hql);int ret=query.executeUpdate();4.5 知识点:STRUTS 2:A

39、CTION4.5.1 概述Struts 2控制器最重要的组成部分就是Action,它是WEB框架的控制中心,是连接模型和视图的桥梁和纽带。Action接受来自视图层的请求,并接受请求参数,同时负责调用模型层方法来完成业务逻辑的处理,最后控制程序的流程,选择一个合适的视图将结果显示给客户。4.5.2 ACTION的定义Struts 2中的Action只需要在一个普通的类中定义一个方法,如:public class XXXAction public String method() return “return Value”; XXXAction:Action的类名,习惯上以Action结尾,更容易

40、阅读和理解Method:用于接受请求的方法,名称可以自定义,默认情况下,会调用execute()方法。该方法不能带任何参数,且必须返回字符串类型。Return Value:返回值,类型必须是字符串,Struts 2会根据返回值控制程序流程。一个简单的例子。定义一个HelloAction,访问该Action的时候在控制台打印“你好”。public class HelloAction public String hello() System.out.println(“你好”); return null; 在struts.xml配置文件中,将刚才创建的Action注册到这里。4.5.2 ACTION

41、的定义name:自定义名称,访问Action时用到,如:helloAction.action。class:Action的类名method:访问该Action时,调用hello()方法。因为hello()方法的返回值是null,表示不跳转到任何地方。如果返回一个字符串,则必须配置的子标签,通过该标签映射一个跳转路径,如:/my.jsp,表示如果方法的返回值为success,则跳转到my.jsp文件。是可选的,在定义Action的响应方法时,如果将方法名称定义为execute,则可省略。如:public class HelloAction public String execute() Syste

42、m.out.println(“你好”); Return nulll; 配置修改如下:4.5.3 通过ACTION获取请求参数通过HttpServletRequest的getParameter()或getParameterValues()方法固然可以得到从客户端传送过来的请求参数,但是这样做很麻烦,而且增加了应用程序的耦合度,增强了对容器的依赖。Struts2在Action中改进了获取请求参数的方式,自动获取请求参数。Struts2获取请求参数的名称,拼成该参数的set方法与get方法,调用方法实现属性的存取操作。比如,从客户端传送一个名叫name的参数,则会拼成setName和getName方

43、法名,通过反射调用setName()方法进行赋值,程序员通过getName()方法就能取到值了。存取值的代码写在Action中就可以。上面的操作是交给OGNL实现的。以下是一个Action获取请求参数的例子。本示例用于演示用户登陆的过程。用户输入用户名和密码,如果分别为admin和admin,则显示登陆成功的信息,否则显示登陆失败的信息。login.jsp 用户名: 密码: 4.5.3 通过ACTION获取请求参数在表单中,表单域的name属性值必须和Action中定义的属性名称一致,才能正确被Action接收,如果读者懂得反射原理,更容易理解。 LoginAction.java作为控制器则负

44、责接收视图层发送过来的用户名和密码,并通过execute()方法调用业务方法,根据执行结果控制程序流程:如果登陆成功,则跳转到success.jsp,否则跳转到failure.jsp。4.5.3 通过ACTION获取请求参数public class LoginAction private String username; private String password; public String getPassword() return password; public void setPassword(String password) this.password = password; p

45、ublic String getUsername() return username; public void setUsername(String username) this.username = username; public String execute() /调用业务组件,如果成功,返回“success”;否则,返回“failure”。 if(.) return “success”; else return “failure”; 4.5.3 通过ACTION获取请求参数提交表单后,请求提交给loginAction.action.loginAction.action是在struts.

46、xml文件中预先配置好的,可以自定义,但最好用一个比较有意义的名字,增强程序的易读性。LoginAction的配置/success.jsp/failure.jsp也可以将定义在Action中的属性封装成一个实体类,更利于控制器与属性的分离。将属性定义在Action中的做法,违背了控制器的初衷。Struts2的开发者们提供了一种更好的处理方式,类似于struts1.x中的ActionForm,但是比ActionForm更加灵活和解耦。4.5.3 通过ACTION获取请求参数将username和password封装到User类中,源代码如下:User.javapublic class User p

47、rivate String username;private String password;public String getPassword() return password;public void setPassword(String password) this.password = password;public String getUsername() return username;public void setUsername(String username) this.username = username;4.5.3 通过ACTION获取请求参数在LoginAction类

48、中,保存一个User的引用就行了。该类的配置不需要改变。LoginAction.java(修改版)public class LoginAction private User user; public User getUser() return user; public void setUser(User user) this.user = user; public String execute() /同上 4.5.3 通过ACTION获取请求参数最后,修改login.jsp中的表单域的name属性值,基本格式为:引用名.属性名。在上例中,引用名是指定义在LoginAction类中的user,属

49、性名是指定义在Users为中的username和password。为了将用户名传递到User类的username属性中保存,修改为即可,所以login.jsp最后的代码如下:login.jsp的修改版,代码如下: 用户名: 密码: 4.5.4 ACTIONSUPPORT在Struts2中,Action与容器已经做到完全解耦,不再继承某个类或实现某个接口,但是,在特殊情况下,为了降低编程的工作难度,充分利用Struts2提供的功能,定义Action时会继承类ActionSupport,该类位于xwork2提供的包com.opensymphony.xwork2中。ActionSupport类为Ac

50、tion提供了一些默认实现,主要包括: 预定义常量 从资源文件中读取文本资源 接收验证错误信息 验证的默认实现下面是ActionSupport类所实现的接口:public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider,Serializable Action接口同样位于com.opensymphony.xwork2包,定义了一些常量和一个execute()方法。public interface Action public static final

51、 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; public String execute() throws Exception;4.5.4 ACTIONSUPPORTAction接口中一共定义了五个常量,每个常量都有特定的意义,这些常量被execute()方法返

52、回,并最终被Result处理,的子标签的name属性可以是这些常量中的任何一个。SUCCESS是name属性的缺省值。其中,SUCCESS表示请求处理成功,ERROR表示请求处理失败,NONE表示请求处理完成后不跳转到任何页面,INPUT表示输入时如果验证失败应该跳转到什么地方,LOGIN表示登陆失败后跳转的目标。接口com.opensymphony.xwork2.ValidationAware的实现类com.opensymphony.xwork2. ValidationAwareSupport定义了三个集合成员,这些集合用于存储错误或消息。ValidationAware的众多方法主要完成对这

53、些成员的存储操作和判断集合中是否有元素的操作,ActionSupport仅仅实现对这些方法的简单调用。4.6 知识点:STRUTS 2:OGNL表达式4.6.1 Struts 2的OGNL表达式OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,OGNL是一个开源项目。OGNL是一种功能强大的EL(Expression Language,表达式语言),可以通过简单的表达式来访问Java对象中的属性。OGNL先在WebWork项目中得到应用,也是Struts 2框架视图默认的表达式语言,可以说,OGNL表达式是Struts 2框架的特点之一。标

54、准的OGNL会设定一个根 对象(root对象)。假设使用标准OGNL表达式来求值(不是Struts2 OGNL),如果OGNL上下文有两个对象:foo对象,bar对象。同时foo对象被设置为根对象(root)。则利用下面的OGNL表达式求值# foo.blah /返回fo.getBlah()#bar.blah /返回bar.getBlah()blah /返回foo.getBlah(),因为foo为根对象使用ONGL非常简单,如果要访问的对象不是根对象,如示例中的bar对象,则需要使用命名空间,用“#”来表示,如“#bar”;如果访问一个根对象,则不用指定命名空间,可以直接访问根对象的属性。4.

55、6.1 STRUTS 2的OGNL表达式 在Struts 2框架中,值栈(Value Stack)就是OGNL的根对象,假设值栈中存在两个对象实例:Man和Animal,这两个对象实例都有一个name属性,Animal有一个species属性,Man有一个salary属性,假设Animal在值栈的顶部,Man在Animal后面,如图4-16所示。下面的代码片段能更好地理解OGNL表达式。值栈AnimalnamespeciesMannamesalaryTop图4-16 一个包含了Animal和Man的值栈4.6.1 STRUTS 2的OGNL表达式species /调用animal.getSpe

56、cies()salary /调用man.getSalry()name /调用animal.getName(),因为Animal位于值栈的顶部最后一行实例代码中,返回的是animal。getName()返回值,即返回了Animal的name属性,因为Animal是值栈的顶部元素,OGNL将从顶部元素搜索,所以会返回Animal的name属性值。如果要获得Man的name值,则需要如下代码:Struts 2允许在值栈中使用索引,实例代码如下所示:0.name /调用animal.getName()1.name /调用man.getName()Struts 2中的OGNL Context是Actio

57、nContext,如图4-17所示4.6.1 STRUTS 2的OGNL表达式图4-17 Struts 2的OGNL Context结构示意图4.6.1 STRUTS 2的OGNL表达式由于值栈是Struts 2中OGNL的根对象,如果用户需要访问值栈中的对象,则可以通过如下代码访问值栈中的属性:$foo /获得值栈中的foo属性如果访问其他Context中的对象,由于不是根对象,在访问时,需要加#前缀 application对象,用于访问ServletContext,例如#application.userName或者#applicationusername,相当于调用Servlet的getA

58、ttribute(username); session对象,用来访问HttpSession,例如#session.userName或者#sessionuserName,相当于调用session.getAttribute(userName)。 request对象 用来访问HttpServletRequest属性的Map,例如#request.userName或者#requestuserName,相当于调用request.getAttribute(userName)。4.6.2 OGNL的集合操作 如果需要一个集合元素的时候(例如List对象或者Map对象),可以使用OGNL中同集合相关的表达式。可以使用如下代码直接生成一个List对象:e1, e2, e3该OGNL表达式中,直接生成了一个List对象,该Li

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论