jsf + spring + hibernate 开发示例

以下是用例图,用户可以进行以下操作:登录、浏览、注册、修改、删除、退出


 

 

创建 user 工程


添加 jsf 框架、spring 框架、hibernate 框架

这里的JSF框架在MyEclipse中使用MyFaces1.0.9,并且在弹出是否增加j2ee包的对话框时,请选择No,如果选择了Yes的话会发现jsp页面无法在Tomcat中显示的问题,不过换了resin3就可以了,请不要使用Sun JSF,因为后面的集成部份必需使用MyFaces,当然,如果有朋友会集成Sun JSF的话也不勉强,并请你教我怎么集成!

在添加spring框架时,选中所有的可选项,具体应该使用哪一个我也分不清,创建完成后需要对 web.xml 文件进行配置,加入以下内容:

<servlet>

<servlet-name>context</servlet-name>

<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>


<context-param>

<param-name>contextConfigLocation</param-name>

<param-value>/WEB-INF/applicationContext.xml</param-value>

</context-param>


在添加完Hibernate时,记得把jdbc文件拷贝到lib目录


使用三层结构: WEB MODEL DATA


启动mysql并创建USERS

CREATE TABLE `user` (

`id` int(11) NOT NULL auto_increment,

`username` varchar(100) NOT NULL default '',

`password` varchar(100) NOT NULL default '',

PRIMARY KEY (`id`)

)


新建三个包,分别为:com.webcom.modelcom.data


其中 com.web 包中包含以下包:

com.web.bocom.web.vo


其中 com.model 包中包含以下包:

com.model.servicecom.model.service.implcom.model.exception


其中 com.data 包中包含以下几个包:

com.data.daocom.data.dao.impl


com.web.bo ,用来存放映射后的BO(业务)层的对像

com.web.vo ,用来存放映射后的VO(业务)层的对像


com.model.service , 用来存放 service(服务)层的对像的接口

com.model.service.impl , 用来存放 service(服务)层的对像接口的实例

com.model.exception ,用来存放自定义的异常处理类


com.data.dao ,用来存放DAO(数据访问)层的对像的接口

com.data.dao.impl ,用来存放DAO(数据访问)层的对像接口的实例


配置完成 hibernate 后对表进行映射操作,将映射文件保存到com.web.bo包内


创建一个异常处理类 UserException.java,内容如下:

public class UserException extends Exception {

public UserException(){

super();

}

public UserException(String msg){

super(msg);

}

public UserException(String msg, Throwable cause) {

super(msg, cause);

}

}


使用 数据浏览工具 创建 User 对像


创建 JSF 绑定类 UserBaseBean UserBean UserBaseBean UserBean 的基类

UserBaseBean 的内容如下:

package com.web.vo;

public class UserBaseBean {

}


UserBean 的内容如下:

package com.web.vo;

import com.model.exception.UserException;

import com.web.bo.User;


public class UserBean extends UserBaseBean {


private User user=new User();

public User getUser() {

return user;

}

public void setUser(User user) {

this.user = user;

}

// 登录事件

public String loginAction(){

return null;

}

// 退出事件

public String logoutAction(){

return null;

}

// 注册事件

public String registerAction(){

return null;

}

// 删除事件

public String deleteAction(){

return null;

}

// 编辑事件

public String editAction(){

return null;

}

// 浏览事件

public String browseAction(){

return null;

}

}


创建 IUserService 接口,内容如下:

此接口的作用是由 UI 层来调用她,她再调用 data 层来访问数据库处理数据。

package com.model.service;

import java.util.List;

import com.web.bo.User;

import com.model.exception.UserException;

public interface IUserService {

public User login(String username,String password) throws UserException;

public boolean logout() throws UserException;

public boolean register(User user) throws UserException;

public boolean delete(Integer uid) throws UserException;

public boolean edit(User user) throws UserException;

public List browse() throws UserException;

}

以上方法都是业务逻辑,从单词中应该可以看出是做什么用的


创建 IUserService 接口的实现 UserServiceImpl 类,内容如下:

package com.model.service.impl;

import java.util.List;

import com.model.exception.IUserService;

import com.model.exception.UserException;

import com.web.bo.User;


public class UserServiceImpl implements IUserService {


public User login(String username, String password) throws UserException {

// TODO Auto-generated method stub

return null;

}

public boolean logout() throws UserException {

// TODO Auto-generated method stub

return false;

}

public boolean register(User user) throws UserException {

// TODO Auto-generated method stub

return false;

}

public boolean delete(Integer uid) throws UserException {

// TODO Auto-generated method stub

return false;

}

public boolean edit(User user) throws UserException {

// TODO Auto-generated method stub

return false;

}

public List browse() throws UserException {

// TODO Auto-generated method stub

return null;

}

}


