您的位置:首页 > 其它

SSH学习笔记(二)

2011-08-15 21:31 537 查看
二、小项目实践

项目描述:对一个用户的姓、名、年龄进行增删查改,使用ssh框架 + apache的dbcp连接池。

1、确认commons-dbcp.jar已被导入(按照上篇的操作,则会被导入)

2、使用mysql数据库,建立名为mytest的数据库,创建表users

create table users (
id int not null,
firstname varchar(50) not null,
lastname varchar(50) not null,
age int not null,
primary key (id)
) ENGIN = InnoDB ROW_FORMAT = DEFAULT;

3、入口网页index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>         <!--  增加页面的structs支持 -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>My JSP 'index.jsp' starting page</title>

</head>

<body>
<h1><font color="red">Operation List</font>
</h1>

<s:a href="save.jsp">Save User</s:a><br><br><br>
<!--  structs提供的标签 -->
<s:a href="listUser.action"> List User</s:a>
<!--  通过调用服务器端的资源来显示所有用户 -->
</body>
</html>

4、新建save.jsp,保存用户页面

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>save user</title>

</head>

<body>
<h1><font color="red">Save User</font>
</h1>

<s:form action="saveUser">
<s:textfield name="user.firstname" label="firstname"></s:textfield>
<s:textfield name="user.lastname" label="lastname"></s:textfield>
<s:textfield name="user.age" label="age"></s:textfield>
<s:submit></s:submit>
</s:form>
</body>
</html>


5、新建包com.test.bean,在其中新建User.java

package com.test.bean;

