【轉】http://blog.sina.com.cn/s/blog_a6a6b3cd01017c57.html
什么是SSH?
SSH對應 struts spring hibernate
struts 采用MVC模式,主要是作用於用戶交互
spring 采用IOC和AOP~作用比較抽象,是用於項目的松耦合
hibernate 是對象持久化框架,其實就是實體類和數據庫表建立關系,操作類就會觸發相應的sql語句,可以不用寫任何sql語句,完成數據庫編程(引自百度知道)
SSH就是Struts + Spring + Hibernate 3個Java框架的集合,現在Java開發中常用的框架組合。用來開發后台,與前台和數據庫進行數據交互。最初學這個是為了寫JSP。
SSH框架搭建步驟很多,但是不難,因為MyEclipse已經幫我們做了大部分的工作,如果純手動添加這個框架的話,那真是夠復雜的了。不過涉及的知識挺多的,適合有一定基礎的人。下面詳細介紹一下SSH框架的搭建步驟並且解決了幾個我在搭建過程中遇到的問題。
事先准備工作:1.JDK
這個是一切的前提,相信大家都有。沒有的話下面的步驟也不用看了,先安裝JDK,配置環境變量吧。
JDK 7.0 下載:http://www.onlinedown.net/soft/61003.htm
配置Java環境變量教程:http://jingyan.baidu.com/article/f96699bb8b38e0894e3c1bef.html2.MyEclipse
我們主要用MyEclipse來搭建SSH, 所以這個必須有,我用MyEclipse 8.5搭建過SSH,沒問題。沒有的話建議下載高版本的,與時俱進嘛。漢化或者不漢化看個人習慣,我覺得中文用起來比較舒服。
Myeclipse 10 下載:http://www.pc6.com/softview/SoftView_57131.html
Myeclipse 漢化包及漢化教程:http://blog.csdn.net/cntanghai/article/details/63102003.MySQL
數據庫,注意安裝時設置的密碼千萬別忘了。
MySQL詳細圖文安裝教程:http://jingyan.baidu.com/article/642c9d34aa809a644a46f717.html
MySQL 5.5.28 下載:http://down.chinaz.com/soft/29015.htm4.Navicat for MySQL
MySQL視圖化管理及開發工具,主要用他來操作MySQL。推薦安裝,非必須。
Navicat for MySQL v10.1.7簡體中文特別版下載:http://www.xiazaiba.com/html/2122.html
5.mysql-connector-java-5.0.8-bin.jar
Java連接MySQL數據庫時需要用到的jar包。
jar下載:http://pan.baidu.com/share/link?shareid=444190&uk=4262258889
6.在MySQL中新建一個表,用來測試數據
我在這里准備做一個注冊登錄功能,所以在test里建了一個user表,表里的字段有id、username、password、nickname四個字段。nickname用來測試中文是否亂碼。
SQL語句:
CREATE TABLE `user` (
`id` bigint(20) unsigned NOT NULL auto_increment COMMENT 'ID',
`username` varchar(40) character set utf8 NOT NULL COMMENT '用戶名',
`password` varchar(40) collate utf8_unicode_ci NOT NULL COMMENT '密碼',
`nickname` varchar(40) character set utf8 NOT NULL COMMENT '昵稱',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='用戶信息表';
SSH框架搭建步驟:
1.新建一個項目。打開MyEclipse,新建一個Web項目,起名就叫SSH吧,點擊完成,若彈出提示點Yes即可。
2.添加Struts框架。右鍵這個項目,選擇MyEclipse->Add Struts Capabilities。 在彈出的菜單中把包的路徑改一下, Base package for new classes選項中的路徑com.yourcompany.struts改成com.ssh.struts, 點擊完成。
展開WebRoot中的WEB-INF文件夾,看到目錄結構如下圖,證明Struts框架添加完成。
3.添加Spring框架。右鍵這個項目,選擇MyEclipse->Add Spring Capabilities。
在菜單中選擇如下6個庫,點擊下一步。
更改Folder路徑,選擇SSH項目WebRoot文件夾下的WEB-INF,完成。
現在項目的目錄結構如下,Spring框架添加完成。
4.連接數據庫。點擊右上角的圖標"打開透視圖",選擇MyEclipse Database Explorer。在窗口中右鍵->New 新建一個數據庫連接。
Driver template 選擇 MySQL Connector/J
Driver name 起名叫test
Connection URL 更改為jdbc:mysql://自己的IP地址:端口號/數據庫名稱
User name 填寫MySQL的用戶名
Password 填寫MySQL的密碼
Driver JARs 點擊Add JARs按鈕,瀏覽到事先准備的mysql-connector-java-5.0.8-bin.jar
Save password 選上
點擊Test Driver,測試結果:數據庫配置正確,點擊完成。
雙擊添加的test連接,展開目錄,可以發現我們事先創建的user表。
5.添加Hibernate框架。右鍵SSH項目,選擇MyEclipse->Add Spring Capabilities。
點擊下一步。
配置中選擇第二項"Spring configuration file"。把Spring與Hibernate整合到一起,點擊下一步。
在菜單中選第二項"Existing Spring configuration file",點擊下一步。
DB Driver選擇在添加Spring框架時配置的test,點擊下一步。
取消Create SessionFactory class?這個選項,點擊完成。
現在的目錄結構如下,SSH框架大體搭建完成。
6.測試功能。
先部署一下項目,訪問首頁看看效果。選擇窗口上方圖標"Deploy MyEclipse J2EE Project to Server"->點擊add添加SSH項目->Server選擇MyEclipse Tomcat。
項目部署成功。
點擊窗口上方圖標"Run MyEclipse Servers"啟動Tomcat。
在瀏覽器中訪問SSH項目地址,別忘了加上Tomcat的默認端口,8080端口。
輸入地址:http://localhost:8080/SSH,Tomcat會訪問SSH項目WebRoot下的index.jsp。
現在修改一下index.jsp中給的內容,在Body中添加"這是我的首頁"。Ctrl+S保存。
這里出現了一個問題,頁面默認的編碼為ISO-8859-1,不支持中文字符,無法保存。我們先把這個提示關掉。
選擇窗口->首選項->MyEclipse->JSP->Files and Editors->JSP,把編碼改為ISO 10646/Unicode(UTF-8)->應用->確定。
編碼問題是一個很常見的問題,為避免出現這類我提我們盡量將工作空間的所有編碼格式統一,無論前台后台還是數據庫,否則會引發許多問題,例如中文亂碼。
選擇窗口->首選項->常規->工作空間->文本文件編碼選擇其他->其他選項里選擇UTF-8->應用->確定。
這樣設置后,我們的工作空間編碼就比較統一了,再生成的JSP頁面就是UTF-8編碼格式了,能夠很好的支持中文字符,不過之前生成的JSP頁面編碼格式要我們手動更改。
把index.jsp中<%@ page language="java" import="java.util.*" pageEncoding="XXX"%> 的pageEncoding改為UTF-8,再保存頁面。這時再訪問http://localhost:8080/SSH , 正確顯示中文,這回沒問題了。
現在寫個注冊登錄的功能來測試一下框架整合的結果。
切換到MyEclipse DataBase Explorer視圖,通過Spring框架的逆向工程功能把user表逆向成Java實體類。右鍵user表選擇"Hibernate Reverse Engineering"。
Java src folder 選擇SSH項目下的src文件夾。
Java package 填寫com.ssh.user
勾選前三個選項:Create POJO、Java Data Obect和Java Data Access Object。POJO類是數據庫表格所對應的Java類,JDO類是MyEclipse自動生成的對數據庫的一些操作,這里會封裝一些常用的操作,基本上可以滿足我們的各種需要了,選擇下一步。
Id Generator 選擇 native,點擊完成。
此時的目錄結構如下,我們可以看到系統生成了3個類,一個配置文件。
User 繼承自AbstractUser,是User表的實體類。
UserDAO 封裝了一些對數據庫的常用操作。
User.hbm.xml 是hibernate-mapping映射配置文件,配置了哪個實體類映射哪個表,配置了實體類的哪個屬性映射表里的哪列。
如果這些東西不用hibernate生成,那么我們就要自己寫,要浪費很多時間,hibernate的作用就體現出來了。
現在來寫測試頁。打開WEB-INF文件夾下的struts-config.xml文件,切換到設計視圖(design)。右鍵->New->Form Action and JSP。
填寫Form表單屬性:
Use case: login
Name:loginForm
在下方Form Properties中添加兩個屬性
username: JSP input type text
password: JSP input type password
切換到JSP選項,填寫JSP屬性:
勾選Create JSP form
路徑修改為/jsp/login.jsp
點擊完成。
此時的目錄結構如下,可以看到在WebRoot/jsp/下 生成了一個login.jsp頁。
我們查看一下現在的目錄結構,並把struts-config.xml切換到Source視圖,看看struts框架幫我們干了什么。
可以看到目錄里多了3個文件:LoginFrom.java、LoginAction.java、login.jsp。這正是我們在設計視圖里選擇Form,Action and JSP所配置的文件。而struts-config.xml里也相應的添加了這3個文件的映射配置信息。如果這些不用struts生成的話,就需要我們自己寫,會浪費很多時間,struts的作用體現出來了。
這里說一下頁面請求的執行順序:
1、login.jsp用戶填寫了登錄信息並點擊了登錄按鈕,發送了一個請求(loginFrom.do)。
2、struts會通過struts-config.xml找到相應的映射配置(Action name==loginFrom)。
3、把登錄表單的屬性映射到loginForm.java里(bean)。
4、把loginForm和mapping、request、response一起交給LoginAction處理。
5、LoginAction執行完后的通過mapping找到跳轉頁面forward(這個下面會提到)。
現在添加兩個頁面:登錄成功頁和登錄失敗頁,實現登錄后的跳轉。
在WebRoot/jsp/下新建兩個JSP頁。起名為loginSuccess.jsp和loginFail.jsp。
向導信息如下:
在loginSuccess.jsp頁面body中添加"登錄成功!<br>"。
在loginFail.jsp頁面body中添加"登錄失敗<br>"。
把登錄頁、登錄成功頁、登錄失敗頁3個頁面相關聯。
切換到struts-config.xml的設計視圖。右鍵login.jsp->New->Forward。
loginSuccess:
選擇Local Action Forward
瀏覽Action Path:/login
填寫name:loginSuccess
瀏覽Path:/jsp/loginSuccess.jsp
完成
loginFail:
選擇Local Action Forward
瀏覽Action Path:/login
填寫name:loginFail
瀏覽Path:/jsp/loginFail.jsp
完成
切換到Source視圖,可以看到代碼如下圖:
Action里多了
<forward name="loginSuccess" path="/jsp/loginSuccess.jsp" />
<forward name="loginFail" path="/jsp/loginFail.jsp" />
兩行代碼,頁面跳轉添加完成。
現在來寫具體的執行代碼。打開LoginAction.java。可以看到自動生成的代碼如下圖:
我們先不連數據庫,先寫一個測試的登錄代碼。
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
//獲取帳號密碼
String username = loginForm.getUsername();
String password = loginForm.getPassword();
//帳號密碼匹配,跳轉到登錄成功頁
if("asd".equals(username) && "asd123".equals(password)){
return mapping.findForward("loginSuccess");
}
//不匹配,跳轉到登錄失敗頁
return mapping.findForward("loginFail");
}
准備就緒,啟動Tomcat,在瀏覽器中訪問登錄頁:
http://localhost:8080/SSH/jsp/login.jsp
看到這個界面,都是英文,很不爽,不僅僅因為丑。把它改成中文的,打開login.jsp,代碼如下:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>JSP for LoginForm form</title>
</head>
<body>
<html:form action="/login">
username : <html:text property="username"/><html:errors property="username"/><br/>
password : <html:password property="password"/><html:errors property="password"/><br/>
<html:submit/><html:cancel/>
</html:form>
</body>
</html>
改成:
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>用戶登錄</title>
</head>
<body>
<html:form action="/login">
帳號 : <html:text property="username"/><html:errors property="username"/><br/>
密碼 : <html:password property="password"/><html:errors property="password"/><br/>
<html:submit value="登錄"/><html:cancel value="取消"/>
</html:form>
</body>
</html>
刷新一下登錄頁面,看看效果:
登錄界面漢化成功!看起來舒服多了。點擊登錄。
這時候因為我們什么都沒填,應該跳轉到登錄失敗頁面。
后退,回到登錄界面,填寫
帳號:asd
密碼:asd123
點擊登錄,帳號密碼和后台設置的匹配,這時候應該跳轉到登錄成功界面。
測試完成,下面我們連接一下數據庫,從數據庫里取出user數據進行匹配。
想操作數據庫我們要先獲取DAO(data access object),我們的UserDAO是hibernate生成的,關於UserDAO的配置信息寫在了applicationContext.xml里。所以在用UserDAO之前要先獲取applicationContext.xml。
百度上查找了一下相關代碼,找到了一個獲取applicationContext.xml的方法。Spring框架里的
ClassPathXmlApplicationContext 通過這個類可以獲取到我們需要的DAO。名字和applicationContext非常像,看起來就是這個類了。
測試一下這個類是否好用:
把LoginAction打開,把代碼改為:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
//獲取帳號密碼
String username = loginForm.getUsername();
String password = loginForm.getPassword();
//獲取用戶信息
ClassPathXmlApplicationContext beans = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println(beans);
//帳號密碼匹配,跳轉到登錄成功頁
if("asd".equals(username) && "asd123".equals(password)){
return mapping.findForward("loginSuccess");
}
//不匹配,跳轉到登錄失敗頁
return mapping.findForward("loginFail");
}
重新啟動Tomcat服務器,訪問登錄頁http://localhost:8080/SSH/jsp/login.jsp,點擊登錄:
javax.servlet.ServletException: org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: class path resource [applicationContext.xml] cannot be opened because it does not exist
出現了一個錯誤,意思為找不到applicationContext.xml。看來我們填寫的路徑有問題,這個配置文件應該是從我們項目classes的根目錄開始查找的,先看一下我們的項目發布后classes的路徑,右鍵SSH項目->屬性->Java構建路徑->源代碼。
可以看到我們項目發布后classes的根目錄是SSH/WebRoot/WEB-INF/classes。 applicationContext.xml是這個位置的上一級,那么相對於這個路徑的位置就是"../applicationContext.xml"。現在把LoginAction里的路徑修改一下:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
//獲取帳號密碼
String username = loginForm.getUsername();
String password = loginForm.getPassword();
//獲取用戶信息
ClassPathXmlApplicationContext beans = new ClassPathXmlApplicationContext("../applicationContext.xml");
System.out.println(beans);
//帳號密碼匹配,跳轉到登錄成功頁
if("asd".equals(username) && "asd123".equals(password)){
return mapping.findForward("loginSuccess");
}
//不匹配,跳轉到登錄失敗頁
return mapping.findForward("loginFail");
}
重新啟動Tomcat服務器,訪問登錄頁http://localhost:8080/SSH/jsp/login.jsp,點擊登錄:
頁面不再報錯,正常跳轉,控制台也輸出了:
org.springframework.context.support.ClassPathXmlApplicationContext@14bb075: startup date [Mon Apr 22 14:26:58 CST 2013]; root of context hierarchy]
路徑的問題解決了,正確的獲取到了配置信息,這個配置信息我們以后要經常用,並且沒必要每次用的時候都把它創建出來,浪費時間,寫一個全局變量保存它吧。在src下新建一個包com.ssh.common,在包里新建一個類Global.java。輸入代碼如下:
package com.ssh.common;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Global {
public static ClassPathXmlApplicationContext beans = new ClassPathXmlApplicationContext("../applicationContext.xml");
public static Object getDAO(String daoName){
return beans.getBean(daoName);
}
}
現在來獲取數據庫里的數據,在user表里新增一個用戶信息
username=asd
password=asd123
nickname=中文不是亂碼
把LoginAction里的代碼改為:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
//獲取帳號密碼
String username = loginForm.getUsername();
String password = loginForm.getPassword();
//檢查該用戶是否存在
User instance = new User();
instance.setUsername(username);
instance.setPassword(password);
UserDAO userDAO = (UserDAO)Global.getDAO("UserDAO");
List<?> list = userDAO.findByExample(instance);
//如果用戶存在,則登錄成功。
if(list.size() > 0){
User user = (User)list.get(0);
String nickname = user.getNickname();
//寫入提示信息
request.setAttribute("message", "您的昵稱為:" + nickname);
return mapping.findForward("loginSuccess");
}
//不匹配,跳轉到登錄失敗頁
return mapping.findForward("loginFail");
}
在loginSuccess.jsp的Body中添加一行代碼:
<%=request.getAttribute("message")%><br>
重新啟動Tomcat服務器,訪問登錄頁http://localhost:8080/SSH/jsp/login.jsp
填寫帳號:asd 密碼:asd123 點擊登錄:
登錄功能完成,這是個SSH框架的搭建教程,這些測試功能就盡量簡單了,大家別介意,下面來做注冊功能。
切換到struts-config.xml的設計視圖,右鍵New->Form,Action and JSP
Use case填寫register
Form Properties填寫3個屬性
username:text
password:password
nickname:text
點選JSP選項,勾選Create JSP form, 路徑更改為/jsp/register.jsp
現在把register.jsp與login.jsp關聯,做注冊成功和注冊失敗的跳轉。
右鍵struts-config.xml設計視圖中的regiser.jsp->New->Forward。
選擇Local Action Forward
Action Path:/register
Name:registerSuccess
Path:/jsp/login.jsp
完成
右鍵struts-config.xml設計視圖中的regiser.jsp->New->Forward。
選擇Local Action Forward
Action Path:/register
Name:registerFail
Path:/jsp/register.jsp
完成
struts-config.xml代碼如下
漢化注冊頁面
<%@ page language="java" pageEncoding="UTF-8"%>
<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<html>
<head>
<title>注冊頁</title>
</head>
<body>
<html:form action="/register">
用戶名 : <html:text property="username"/><html:errors property="username"/><br/>
密碼 : <html:password property="password"/><html:errors property="password"/><br/>
昵稱 : <html:text property="nickname"/><html:errors property="nickname"/><br/>
<html:submit value="確定"/><html:cancel value="取消"/>
</html:form>
</body>
</html>
打開RegisterAction.java文件,實現數據的插入,修改代碼如下:
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
//填寫的注冊信息
RegisterForm registerForm = (RegisterForm) form;
String username = registerForm.getUsername();
String password = registerForm.getPassword();
String nickname = registerForm.getNickname();
//檢查用戶名是否已被注冊
UserDAO userDAO = (UserDAO)Global.getDAO("UserDAO");
List<?> list = userDAO.findByUsername(username);
//用戶名已被注冊,返回注冊頁面
if(list.size() > 0){
request.setAttribute("message", "該用戶名已被注冊");
return mapping.findForward("registerFail");
}
//插入新用戶
User user = new User();
user.setUsername(username);
user.setPassword(password);
user.setNickname(nickname);
userDAO.save(user);
request.setAttribute("message", "注冊成功,請登錄:" + nickname);
return mapping.findForward("registerSuccess");
}
打開login.jsp在body中添加一行代碼<%=request.getAttribute("message")%><br>
重新啟動Tomcat服務器,訪問注冊頁http://localhost:8080/SSH/jsp/register.jsp
輸入帳號:asd2
輸入密碼:asd123
輸入昵稱:中文不應該是亂碼
點擊確認
頁面提示:注冊成功,請登錄:䏿–‡ä¸åº”该是乱ç
我們期望的是"中文不應該是亂碼",但它變成亂碼了,很常見的一種問題。百度查了一下相關問題,原因是使用Tomcat服務器時,struts的Form提交不支持中文,於是我們需要添加一個過濾器。
在com.ssh.common包下新建一個TomcatFormFilter類,代碼如下:
package com.ssh.common;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class TomcatFormFilter implements Filter{
//接收字符編碼
protected String encoding;
public TomcatFormFilter(){}
public void init(FilterConfig filterConfig) throws ServletException {
//從web.xml中讀取encoding值
encoding = filterConfig.getInitParameter("encoding");
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if(request.getCharacterEncoding() == null && encoding != null){
//設置字符集
request.setCharacterEncoding(encoding);
}
//繼續執行
chain.doFilter(request, response);
}
public void destroy() {}
}
拷貝這個類中注釋代碼部分的xml,粘貼到web.xml中
重新啟動Tomcat服務器,訪問注冊頁http://localhost:8080/SSH/jsp/register.jsp
輸入帳號:asd3
輸入密碼:asd123
輸入昵稱:這回中文不應該是亂碼了
點擊確定
至此SSH框架的搭建全部完成