转自:http://blog.csdn.net/syneer/archive/2010/06/08/5656396.aspx
一、初始配置环境
操作系统: Windows XP
开发工具: MyEclipse7.5
JDK : 6.0 版本
Web 服务器: Tomcat6.0
数据库: MySQL5.0
●关于开发环境的配置说明、测试开发环境是否正常不再赘述,配置过程参见百度。
●关于 Java 的基本语法不再赘述, Java 语言学习请参见 Cay S.Horstmann 、 Gary Cornell 的《 Java2 核心技术》上下卷等书籍。
●关于 SQL 语言不再赘述, SQL 学习参见 Konrad King 的《 SQL 编程实用大全》或者《 SQL 完全手册》等书籍。
二、热身:一个最简单的 Java Web 项目—— TinyBee
目标:
⊙指导新手在 Java Web 开发的世界扬帆起航;
⊙熟悉 MyEclipse 开发环境;
⊙培养新手的成就感;
⊙想本文的阅读者致意!
1、 在 MyEclipse7.5 中新建一个名为“ TinyBee ”的 Web Project
2、 在“ src ”下新建一个名为“ com.ww.tinybee ”的包,并在该包下添加一个名为“ HelloTinyBee ”的类,
package com.ww. tinybee ;
public class HelloTinyBee { public String sayHello(String tinybee){ return "Hello ," +tinybee+ "!" ; } } |
3、 “ WebRoot ”下新建一个名为“ index.html ”的页面,用于接收用户请求
<%@ page language = "java" import = "java.util.*" pageEncoding = "GB18030" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+ "://" +request.getServerName()+ ":" +request.getServerPort()+path+ "/" ; %>
<! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title > Please enter your name: </ title > </ head > < body > < form method = "post" action = "hellotinybee.jsp" > Please enter your name : < input type = "text" name = "tinybee" > < input type = "submit" value = " 递交 " > </ form > </ body > </ html > |
4、 “ WebRoot ”下新建一个名为“ hellotinybee.jsp ”的页面,用于响应用户输入的请求,
<%@ page language = "java" contentType = "text/html; charset=UTF-8" pageEncoding = "UTF-8" %> <! DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd" > <%@ page import = "com.ww.tinybee.HelloTinyBee" %> < html > < head > < meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" > < title > Insert title here </ title > </ head > < body > <% String tinybee=request.getParameter( "tinybee" ); HelloTinyBee hello= new HelloTinyBee(); String hellotinybee=hello.sayHello(tinybee); %> <%= hellotinybee %> </ body > </ html > |
5、 Deploy 项目并启动 Tomcat6.0 后,打开浏览器输入 http://127.0.0.1:8080/TinyBee/index.jsp
输入“ TinyBee ”,提交后成功出现预期页面:
至此为止,一个最为简单的 Java Web 项目建立完成,打包部署不再赘述。
可实际项目不可能这么简单,页面控制跳转( Control , MVC 之“ C ”)是 Web 项目的一个通用功能,程序员可不可以不用去做这些费神费力不讨好的事情? Struts 应运而生(当然 Struts 不单只用来控制页面跳转,但确实其最重要的功能之一)。
三、为项目添加 Spring 、 Struts 、 Hibernate 能力
目标:
⊙初步掌握如何手动配置、使用 SSH2 ;
为什么用 SSH2 框架或者其他类似框架?
随着项目的复杂程度越来越高,一个构架清晰的项目才具备可维护性的基础;并且,为了使开发人员专注于业务领域,一个具备可集成业务、解决业务外通用问题的框架乃众望所归。感谢开源社区,为 Java 量身定做了 SSH 框架,该框架的发展史、关注点、特点、优点在网上或者任何一本价值 99 元的计算机书籍均可找到,不再赘述。
有些大公司做项目还是用原始的 Servlet 、 Jsp 方式,而不是采用 SSH 框架,这有以下三方面的原因:一是大公司所做的项目都比较早,前期没有 SSH 框架,后期不会刻意去添加该框架(可能随着项目的发展,逐渐演变出类似 SSH 的 MVC 框架);二是大公司所做的项目一般比较规范, SSH 的主旨之一也是为了规范开发、增强可维护性,因此也就没有转变到 SSH 框架的迫切需求;三是大公司在做项目的过程中,比较倾向于沿用以往成功经验,也就不一定非得引入 SSH 框架。正所谓“兵无定势、水无常形 ”, SSH2 仅仅是一个框架、一个提高工作效率的工具,我们必须相信 Every Roads to Rome ,才可以掌握框架,而不是被框架奴役,谨记,永远是“软件工程本身,而不是什么其他东西 ” 。
在 MyEclipse7.5 下,为我们上述的 TinyBee 项目添加 SSH 能力是一项很小白的活动,也不再赘述,提醒新手注意 Spring 是 SSH 框架的基础框架,应该最早添加 。
★ Tips 0001 : MyEclipse7.5 自动添加 SSH 的选项中没有最新的 Spring3 、 Struts2 、 Hibernate3 ,但想用这些最新的,怎么办?(难度:★)
答:手动添加。其实 SSH 和 SSH2 的根本区别是 Struts 版本的变化,因为 Struts 1 跟 Struts 2 差别甚大,而 Spring 和 Hibernate 截止目前版本,仅仅是升级完善上的意义,所以这个“ 2 ”指的就是 Struts 的改进。既然有更好的 SSH2 框架,我们就采用此框架。
若用 MyEclipse 自带的 SSH 能力添加向导,实在不值一提,但是一个版本的 MyEclipse 往往仅支持几个子版本号的 SSH 添加,比如 MyEclipse7.5 就没有 Struts2 能力添加向导。那就手动来一个吧!顺便为了说明 Spring 是如何整合 Hibernate 和 Struts ,我故意把 Spring 放在最后整,也便于大家看到一个好的框架是如何松耦合的。
本案例使用Spring3.0.2+Struts2.1.8.1+Hibernate3.5.2,不同版本jar包略有不同,特于提醒。
3.1 配置 Struts2
如前文提到, struts 给出了一个清晰的 MVC 模式,使开发变得简单高效,以下这个例子就可以看出运用 Struts 控制跳转是多么地方便。
1 、添置必备包:将 commons-fileupload-1.2.1.jar 、 commons-logging-1.0.4.jar 、 freemarker-2.3.15.jar 、 log4j-1.2.15.jar 、 ognl-2.7.3.jar 、 struts2-core-2.1.8.1.jar 、 xwork-core-2.1.6.jar 拷贝到项目的 /WebRoot/WEB-INF/lib 下(其他包按需要添加),并在工程中导入这些库;
2 、配置相关配置文件:在项目的 src 下配置 log4j.properties
## LOGGERS ## #define a logger #log4j.rootLogger=DEBUG,console,file log4j.rootLogger= INFO,console,file
## APPENDERS ## # define an appender named console, which is set to be a ConsoleAppender log4j.appender.console= org .apache .log4j.ConsoleAppender
# define an appender named file, which is set to be a RollingFileAppender log4j.appender.file= org .apache .log4j.RollingFileAppender log4j.appender.file.File= d : /demo_log.txt
#set the log's size log4j.appender.file.MaxFileSize= 1000KB log4j.appender.file.MaxBackupIndex= 20
## LAYOUTS ## # assign a SimpleLayout to console appender log4j.appender.console.layout= org .apache .log4j.SimpleLayout
# assign a PatternLayout to file appender log4j.appender.file.layout= org .apache .log4j.PatternLayout # For debug # log4j.appender.file.layout.ConversionPattern=[%-5p][%t][%C][%d{yyyy -MM-dd HH:mm:ss}] %m%n # For deployment log4j.appender.file.layout.ConversionPattern= [%-5p][%d{yyyy -MM-dd HH : mm:ss}] %m%n |
配置 struts.properties
### Struts default properties ###(can be overridden by a struts.properties file in the root of the classpath ) ###
### Specifies the Configuration used to configure Struts ### one could extend org .apache .struts2.config .Configuration ### to build one's customize way of getting the configurations parameters into Struts # struts.configuration=org .apache .struts2.config .DefaultConfiguration
### This can be used to set your default locale and encoding scheme # struts.locale =en_US struts.i18n.encoding= UTF-8
### if specified, the default object factory can be overridden here ### Note: short-hand notation is supported in some cases, such as "spring" ### Alternatively, you can provide a com .opensymphony .xwork2.ObjectFactory subclass name here # struts.objectFactory = spring
### specifies the autoWiring logic when using the SpringObjectFactory. ### valid values are: name, type, auto, and constructor (name is the default) struts.objectFactory.spring.autoWire = name
### indicates to the struts-spring integration if Class instances should be cached ### this should, until a future Spring release makes it possible, be left as true ### unless you know exactly what you are doing! ### valid values are: true, false (true is the default) struts.objectFactory.spring.useClassCache = true
### if specified, the default object type determiner can be overridden here ### Note: short-hand notation is supported in some cases, such as "tiger" or "notiger " ### Alternatively, you can provide a com .opensymphony .xwork2.util .ObjectTypeDeterminer implementation name here ### Note: By default, com .opensymphony .xwork2.util .DefaultObjectTypeDeterminer is used which handles type detection ### using generics . com .opensymphony .xwork2.util .GenericsObjectTypeDeterminer was deprecated since XWork 2, it's ### functions are integrated in DefaultObjectTypeDeterminer now. ### To disable tiger support use the "notiger " property value here. #struts.objectTypeDeterminer = tiger #struts.objectTypeDeterminer = notiger
### Parser to handle HTTP POST requests, encoded using the MIME-type multipart /form-data # struts.multipart .parser=cos # struts.multipart .parser=pell struts.multipart.parser= jakarta # uses javax .servlet .context.tempdir by default struts.multipart.saveDir= struts.multipart.maxSize= 2097152
### Load custom property files (does not override struts.properties!) # struts.custom.properties=application,org /apache /struts2/extension/custom
### How request URLs are mapped to and from actions #struts.mapper .class=org .apache .struts2.dispatcher.mapper .DefaultActionMapper
### Used by the DefaultActionMapper ### You may provide a comma separated list, e.g. struts.action.extension=action,jnlp ,do struts.action.extension= do
### Used by FilterDispatcher ### If true then Struts serves static content from inside its jar. ### If false then the static content must be available at <context_path> /struts struts.serve.static= true
### Used by FilterDispatcher ### This is good for development where one wants changes to the static content be ### fetch on each request. ### NOTE: This will only have effect if struts.serve.static=true ### If true -> Struts will write out header for static contents such that they will ### be cached by web browsers (using Date, Cache-Content, Pragma , Expires) ### headers). ### If false -> Struts will write out header for static contents such that they are ### NOT to be cached by web browser (using Cache-Content, Pragma , Expires ### headers) struts.serve.static.browserCache= true
### Set this to false if you wish to disable implicit dynamic method invocation ### via the URL request. This includes URLs like foo !bar.action, as well as params ### like method:bar (but not action:foo). ### An alternative to implicit dynamic method invocation is to use wildcard ### mappings, such as <action name="*/*" method="{2}" class="actions.{1}"> struts.enable.DynamicMethodInvocation = true
### Set this to true if you wish to allow slashes in your action names. If false, ### Actions names cannot have slashes, and will be accessible via any directory ### prefix. This is the traditional behavior expected of WebWork applications. ### Setting to true is useful when you want to use wildcards and store values ### in the URL, to be extracted by wildcard patterns, such as ### <action name="*/*" method="{2}" class="actions.{1}"> to match "/foo /edit" or ### "/foo /save". struts.enable.SlashesInActionNames = false
### use alternative syntax that requires %{} in most places ### to evaluate expressions for String attributes for tags struts.tag.altSyntax= true
### when set to true, Struts will act much more friendly for developers. This ### includes: ### - struts.i18n.reload = true ### - struts.configuration.xml .reload = true ### - raising various debug or ignorable problems to errors ### For example: normally a request to foo .action?someUnknownField=true should ### be ignored (given that any value can come from the web and it ### should not be trusted). However, during development, it may be ### useful to know when these errors are happening and be told of ### them right away. struts.devMode = false
### when set to true, resource bundles will be reloaded on _every_ request. ### this is good during development, but should never be used in production struts.i18n.reload= false
### Standard UI theme ### Change this to reflect which path should be used for JSP control tag templates by default struts.ui.theme= simple struts.ui.templateDir= template #sets the default template type. Either ftl , vm , or jsp struts.ui.templateSuffix= ftl
### Configuration reloading ### This will cause the configuration to reload struts.xml when it is changed struts.configuration.xml.reload= false
### Location of velocity.properties file. defaults to velocity.properties struts.velocity.configfile = velocity.properties
### Comma separated list of VelocityContext classnames to chain to the StrutsVelocityContext struts.velocity.contexts =
### Location of the velocity toolbox struts.velocity.toolboxlocation=
### used to build URLs, such as the UrlTag struts.url.http.port = 80 struts.url.https.port = 443 ### possible values are: none, get or all struts.url.includeParams = get
### Load custom default resource bundles struts.custom.i18n.resources= com .demo.struts2.resources.ApplicationResources
### workaround for some app servers that don't handle HttpServletRequest.getParameterMap() ### often used for WebLogic, Orion, and OC4J struts.dispatcher.parametersWorkaround = false
### configure the Freemarker Manager class to be used ### Allows user to plug-in customised Freemarker Manager if necessary ### MUST extends off org .apache .struts2.views.freemarker .FreemarkerManager #struts.freemarker .manager.classname =org .apache .struts2.views.freemarker .FreemarkerManager
### Enables caching of FreeMarker templates ### Has the same effect as copying the templates under WEB_APP/templates struts.freemarker.templatesCache= false
### Enables caching of models on the BeanWrapper struts.freemarker.beanwrapperCache= false
### See the StrutsBeanWrapper javadocs for more information struts.freemarker.wrapper.altMap= true
### configure the XSLTResult class to use stylesheet caching. ### Set to true for developers and false for production. struts.xslt.nocache= false
### A list of configuration files automatically loaded by Struts struts.configuration.files= struts-default.xml ,struts-plugin .xml ,struts.xml
### Whether to always select the namespace to be everything before the last slash or not struts.mapper.alwaysSelectFullNamespace= false |
配置 struts.xml (尚未配置,先放模板)
<? 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" >
< struts > < constant name = "struts.enable.DynamicMethodInvocation" value = "false" /> < constant name = "struts.devMode" value = "false" />
< include file = "example.xml" />
<!-- Add packages here -->
</ struts > |
上述两步骤为惯常步骤。下面验证 struts 是否可用:
3 、在 src 的 com.tinybee.struts2.actions 下建立 LoginAction 控制登录跳转逻辑:
package com.tinybee.struts2.actions; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport;
public class LoginAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private String username; private String password;
@SuppressWarnings("unchecked") public String execute() throws Exception {
if ( username .equals( "TinyBee" ) && password .equals( "123456" )) { ActionContext.getContext ().getSession().put( "username" , username ); return Action. SUCCESS ; } else { //super.addActionError(super.getText("login.message.failed")); return Action. LOGIN ; } } public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
} |
4 、配置 struts.xml (其中粗体部分),指定跳转页面:
<? 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" >
< struts >
< constant name = "struts.enable.DynamicMethodInvocation" value = "false" /> < constant name = "struts.devMode" value = "false" />
< include file = "example.xml" />
<!-- Add packages here --> < package name = "myLogin" extends = "struts-default" > < action name = "login" class = "com.tinybee.struts2.actions.LoginAction" > < result name = "success" > success.jsp </ result > < result name = "login" > login.jsp </ result > </ action > </ package >
</ struts > |
5 、配置 web.xml (其中粗体为插入部分)
< web-app version = "2.4" xmlns = "http://java.sun.com/xml/ns/j2ee" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
< filter > < filter-name > struts2 </ filter-name > < filter-class > org.apache.struts2.dispatcher.FilterDispatcher </ filter-class > </ filter > < filter-mapping > < filter-name > struts2 </ filter-name > < url-pattern > /* </ url-pattern > </ filter-mapping >
</ web-app > |
上述工作完成了页面成功或失败的跳转控制(为精简,本例子失败跳回本页)
6 、构建相应的 login.jsp 和 success.jsp
login.jsp:
< form action = "login.do" method = "post" > < input type = "text" name = "username" > < input type = "text" name = "password" > < input type = "submit" value = "Login" > </ form > |
success.jsp:
< table width = "300" border = "1" > < tr > < td > Hello! <%= (String) session.getAttribute( "username" ) %> </ td > </ tr >
< tr > < td >< a href = "login.jsp" > [Back] </ a ></ td > </ tr > </ table > |
7 、在浏览器输入 http://127.0.0.1:8080/TinyBee/login.jsp
仅当输入“ TinyBee/123456 ”账号时,出现
验证 struts2 成功!
想一下,在前面不用 struts 的那个例子中,控制页面的跳转得写多少代码,对于一个动辄几百个页面的项目意味着什么呢?其他好处慢慢细说。
3.2 配置 Hibernate
刚才,验证账号“ TinyBee/123456 ”是否与输入匹配在 LoginAction 中是写死的,这在真正的项目中当然不会出现,而是在数据库中持久化,用时才去取。为了屏蔽对数据库的底层操作(又是一件费神费力不讨好的事情),专注于业务本身,涌现了大量的数据持久化框架来解决数据库与对象映射问题, Hibernate 就是其中的佼佼者。
接上文,我们把存取数据的工作交给 Hibernate 去做。
1 、添加需要的基础包: mysql-connector-java-5.1.10-bin.jar (这个包不属于 Hibernate ,是连接 MySql 数据库的连接驱动, Oracle 、 Sql Server 的也有相类似的包)、 hibernate3.jar 、 antlr-2.7.6.jar 、 commons-collections-3.1.jar 、 dom4j-1.6.1.jar 、 javassist-3.9.0.GA.jar 、 jta-1.1.jar 、 slf4j-api-1.5.8.jar (数字随版本号不同略有变化,此处用 Hibernate3.5.2 最终版),另外需要特别注意的是,下载一个名为 slf4j-log4j12-1.5.8.jar 的包(版本号与前面的 slf4j-api-1.5.8.jar 保持一致)添加进去
2、 添加配置文件 hibernate.cfg.xml :
<? xml version = '1.0' encoding = 'UTF-8' ?> <! DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd" > < hibernate-configuration > < session-factory > < property name = "connection.driver_class" > com.mysql.jdbc.Driver </ property > < property name = "connection.url" > jdbc:mysql://localhost:3306/wwmis </ property > < property name = "myeclipse.connection.profile" > MySQLConnection </ property > < property name = "connection.username" > root </ property > < property name = "connection.password" > 4736693 </ property > < property name = "dialect" > org.hibernate.dialect.MySQLDialect </ property > < property name = "show_sql" > true </ property > < mapping resource = "com/ww/tinybee/hibernate/beans/UserAccount.hbm.xml" /> </ session-factory > </ hibernate-configuration > |
此处是连接 MySQL 数据库,数据库名为 wwmis ,账号 root/4736693 ,在后文用到的账户表 user_account 表如下所示,有一账号为“ TinyBee/123456 ”的记录:
连接 Oracle 、 SQL Server 的配置参见百度。
By the way ,这里 <mapping resource=”com/ww/..” /> 可以随便写,后面利用 MyEclipse 的 Hibernate Reverse Engineering 功能自动生成 Bean 和 DAO 时会自动生成 mapping ,届时把这个不要的 mapping 行删除即可。
3、 添加 HibernateSessionFactory.java, 代码如下:
package com.ww.tinybee.hibernate.util;
import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.cfg.Configuration;
/** * Configures and provides access to Hibernate sessions, tied to the * current thread of execution. Follows the Thread Local Session * pattern, see {@link http://hibernate.org/42.html } . */ public class HibernateSessionFactory {
/** * Location of hibernate.cfg.xml file. * Location should be on the classpath as Hibernate uses * #resourceAsStream style lookup for its configuration file. * The default classpath location of the hibernate config file is * in the default package. Use #setConfigFile() to update * the location of the configuration file for the current session. */ private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml" ; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration(); private static org.hibernate.SessionFactory sessionFactory ; private static String configFile = CONFIG_FILE_LOCATION ;
static { try { configuration .configure( configFile ); sessionFactory = configuration .buildSessionFactory(); } catch (Exception e) { System. err .println( "%%%% Error Creating SessionFactory %%%%" ); e.printStackTrace(); } } private HibernateSessionFactory() { }
/** * Returns the ThreadLocal Session instance. Lazy initialize * the <code> SessionFactory </code> if needed. * * @return Session * @throws HibernateException */ public static Session getSession() throws HibernateException { Session session = (Session) threadLocal .get();
if (session == null || !session.isOpen()) { if ( sessionFactory == null ) { rebuildSessionFactory (); } session = ( sessionFactory != null ) ? sessionFactory .openSession() : null ; threadLocal .set(session); }
return session; }
/** * Rebuild hibernate session factory * */ public static void rebuildSessionFactory() { try { configuration .configure( configFile ); sessionFactory = configuration .buildSessionFactory(); } catch (Exception e) { System. err .println( "%%%% Error Creating SessionFactory %%%%" ); e.printStackTrace(); } }
/** * Close the single hibernate session instance. * * @throws HibernateException */ public static void closeSession() throws HibernateException { Session session = (Session) threadLocal .get(); threadLocal .set( null );
if (session != null ) { session.close(); } }
/** * return session factory * */ public static org.hibernate.SessionFactory getSessionFactory() { return sessionFactory ; }
/** * return session factory * * session factory will be rebuilded in the next call */ public static void setConfigFile(String configFile) { HibernateSessionFactory. configFile = configFile; sessionFactory = null ; } /** * return hibernate configuration * */ public static Configuration getConfiguration() { return configuration ; } } |
位于 com.ww.tinybee.hibernate.util 下。
4、 生成实体 Bean 、 DAO 和映射文件:在 MyEclipse 的 MyEclipse Database Explorer perspective 模式下,对表 user_account 执行 Hibernate Reverse Engineering ,自动生成 Bean ( AbstractUserAccount.java 、 UserAccount.java )、 DAO ( BaseHibernateDAO.java 、 IBaseHibernateDAO.java 、 UserAccountDAO.java )和 UserAccount.hbm.xml ,结构如下:
5、 测试 Hibernate :写一个登录验证测试一下。如上图所示,在 service 包中写一个 Login 类:
package com.ww.tinybee.service;
import com.ww.tinybee.hibernate.beans.*; import com.ww.tinybee.hibernate.DAO.UserAccountDAO; import java.util.List;
public class Login {
public boolean ValidateUser(String username,String password){ UserAccountDAO userAccountDAO= new UserAccountDAO(); List record=userAccountDAO.findByAccountName(username); if (record.isEmpty()== true ) return false ; else { String pwd=((UserAccount)record.get(0)).getAccountPassword(); if (pwd!= null &&pwd.equals(password)){ return true ; } else { return false ; } }
}
/** 测试类 */ public static void main(String args[]){ Login login= new Login(); System. out .println (login.ValidateUser( "TinyBee" , "123456" )); System. out .println (login.ValidateUser( "TinyBee" , "111111" )); }
} |
运行结果如下:
表明 TinyBee 用户用“ 123456 ” 密码登录验证成功。
6、 Struts 2+Hibernate 集成:话归前文,如何让 Struts 中的页面使用 Hibernate 得到的数据?只须将上文 Struts 2 中的 LoginAction.java 改为(深色部分):
package com.ww.tinybee.struts2.actions;
import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.ww.tinybee.service.Login;
public class LoginAction extends ActionSupport {
private static final long serialVersionUID = 1L;
private String username ;
private String password ;
@SuppressWarnings ( "unchecked" ) public String execute() throws Exception { Login login= new Login(); if (login.ValidateUser( username , password )== true ){ ActionContext.getContext ().getSession().put( "username" , username ); return Action. SUCCESS ; } else { //super.addActionError(super.getText("login.message.failed")); return Action. LOGIN ; }
/** 此为原来代码 if (username.equals("TinyBee") && password.equals("123456")) { ActionContext.getContext().getSession().put("username", username); return Action.SUCCESS; } else { //super.addActionError(super.getText("login.message.failed")); return Action.LOGIN; } */ }
public String getUsername() { return username ; }
public void setUsername(String username) { this . username = username; }
public String getPassword() { return password ; }
public void setPassword(String password) { this . password = password; }
} |
7、 在浏览器输入 http://127.0.0.1:8080/TinyBee/login.jsp
仅当输入“ TinyBee/123456 ”账号时,出现
验证 Struts2+Hibernate 成功!