SSH學習筆記(二)

二、小項目實踐

項目描述:對一個用戶的姓、名、年齡進行增刪查改,使用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" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

 <class name="com.test.bean.User" table="users">

 <id name="id" type="java.lang.Integer" column="id"> <generator class="increment"/><!-- 主鍵生成策略爲increment --> </id>

 <property column="firstname" name="firstname" type="string" length="50"> </property>  <property column="lastname" name="lastname" type="string"  length="50">  </property>   <property column="age" name="age" type="java.lang.Integer"> </property>  </class>

</hibernate-mapping>

6、新建包com.test.action.user,在包中新建SaveUserAction.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,訪問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相同。

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

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章