public class User {
private Integer id;
private String firstname;
private String lastname;
private int age;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getFirstname() {
return firstname;
}

public void setFirstname(String firstname) {
this.firstname = firstname;
}

public String getLastname() {
return lastname;
}

public void setLastname(String lastname) {
this.lastname = lastname;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

这个javabean就好了。然后生成与之对应的hibernate配置文件。在相同的包里新建User.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"
6、新建包com.test.action.user,在包中新建SaveUserAction.java

[code=java]package com.test.action.user;

import com.opensymphony.xwork2.ActionSupport;
import com.test.bean.User;
import com.test.service.UserService;

public class SaveUserAction extends ActionSupport {

/**
*
*/
private static final long serialVersionUID = 1L;
private User user;
private UserService service;

public User getUser() {
return user;
}

public void setUser(User user) {
this.user = user;
}

@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
//不自己实现保存用户,而是调用业务逻辑层来实现
this.service.save(this.user);
return this.SUCCESS;
}

public UserService getService() {
return service;
}

public void setService(UserService service) {
this.service = service;
}

}

7、为页面添加国际化支持。在src目录下新建文件struts.properties,在文件中写上

struts.custom.i18n.resources=globalMessages

在src目录下新建globalMessages_en.properties,在文件中写上

firstname=firstname
lastname=lastname
age=age

在src目录下新建globalMessages_zh.properties,添加对应关系,在文件中写上(这里用图形化操作比较好)

firstname=\u59D3
lastname=\u540D
age=\u5E74\u9F84

即firstname对应“姓”,lastname对应“名”,age对应“年龄”。

修改save.jsp,将label属性改一下,修改后为

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>save user</title>

</head>

<body>
<h1><font color="red">Save User</font>
</h1>

<s:form action="saveUser">
<s:textfield name="user.firstname" label="%{getText('firstname')}"></s:textfield>
<s:textfield name="user.lastname" label="%{getText('lastname')}"></s:textfield>
<s:textfield name="user.age" label="%{getText('age')}"></s:textfield>
<s:submit></s:submit>
</s:form>
</body>
</html>

这样,save.jsp就有了国际化的支持了。

8、新建包com.test.dao,在包中新建UserDAO.java

package com.test.dao;

import java.util.List;

import com.test.bean.User;

public interface UserDAO {

public void saveUser(User user);

public void removeUser(User user);

public User findUserById(Integer id);

public List<User> findAllUsers();

public void updateUser(User user);
}

9、新建包com.test.dao.impl,在包中新建UserDAOImpl.java

package com.test.dao.impl;

import java.util.List;

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

import com.test.bean.User;
import com.test.dao.UserDAO;

public class UserDAOImpl extends HibernateDaoSupport implements UserDAO {

@SuppressWarnings("unchecked")
public List<User> findAllUsers() {
// 根据hql查询
//@SuppressWarnings("unchecked")
String hql = "from User user order by user.id desc";
return (List<User>)this.getHibernateTemplate().find(hql);
}

public User findUserById(Integer id) {
// TODO Auto-generated method stub
User user = (User)this.getHibernateTemplate().get(User.class, id);
return user;
}

public void removeUser(User user) {
// TODO Auto-generated method stub
this.getHibernateTemplate().delete(user);
}

public void saveUser(User user) {
// TODO Auto-generated method stub
this.getHibernateTemplate().save(user);
}

public void updateUser(User user) {
// TODO Auto-generated method stub
this.getHibernateTemplate().update(user);
}

}

10、新建包com.test.service,在包中新建UserService.java

package com.test.service;

import java.util.List;

import com.test.bean.User;

public interface UserService {

public List<User> findAll();

public void save(User user);

public void delete(User user);

public User findById(Integer id);

public void update(User user);
}

11、新建包com.test.service.impl,在包中新建UserServiceImpl.java

package com.test.service.impl;

import java.util.List;

import com.test.bean.User;
import com.test.dao.UserDAO;
import com.test.service.UserService;

public class UserServiceImpl implements UserService {

private UserDAO userDao;

public void delete(User user) {
// TODO Auto-generated method stub
this.userDao.removeUser(user);
}

public List<User> findAll() {
// TODO Auto-generated method stub
return this.userDao.findAllUsers();
}

public User findById(Integer id) {
// TODO Auto-generated method stub
return this.userDao.findUserById(id);
}

public void save(User user) {
// TODO Auto-generated method stub
this.userDao.saveUser(user);
}

public void update(User user) {
// TODO Auto-generated method stub
this.userDao.updateUser(user);
}

public UserDAO getUserDao() {
return userDao;
}

public void setUserDao(UserDAO userDao) {
this.userDao = userDao;
}

}

12、编辑structs.xml,添加action的信息

<?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>
<package name="user" extends="struts-default">
<action name="saveUser" class="saveUserAction">
<result name="success" type="redirect">listUser.action</result> <!-- 输入正确的话跳转到另一个action -->
<result name="input">/saveUser.jsp</result>  <!-- 输入错误的话跳就在saveUser.jsp页面继续输入 -->
</action>
</package>

</struts>

13、这时如果打开tomcat,会报错,Action class [saveUserAction] not found,这时因为我们的structs.xml里面配置的是一个别名,这个别名是由Spring来为我们提供的,但是这个Spring的配置文件我们还没编写。

14、把mysql-connector-java-5.0.3-bin.jar连接器拷贝到项目的lib目录下,编辑/WebRoot/WEB-INF/applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"> 
<!-- 整个文件是一层一层注入,从数据源注入到sessionFactory,然后从sessionFactory注入到dao -->

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <!-- 配置数据库连接池 -->
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mytest"></property>
<property name="username" value="root"></property>
<property name="password" value="moiyer"></property>
<property name="maxActive" value="100"></property>
<property name="maxIdle" value="30"></property>
<property name="maxWait" value="500"></property>
<property name="defaultAutoCommit" value="true"></property> <!-- 本项目中的操作不需要事务,都是原子性的 -->
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/test/bean/User.hbm.xml</value><!-- 即包com.test.bean下的User.hbm.xml -->
</list>
</property>
</bean>

<bean id="userDao" class="com.test.dao.impl.UserDAOImpl" scope="singleton"> <!-- 这个singleton与设计模式里的singleton模式不同 -->
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>

<bean id="userService" class="com.test.service.impl.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>

<bean id="saveUserAction" class="com.test.action.user.SaveUserAction">
<property name="service" ref="userService"></property>
</bean>
</beans>

这时打开tomcat,会报错,Error creating bean with name 'sessionFactory' defined in...这是因为myeclipse为我们自动导入包的时候造成了包冲突,删除lib目录下的asm-2.2.3.jar即可解决。

15、到现在为止,项目的ssh框架已经完全整合起来了。打开tomcat,访问[url=http://localhost:8080/mytest/index.jsp]http://localhost:8080/mytest/index.jsp,保存用户,不论中英文都可以在数据库中保存(将字符集设置成utf-8比较好:将页面pagecoding设置成utf-8,将structs设置成utf-8(默认已如此),将mysql设置成utf-8)。这时保存用户提交后页面会跳转到一个无法访问的页面,这是因为这个页面我们还没有写,但是可以从数据库看是否成功。

16、在包com.test.action.user中新建ListUserAction.java

package com.test.action.user;

import java.util.Map;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.test.service.UserService;

public class ListUserAction extends ActionSupport {

@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
Map request = (Map) ActionContext.getContext().get("request");
request.put("list", service.findAll());
return SUCCESS;
}

private UserService service;

public UserService getService() {
return service;
}

public void setService(UserService service) {
this.service = service;
}
}

在structs.xml中加上listuser的action

<action name="listUser" class="listUserAction">
<result>/list.jsp</result> <!-- 直接跳到list.jsp -->
</action>

在applicationContext.xml中加上listuser的bean

<bean id="listUserAction" class="com.test.action.user.ListUserAction">
<property name="service" ref="userService"></property>
</bean>


17、在WebRoot中新建list.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>         <!--  增加页面的structs支持 -->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>

<title>list page</title>

</head>

<body>
<h1><font color="red">User List</font>
</h1>

<table border="1" align="center"><!-- 删除和更新操作以后再实现 -->
<tr>
<td>id
</td>
<td>姓
</td>
<td>名
</td>
<td>年龄
</td>
<td>删除
</td>
<td>更新
</td>
</tr>
<s:iterator value="#request.list" id="us">
<tr>
<td><s:property value="#us.id"/>
</td>
<td><s:property value="#us.firstname"/>
</td>
<td><s:property value="#us.lastname"/>
</td>
<td><s:property value="#us.age"/>
</td>
<td><s:a href="deleteUser.action?user.id=%{#us.id}">delete</s:a>
<td><s:a href="updatePUser.action?user.id=%{#us.id}">update</s:a>
</td>
</tr>
</s:iterator>

</table>
</body>
</html>

18、重新打开tomcat,进行插入用户操作,操作成功。自此,这个小项目基本完成。


19、添加输入校验信息。有两种方法:(1)、使用在action的validate方法中进行输入信息的校验。(2)、使用模型驱动来进行校验,基于structs2校验框架。第一种方法比较容易理解,下面使用第二种方法来实现。有2种校验方式,方法1)编写校验文件:在包com.test.action.user包中新建SaveUserAction-validation.xml(注意名字一定为这个)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
<field name="user.firstname">
<field-validator type="requiredstring">
<message>required first name</message>
</field-validator>
</field>

