從今天開始一個Java Web實戰項目,參考自 http://blog.csdn.net/eson_15/article/details/51277324 這個博客(很是感謝博主的分享精神)。本博客系列文章也會參考前面博客中項目的進度來寫,所以標題可能高度類似,章節結構也可能類似,只是內容排版和行文上會有些區別。html
如今開始記錄我開發的過程,爭取每個項目中的每個知識點都有一個比較詳細的記錄,對每一個知識點儘量記錄總結好1. 基本原理,2.框架/工具使用配置, 2.框架/工具/解決方案的基本用法。技術能力須要在實踐中獲得提升,概念也須要從實踐中才能深入理解,可是光作項目不夠,還須要作總結,消化作過的項目,才能真正變成本身的知識。java
須要說明的是本博客是邊開發變記錄, 所以不少東西可能不會很準確,也不會很全面, 後續會逐步訂正和完善的。mysql
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++web
下面開始本項目第一篇,環境的搭建,本項目主要使用主流框架SSH來完成。 搭建環境的總體步驟是是,spring
這個步驟須要注意的是作好java web的基本設置,例如編碼之類。以及tomcat的一些基本配置。sql
下載tomcat,也能夠下載xampp集成包,由於裏面帶有mysql使用方便。解壓tomcat目錄結構以下,數據庫
若是單獨配置tomcat,咱們須要使用以下一些配置文件apache
1 bin:二進制執行文件。裏面最經常使用的文件是startup.bat,若是是 Linux 或 Mac 系統啓動文件爲 startup.sh。 啓動tomcat後 2 conf:配置目錄。裏面最核心的文件是server.xml。能夠在裏面改端口號等。默認端口號是8080,也就是說,此端口號不能被其餘應用程序佔用。 3 lib:庫文件。tomcat運行時須要的jar包所在的目錄 4 logs:日誌 5 temp:臨時產生的文件,即緩存 6 webapps:web的應用程序。web應用放置到此目錄下瀏覽器能夠直接訪問 7 work:編譯之後的class文件。
若是啓動上面的startup.bat, 在瀏覽器輸入 http://localhost:8080/, 則能夠看到tomcat的控制檯頁面(經典的湯姆貓頁面),本篇暫不對tomcat的管理頁面作介紹,由於本項目將使用Eclipse集成tomcat搭建web服務器。
若是要在Eclipse中集成tomcat,則不須要改動以上配置,直接在Eclipse中新建一個server,將路徑指向tomcat的根目錄便可,而且無需進入tomcat的bin目錄去啓動tomcat,而是直接在Eclipse中啓動。windows
在Eclipse搭建基本的Java Web運行環境步驟以下,設計模式
這樣就算是配置了好了一個能運行的java web應用了, 注意上面的web.xml若是沒有自動生成, 能夠直接拷貝 tomcat根目錄的webapps\examples\WEB-INF\web.xml來用;
若是上面的tomcat library沒有導入進web工程, 也能夠手動在build path->libraries->Add libraries->Server Runtime中添加tomcat。
若是不盡早統一編碼, 因爲後續須要往工程中添加jsp, java, xml 等多種不一樣類型的文件, 同時還須要鏈接數據庫, 不一樣編碼的數據在不一樣載體中傳輸存儲,勢必會引發亂碼問題, 所以須要儘早統一編碼。
在Eclipse中,默認編碼是ISO-8859-1,不支持中文,能夠設置全局的缺省字符編碼(即默認編碼),設置步驟以下。
a. windows->preference->general->workspace, 設置textfile encoding 爲UTF-8
b.windows->preference->general->content types, 將右邊全部文件都設置爲UTF-8
c. 若是以上方法不起做用,還能夠嘗試直接找到相應類型的文件設置編碼,以下
Spring中的jar包多達六七十個,但咱們並不須要使用所有jar包。
按照Spring4.2.4 reference大體能夠分爲,core, aop, message, data access, web, test這6個模塊, 咱們也能夠在Eclipse中分別建立不一樣的user library, 參考上面博客的分法,我也建立了以下library.
當咱們導入core和aop兩個library以後,就已經能夠進行Spring最基本的IOC特性的測試了,下面是一個簡單的測試用例。
Spring的test模塊中,org.springframework.test.context.junit4包提供在Junit下進行Spring集成測試的功能, 其中SpringJUnit4ClassRunner類提供了Spring容器,註解功能。
要在Junit中作基本的Spring容器測試,只須要在測試類頭部添加註解 @RunWith(SpringJUnit4ClassRunner.class)
Junit默認會從類加載目錄加載applicationContext.xml配置文件,固然也能夠經過類頭部的 @ContextConfiguration(locations="classpath*:testSpringContext.xml") 自定義配置文件,
若是在測試類中定義一個自動裝配的容器對象
@Autowired
private ApplicationContext ctx
則此容器對象就能自動根據Junit測試類默認的spring配置文件或者自定義的配置文件進行初始化,
此時就能直接在測試類中使用Spring容器對象去加載Spring中的bean了! 一個基本的Junit集成Spring測試類以下,
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration(locations="classpath*:testSpringContext.xml") 3 public class TestSpring { 4 @Autowired 5 private ApplicationContext ctx; 6 7 @Test 8 public void testSpringIoc() { 9 TestBean tb = (TestBean)ctx.getBean("testBean"); 10 tb.test(); 11 } 12 }
如今就在當前的J2eeShop工程中經過Junit測試Spring容器的基本功能,
先建立一個測試Bean,
1 package test; 2 3 public class TestBean implements java.io.Serializable { 4 private String name; 5 private int age; 6 public String getName() { 7 return name; 8 } 9 public void setName(String name) { 10 this.name = name; 11 } 12 public int getAge() { 13 return age; 14 } 15 public void setAge(int age) { 16 this.age = age; 17 } 18 public void test() { 19 System.out.println("this is TestBean.test()"); 20 System.out.println("name="+this.getName()+",age="+this.getAge()); 21 } 22 }
從spring的文檔中拷貝一個配置文件模板內容,在6.2.1 Configuration metadata章節就有一個,而後配置一個最基本的測試bean
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:context="http://www.springframework.org/schema/context" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 9 10 <context:component-scan base-package="test" /> 11 12 <bean id="testBean" class="test.TestBean"> 13 <property name="name" value="zhangsan" /> 14 <property name="age" value="25" /> 15 </bean> 16 </beans>
建立一個Junit測試類,
1 package test; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Test; 6 import org.junit.runner.RunWith; 7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.context.ApplicationContext; 9 import org.springframework.test.context.ContextConfiguration; 10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 11 12 @RunWith(SpringJUnit4ClassRunner.class) 13 @ContextConfiguration(locations="classpath*:testSpringContext.xml") 14 public class TestSpring { 15 @Autowired 16 private ApplicationContext ctx; 17 18 @Test 19 public void testSpringIoc() { 20 TestBean tb = (TestBean)ctx.getBean("testBean"); 21 tb.test(); 22 } 23 }
執行結果,
this is TestBean.test() name=張三,age=25
咱們上面的步驟僅僅是單獨地配置了Web環境和Spring環境,並無將二者集成起來。 咱們在web.xml中配置<context-param>, 用來指定Spring容器的配置文,添加一個<listener>,用來監聽Spring容器對象。
1 <context-param> 2 <param-name>contextConfigLocation</param-name> 3 <param-value>/WEB-INF/applicationContext.xml, /WEB-INF/daoContext.xml</param-value> 4 </context-param> 5 6 <listener> 7 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 8 </listener>
這樣,當Java web應用啓動時, 會負責根據Spring配置文件來初始化一個Sping的容器對象。
像上面那樣將Spring集成到Java web中後,Spring容器就會隨着java web應用的啓動而啓動,可是整個過程的基本原理是怎樣的呢。
要弄清楚這個問題,須要先搞清楚java web應用,即servlet在tomcat中的啓動過程。
如下文章詳細描述了servlet在tomcat中的工做原理,
Servlet 工做原理解析 - https://www.ibm.com/developerworks/cn/java/j-lo-servlet/
Tomcat 系統架構與設計模式,第 2 部分: 設計模式分析 - https://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/
tomcat從啓動到爲一個java web應用提供服務的過程很是複雜,我將上面的內容高度抽象成下五步,
前面說了java web應用程序的啓動過程,那麼集成在java web中的spring容器又是如何加載的呢?
咱們知道tomcat會使用觀察者/廣播訂閱的設計模式來通知事件的發生,當一個servlet容器(即建立了servletContext對象)啓動,即發生了一個servlet容器建立事件,
tomcat中的web容器會將這個事件通知給相應監聽對象。
在4.1節的第4步中,servletContext對象將會根據web.xml配置建立listener對象,咱們在第3節中在web.xml配置了一個ContextLoaderListener監聽器,
這是spring提供的一個監聽器,servlet容器在初始化的時候會根據web.xml配置建立這樣的監聽器對象,這個監聽器有什麼做用呢?
查看這個監聽器的源碼以下,
1 public class ContextLoaderListener extends ContextLoader 2 implements ServletContextListener 3 { 4 ... 5 public void contextInitialized(ServletContextEvent event) 6 { 7 initWebApplicationContext(event.getServletContext()); 8 } 9 ... 10 }
可見這個監聽器實現了servlet包中的ServletContextListener接口,並重寫其中的contextInitialized方法,
根據servlet技術描述,servlet中的ServletContextListener實現類的實例能夠監聽servlet容器的啓動(即建立servletContext對象)事件,並回調contextInitialized方法。
也就是說當上面的java web應用啓動以後,將會通知spring的這個監聽類對象,並回調被spring監聽類重寫的contextInitialized方法,
而在這個由spring監聽器重寫的回調方法中,進行了spring容器的初始化!即建立spring容器對象WebApplicationContext,並將此對象保存在servlet容器(即servletContext對象)中。
至此,java web容器完成了全部初始化工做,同時加載了spring容器,能夠在web應用中直接使用註冊在spring中的bean了,
上面過程比較複雜,下面再簡要總結一下java web應用加載spring容器的過程,
當咱們完成了java web應用於spring的集成配置以後,就能夠進行簡單的測試了,咱們能夠直接在jsp中經過WebApplicationContextUtils獲取spring容器對象,
index.jsp
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@page import="org.springframework.web.context.WebApplicationContext" %> 4 <%@page import="org.springframework.web.context.support.WebApplicationContextUtils" %> 5 <%@page import="test.TestBean" %> 6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 7 <html> 8 <head> 9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 10 <title>Insert title here</title> 11 </head> 12 <body> 13 <h1>Hello World</h1> 14 <% 15 WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); 16 TestBean tb = (TestBean) ctx.getBean("testBean"); 17 out.println("<h1>"+tb.getName()+"</h1>"); 18 tb.setName("lisi"); 19 %> 20 </body> 21 </html>
關鍵代碼,
1 <% 2 WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); 3 TestBean tb = (TestBean) ctx.getBean("testBean"); 4 out.println("<h1>"+tb.getName()+"</h1>"); 5 tb.setName("lisi"); 6 %>
執行結果,能夠看咱們並無顯式地初始化spring容器,而是用工具WebApplicationContextUtils(本質上是獲取由servlet容器初始化的spring容器)到了spring容器對象,將spring容器中的testBean的屬性打印出來了,
到這裏,spring框架就整合到了java web項目中,下一步是要整合Hibernate框架。
3、搭建Hibernate環境
首先也是導入Hibernat的必要jar包,以及Hibernate提供的一些第三方工具包(例如數據池C3P0和二級緩存ehcache),