修改 UserBaseBean ,这个类只有一个属性为 IUserService 对像,内容如下:

import com.model.service.IUserService;


public class UserBaseBean {

private IUserService userService;

public IUserService getUserService() {

return userService;

}

public void setUserService(IUserService userService) {

this.userService = userService;

}

}


配置 UserService,此类将由 Spring 来管理,内容如下:


spring配置文件 applicationContext.xml 文件中配置 userService 对像,配置内容如下:

<bean id="userService" class="com.model.service.impl.UserServiceImpl"></bean>


为了让 JSF 能够获得 Spring 的配置信息,需要使用 Spring 提供的 DelegatingVariableResolver 类来进行集成

这时只需要增加 JSF 的配置信息即可

打开 faces-config.xml 文件

按下 Ctrl + N 键,选择 Application 向导

点击 下一步 ,在对话框中填入以下值:

Variable Resolver:org.springframework.web.jsf.DelegatingVariableResolver

点击 完成 生成以下配置信息:

<application>

<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>

</application>

这段配置信息的功能为使用Spring的变量解析器来替换JSF的变量解析器


按下 Ctrl + N 键,使用向导来配置 JSF Managed Bean

在弹出的对话框中填入以下值:

Name:userBean 因为 UserBean 类是继承于 UserBaseBean 类,所以注入时实际上却是要注入到 UserBean 而不是 UserBaseBean

Class:com.web.vo.UserBean

Scope:session 这个很重要,Bean中的对像将会自动保存在session中,这样页面跳转之后也可以使用getter方法来获取数据

点击 Add 按钮,创建一个属性

Name:userService 这里的值对应 UserBaseBean 类中的 userService 对像,名称不能弄错

点击下一步

Name:#{userService} 这里的值将会读取 spring 配置文件并创建一个 userService 对像并注入到 UserBean 对像中

点击完成后生成以下配置信息:

<managed-bean>

<managed-bean-name>userBean</managed-bean-name>

<managed-bean-class>com.web.vo.UserBean</managed-bean-class>

<managed-bean-scope>request</managed-bean-scope>

<managed-property>

<property-name>userService</property-name>

<value>#{userService}</value>

</managed-property>

</managed-bean>


创建 IUserDao 接口,内容如下:

package com.data.dao;

import java.util.List;

import com.web.bo.User;


public interface IUserDao {

public User getUser(String username);

public boolean addUser(User user);

public boolean delUser(Integer uid);

public boolean updateUser(User user);

public List getAllUser();

}

以上全部是数据库操作的方法,具体操作由下面的类来负责


创建 IUsersDao 接口的实现 UserDaoImpl 类,因为要使用到 Hibernate 所在得继承 HibernateDaoSupport

只有继承了这个类才可以注入 sessionFactory 对像(注意版本)内容如下:

import java.util.List;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.data.dao.IUserDao;

import com.web.bo.User;


public class UserDaoImpl extends HibernateDaoSupport implements IUserDao {

public User getUser(String username) {

// TODO Auto-generated method stub

return null;

}

public boolean addUser(User user) {

// TODO Auto-generated method stub

return false;

}

public boolean delUser(Integer uid) {

// TODO Auto-generated method stub

return false;

}

public boolean updateUser(User user) {

// TODO Auto-generated method stub

return false;

}

public List getAllUser() {

// TODO Auto-generated method stub

return null;

}

}


现在修改 UserServiceImpl.java 文件,增一个 IUserDao 对像的属性,并添加 getter setter 方法

private IUserDao userDao;

public IUserDao getUserDao() {

return userDao;

}

public void setUserDao(IUserDao userDao) {

this.userDao = userDao;

}


修改 Spring 配置文件,增加数据库相关部份的配置信息,内容如下:

<!-- 配置 dataSource 使用Hibernate2的话要修改下面的第一行 -->

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

<property name="driverClassName">

<value>com.mysql.jdbc.Driver</value>

</property>

<property name="url">

<value>jdbc:mysql://localhost/test</value>

</property>

<property name="username">

<value>root</value>

</property>

<property name="password">

<value>root</value>

</property>

</bean>


<!-- 配置sessionFactory, 注意这里引入的包的不同 -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

<property name="dataSource">

<ref local="dataSource" />

</property>

<property name="mappingResources">

<list>

<value>com/web/bo/User.hbm.xml</value>

</list>

</property>

<property name="hibernateProperties">

<props>

<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>

<prop key="hibernate.show_sql">true</prop>

</props>

</property>

</bean>


<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">

<property name="sessionFactory">

<ref local="sessionFactory" />

</property>

</bean>


增加 userDao对像 注入到 userService 对像,修改后的配置文件内容如下:

<bean id="userDao" class="com.data.dao.impl.UserDaoImpl">

<property name="sessionFactory">

<ref local="sessionFactory" />

</property>

</bean>

<bean id="userService" class="com.model.service.impl.UserServiceImpl">

<property name="userDao">

<ref bean="userDao" />

</property>

</bean>



现在整个模型已经搭建完毕了,后面仅仅是修改代码的问题了

*****************************************************************************************


下面是页面设计部份

以下是页面导航图例

 


导航内容如下:

<navigation-rule>

<from-view-id>/index.jsp</from-view-id>

<navigation-case>

<to-view-id>/login.jsp</to-view-id>

</navigation-case>

</navigation-rule>

<navigation-rule>

<from-view-id>/browse.jsp</from-view-id>

<navigation-case>

<from-outcome>Delete</from-outcome>

<to-view-id>/browse.jsp</to-view-id>

</navigation-case>

<navigation-case>

<from-outcome>Logout</from-outcome>

<to-view-id>/index.jsp</to-view-id>

</navigation-case>

<navigation-case>

<from-outcome>Edit</from-outcome>

<to-view-id>/edit.jsp</to-view-id>

<redirect></redirect>

</navigation-case>

<navigation-case>

<from-outcome>Register</from-outcome>

<to-view-id>/register.jsp</to-view-id>

</navigation-case>

<navigation-case>

<from-outcome>Find:success</from-outcome>

<to-view-id>/browse.jsp</to-view-id>

</navigation-case>

</navigation-rule>

<navigation-rule>

<from-view-id>/error.jsp</from-view-id>

</navigation-rule>

<navigation-rule>

<from-view-id>/login.jsp</from-view-id>

<navigation-case>

<from-outcome>Login:failure</from-outcome>

<to-view-id>/error.jsp</to-view-id>

</navigation-case>

<navigation-case>

<from-outcome>Login:success</from-outcome>

<to-view-id>/browse.jsp</to-view-id>

</navigation-case>

</navigation-rule>

<navigation-rule>

<from-view-id>/edit.jsp</from-view-id>

<navigation-case>

<from-outcome>Edit:success</from-outcome>

<to-view-id>/browse.jsp</to-view-id>

<redirect /></navigation-case>

<navigation-case>

<from-outcome>Edit:failure</from-outcome>

<to-view-id>/edit.jsp</to-view-id>

</navigation-case>

</navigation-rule>

<navigation-rule>

<from-view-id>/register.jsp</from-view-id>

<navigation-case>

<from-outcome>Register:success</from-outcome>

<to-view-id>/browse.jsp</to-view-id>

</navigation-case>

<navigation-case>

<from-outcome>Register:failure</from-outcome>

<to-view-id>/register.jsp</to-view-id>

</navigation-case>

</navigation-rule>


现然先用熟悉的 登录(login) 来做一下测试


首先打开 index.jsp 文件,修改后文件内容如下:

<html>

<head>

<title>Index</title>

</head>

<body>

<a href="login.faces">Login</a>

</body>

</html>


修改 login.jsp 文件,内容如下:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<%@ page language="java" pageEncoding="UTF-8"%>

<html>

<head>

<title>Login</title>

</head>

<body>

<f:view>

<h:form>

<h:panelGrid columns="3">

<h:outputLabel for="username" value="User Name:" />

<h:inputText id="username" value="#{userBean.user.username}" required="true" />

<h:message for="username" />

<h:outputLabel for="password" value="Password:" />

<h:inputSecret id="password" value="#{userBean.user.password}" required="true" />

<h:message for="password" />

</h:panelGrid>

<h:panelGrid>

<h:panelGroup>

<h:commandButton value="Login" action="#{userBean.loginAction}" />

</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>

</body>

</html>

其中绑定 UserBean 的内容有三处,两个属性:#{userBean.user.username}#{userBean.user.password} 一个事件 #{userBean.loginAction}


修改 error.jsp 文件,内容如下:

<html>

<head>

<title>Error!!!</title>

</head>

<body>

Error!!!<br>

</body>

</html>


修改 UserBean loginAction 事件内容,代码如下:

public String loginAction() throws UserException{

User user=this.getUserService().login(this.user.getUsername(),this.user.getPassword());

if(user==null)

return "Login:failure";

return "Login:success";

}

注意返回的字符串要和页面设计时所定义的字符串一至

这个事件为点击页面中的 Login 按钮后执行 UserServiceImpl 对像中的 login() 方法,并返回一个 User 对像


现在修改 UserServiceImpl 对像中的 login() 方法,代码如下:

public User login(String username, String password) throws UserException {

// 调用 UserDao 成功后得到一个 User 对像

try {

User user=userDao.getUser(username);

if(user==null)

return null;

// 判断密码是否正确

if(!password.equals(user.getPassword()))

return null;

return user;

} catch (HibernateObjectRetrievalFailureException he) {

throw new UserException(username);

}

}


现在轮到 UserDaoImpl 对像的 getUser() 方法了,代码如下:

public User getUser(String username) {

// 根据用户名得到 User 对像

String hql="from User u where username=?";

List users=this.getHibernateTemplate().find(hql,username);

if(users.size()==1)

return (User)users.get(0);

return null;

}


好了,登录过程已经OK!!!,手动在数据库 User 表中插入一条记录,以作为初始管理员。


现在做 浏览页


修改 browse.jsp 文件,内容如下:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<%@ page language="java" pageEncoding="UTF-8"%>

<html>

<head>

<title>

Browse User

</title>

</head>

<body>

<f:view>

<h:form id="allUser">

<h:dataTable id="table" value="#{userBean.users}" var="u" border="1" width="80%">

<h:column>

<f:facet name="header">

<f:verbatim escape="true">ID</f:verbatim>

</f:facet>

<h:outputText value="#{u.id}" />

</h:column>

<h:column>

<f:facet name="header">

<f:verbatim escape="true">User Name</f:verbatim>

</f:facet>

<h:commandLink id="username" action="#{userBean.editAction}" value="#{u.username}">

</h:commandLink>

</h:column>

<h:column>

<f:facet name="header">

<f:verbatim escape="true">Password</f:verbatim>

</f:facet>

<h:outputText value="#{u.password}" />

</h:column>

</h:dataTable>

</h:form>

</f:view>

</body>

</html>

这个页面中使用了一个新值,#{userBean.users},这是一个数据集,是一个 DataModel 接口的实现对像(ListDataModel),也可以是 List

还有一个事件 #{userBean.editAction} 这个事件出现在用户名上,点击用户名称后就会跳转到编辑页面

页面中使用了 JSF dataTable 组件来呈现数据集,点击 Find 链接后将查询所有用户并显示


现在需要在 UserBean 中增加一个 users 的属性

private DataModel users=new ListDataModel();


public DataModel getUsers() throws UserException {

// 此方法是在页面获取users前从数据库中查询得到users

// 此方法只有放到这里,Table中的链接才可以实现userBean中的方法

// 查询方法只能在这里,而原来设定的browseAction()方法已经不需要了。

users.setWrappedData(this.getUserService().browse());

return users;

}


public void setUsers(DataModel users) {

this.users = users;

}


接下来修改 UserServiceImpl browse() 方法

public List browse() throws UserException {

// 得到所有用户

try {

List users=userDao.getAllUser();

return users;

} catch (HibernateObjectRetrievalFailureException he) {

throw new UserException("Browse Users");

}

}


最后修改 UserDaoImpl getAllUser() 方法

public List getAllUser() {

// 查询所有用户记录

String hql="from User u";

List users=this.getHibernateTemplate().find(hql);

return users;

}


好了,浏览已经完成了


现在做注册新用户


修改 register.jsp 文件,内容如下

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<%@ page language="java" pageEncoding="UTF-8"%>

<html>

<head>

<title>Register</title>

</head>

<body>

<f:view>

<h:form>

<h:panelGrid columns="3">

<h:outputLabel for="username" value="User Name:" />

<h:inputText id="username" value="#{userBean.user.username}" required="true" />

<h:message for="username" />

<h:outputLabel for="password" value="Password:" />

<h:inputSecret id="password" value="#{userBean.user.password}" required="true" />

<h:message for="password" />

</h:panelGrid>

<h:panelGrid>

<h:panelGroup>

<h:commandButton value="Register" action="#{userBean.registerAction}" />

</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>

</body>

</html>


修改 browse.jsp 文件,内容如下

<f:view>

<h:outputLink id="register" value="register.faces">

<h:outputText value="Register User"></h:outputText>

</h:outputLink>

<h:form id="allUser">


修改 UserBean.java 文件的 registerAction() 方法

// 注册事件

public String registerAction() throws UserException {

User newuser=new User();

newuser.setUsername(user.getUsername());

newuser.setPassword(user.getPassword());

if(this.getUserService().register(user))

return "Register:success";

else

return "Register:failure";

}


打开 UserServiceImpl.java 文件,修改 register() 方法

public boolean register(User user) throws UserException {

// 注册新用户

return userDao.addUser(user);

}


打开 UserDaoImpl.java 文件,修改 addUser() 方法

public boolean addUser(User user) {

// 增加新用户

this.getHibernateTemplate().save(user);

return true;

}


好了,注册用户完成!


现在做修改 ,edit.jsp 文件内容如下:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>

<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>

<%@ page language="java" pageEncoding="UTF-8"%>

<html>

<head>

<title>Edit</title>

</head>

<body>

<f:view>

<h:form>

<h:panelGrid columns="3">

<h:outputLabel for="username" value="User Name:" />

<h:inputText id="username" value="#{userBean.user.username}" required="true" />

<h:message for="username" />

<h:outputLabel for="password" value="Password:" />

<h:inputText id="password" value="#{userBean.user.password}" required="true" />

<h:message for="password" />

</h:panelGrid>

<h:panelGrid>

<h:panelGroup>

<h:commandButton value="UpDate" action="#{userBean.updateAction}" />

</h:panelGroup>

</h:panelGrid>

</h:form>

</f:view>

</body>

</html>


修改 UserBean editAction 方法

// 编辑事件,现用来做为导航事件

public String editAction() {

// 此方法可以从 users 对像中得到点击后的 user 对像

this.setUser((User)users.getRowData());

return "Edit";

}


UserBean 中增加 updateAction 方法

// 修改事件

public String updateAction() throws UserException{

if(this.getUserService().edit(user)){

users.setWrappedData(this.getUserService().browse());

return "Edit:success";

}

else

return "Edit:failure";

}


修改 UserServiceImpl 中的 edit() 方法

public boolean edit(User user) throws UserException {

// 修改用户密码

try {

// 先读取 User 对像

return userDao.updateUser(user);

} catch (HibernateObjectRetrievalFailureException he) {

throw new UserException("Update user");

}

}


修改 UserDaoImpl updateUser() 方法

public boolean updateUser(User user) {

// 修改User

this.getHibernateTemplate().update(user);

return true;

}


好了,修改也已经完成了。

以下是注意的地方:

配置文件中 UserBean 的配置信息中

<managed-bean-scope>session</managed-bean-scope>

这里一定要使用 session,如果使用的是 request 的话会造成 User 对像中的 ID 值变为 null ,这时就不能进行 UpDate 操作了



现在开始做 删除


打开 browse.jsp 文件,增加以下内容

...

<h:column>

<f:facet name="header">

<f:verbatim escape="true">Operation</f:verbatim>

</f:facet>

<h:commandLink id="operation" action="#{userBean.deleteAction}">

<h:outputText value="Delete" />

</h:commandLink>

</h:column>

</h:dataTable>

...

这里是面 Table 中增加一列,此列的作用是增加一个链接,点击此链接后将执行 UserBean 中的 deleteAction() 方法


打开 UserBean.java 文件,修改 deleteAction() 事件

// 删除事件

public String deleteAction() throws UserException {

this.setUser((User)users.getRowData());

this.getUserService().delete(user.getId());

return null;

}


打开 UserServiceImpl.java 文件,修改 delete() 方法

public boolean delete(Integer uid) throws UserException {

// 删除用户

return userDao.delUser(uid);

}


打开 UserDaoImpl.java 文件,修改 delUser() 方法

public boolean delUser(Integer uid) {

// 删除一个用户

User user=(User) this.getHibernateTemplate().load(User.class,uid);

this.getHibernateTemplate().delete(user);

return true;

}


删除事件已经完成!


现在做最后一个事件,注销事件


修改 browse.jsp 文件,内容如下

</h:form>

<br>

<h:commandLink id="logout" action="#{userBean.logoutAction}" value="Logout">

</h:commandLink>

</f:view>


修改 UserBean.java 文件的 logoutAction() 方法

// 退出事件

public String logoutAction() {

this.setUser(null);

return "Logout";

}


好了,注销已经完成了!


现在所有的代码编写都已经完成,可以进行完整的测试了!

posted on 2008-01-24 10:29  岚之山  阅读(265)  评论(0编辑  收藏  举报

导航