<field name="user.lastname">
<field-validator type="requiredstring">
<message>required last name</message>
</field-validator>
</field>

<field name="user.age">
<field-validator type="required">
<message>required age</message>
</field-validator>
<field-validator type="int">
<param name="min">1</param>
<param name="max">150</param>
<message>age should be between ${min} and ${max}</message>
</field-validator>
</field>

</validators>

方法2)在包com.test.action.user包中新建SaveUserAction-validation.xml(注意名字一定为这个)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
<field name="user">
<field-validator type="visitor">        <!-- visitor类型表示通过另外一个配置文件对user的属性进行校验 -->
<param name="context">user</param>   <!-- 与实际校验文件的名字有关,“类名-user-validation” -->
<param name="appendPrefix">true</param>  <!-- 几个提示信息的前缀相同,都为user's -->
<message>user's </message>
</field-validator>
</field>
</validators>



在com.test.bean包中新建校验文件User-user-validation.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0.2//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">

<validators>
<field name="firstname">
<field-validator type="requiredstring">
<message>required first name</message>
</field-validator>
</field>

<field name="lastname">
<field-validator type="requiredstring">
<message>required last name</message>
</field-validator>
</field>

<field name="age">
<field-validator type="required">
<message>required age</message>
</field-validator>
<field-validator type="int">
<param name="min">1</param>
<param name="max">150</param>
<message>age should be between ${min} and ${max}</message>
</field-validator>
</field>

</validators>

20、好了,校验框架完成了。但是如果第一次输入的数据错误,点提交报错后,再填错误的信息提交,但是输出的错误消息会叠加,这显然是错误的。对于使用structs2.0管理的项目,请求来了之后,actionservelet会创建一个action,不会出现这个错误。但是我们的项目是由spring管理的,action是由bean工厂来创建的,默认是单例的,即使用创建的一个action来处理所有的用户请求,所以就会出现上述错误。解决方法 是修改applicationContext.xml的action申明

<bean id="saveUserAction" class="com.test.action.user.SaveUserAction" scope="prototype">   <!-- scope保证对于每一个新的请求,会创建一个新的action来处理 -->
<property name="service" ref="userService"></property>
</bean>

<bean id="listUserAction" class="com.test.action.user.ListUserAction"  scope="prototype">
<property name="service" ref="userService"></property>
</bean>

21、删除用户功能。在包com.test.action.user中新建RemoveUserAction.java

package com.test.action.user;

import com.opensymphony.xwork2.ActionSupport;
import com.test.bean.User;
import com.test.service.UserService;

public class RemoveUserAction extends ActionSupport
{
private User user;
private UserService service;

public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public UserService getService()
{
return service;
}
public void setService(UserService service)
{
this.service = service;
}

@Override
public String execute() throws Exception
{
this.service.delete(user);

return SUCCESS;
}

}


在structs.xml中添加action的声明

<action name="deleteUser" class="removeUserAction">
<result name="success" type="redirect">listUser.action</result>
</action>

在applicationContext.xml中添加action的声明

<bean id="removeUserAction" class="com.test.action.user.RemoveUserAction" scope="prototype">
<property name="service" ref="userService"></property>
</bean>

好了,项目的删除功能已经完成了。

22、完成更新功能。在包com.test.action.user中新建UpdatePUserAction.java这个action进行更新预处理

package com.test.action.user;

import com.opensymphony.xwork2.ActionSupport;
import com.test.bean.User;
import com.test.service.UserService;

public class UpdatePUserAction extends ActionSupport
{
private User user;
private UserService service;

public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public UserService getService()
{
return service;
}
public void setService(UserService service)
{
this.service = service;
}

@Override
public String execute() throws Exception
{
user = this.service.findById(user.getId());    //两个user不是一样的

return SUCCESS;
}
}

在structs.xml中添加action的声明

<action name="updatePUser" class="updatePUserAction">
<result name="success">/update.jsp</result>
</action>

在applicationContext.xml中添加action的声明

<bean id="updatePUserAction" class="com.test.action.user.UpdatePUserAction" scope="prototype">
<property name="service" ref="userService"></property>
</bean>

在WebRoot下新建update.jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'update.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->

</head>

<body>

<h1><font color="red">Update User</font></h1>

<s:form action="updateUser">

<table>
<tr>
<td>
<s:hidden name="user.id" value="%{user.id}"></s:hidden>  <!-- 将id设为不显示,但是还是会提交 -->
</td>
</tr>

<tr>
<td>
<s:textfield name="user.firstname" value="%{user.firstname}" label="%{getText('firstname')}"></s:textfield>
</td>
</tr>

<tr>
<td>
<s:textfield name="user.lastname" value="%{user.lastname}" label="%{getText('lastname')}"></s:textfield>
</td>
</tr>

<tr>
<td>
<s:textfield name="user.age" value="%{user.age}" label="%{getText('age')}"></s:textfield>
</td>
</tr>

<tr>
<td>
<s:submit></s:submit>
</td>
</tr>
</table>

</s:form>

</body>
</html>

在包com.test.action.user中新建UpdateUserAction.java这个action真正进行更新

package com.test.action.user;

import com.opensymphony.xwork2.ActionSupport;
import com.test.bean.User;
import com.test.service.UserService;

public class UpdateUserAction extends ActionSupport
{
private User user;
private UserService service;

public User getUser()
{
return user;
}

public void setUser(User user)
{
this.user = user;
}

public UserService getService()
{
return service;
}

public void setService(UserService service)
{
this.service = service;
}

@Override
public String execute() throws Exception
{
this.service.update(user);

return SUCCESS;
}

}

在structs.xml中添加action的声明

<action name="updateUser" class="updateUserAction">
<result name="success" type="redirect">listUser.action</result>
<result name="input">/update.jsp</result>
</action>

在applicationContext.xml中添加action的声明

<bean id="updateUserAction" class="com.test.action.user.UpdateUserAction" scope="prototype">
<property name="service" ref="userService"></property>
</bean>

输入校验,在包com.test.user.action中新建UpdateUserAction-validation.xml,内容与SaveUserAction-validation.xml相同。

到此,更新功能已经完成。



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: