Struts2框架_快速入門(mén)

一憔涉、 Struts2概述

在MVC設(shè)計(jì)模式中,Struts2作為控制器(Controller)來(lái)建立模型與視圖的數(shù)據(jù)交互拘哨。

Struts 2是Struts的下一代產(chǎn)品,是在 struts 1和WebWork的技術(shù)基礎(chǔ)上進(jìn)行了合并的全新的Struts 2框架耸成。

其全新的Struts 2的體系結(jié)構(gòu)與Struts 1的體系結(jié)構(gòu)差別巨大届囚。

Struts 2以WebWork為核心询微,采用攔截器的機(jī)制來(lái)處理用戶的請(qǐng)求,
這樣的設(shè)計(jì)也使得業(yè)務(wù)邏輯控制器能夠與ServletAPI完全脫離開(kāi),所以Struts 2可以理解為WebWork的更新產(chǎn)品间螟。

雖然從Struts 1到Struts 2有著太大的變化淑仆,但是相對(duì)于WebWork花竞,Struts 2的變化很小岩瘦。

  • 三層結(jié)構(gòu)體系(來(lái)自于JavaEE規(guī)范):

    表現(xiàn)層(頁(yè)面數(shù)據(jù)顯示、頁(yè)面跳轉(zhuǎn)調(diào)度)jsp/servlet
    業(yè)務(wù)層(業(yè)務(wù)處理和功能邏輯唇敞、事務(wù)控制)-service
    持久層(數(shù)據(jù)存取和封裝蔗草、和2交道)dao

    換句話說(shuō):
    Struts2是一個(gè)表現(xiàn)層框架,用來(lái)簡(jiǎn)化表現(xiàn)層代碼開(kāi)發(fā)的疆柔。
    而Hibernate是一個(gè)持久層框架,用來(lái)替代DBUtils來(lái)簡(jiǎn)化持久層的代碼開(kāi)發(fā)咒精。

二、 入門(mén)案例_Hello World

1. 入門(mén)案例步驟

  1. 創(chuàng)建Web工程

  2. 導(dǎo)入Struts2的jar包

  3. 配置Struts2的前端控制器

  4. 模擬頁(yè)面請(qǐng)求,編寫(xiě)hello.jsp

  5. 編寫(xiě)表現(xiàn)層Action,響應(yīng)返回跳轉(zhuǎn)到result.jsp

  6. 根據(jù)請(qǐng)求與響應(yīng)跳轉(zhuǎn)旷档,配置Struts2的核心配置文件struts.xml

    1. 找到struts2-blank.war.zip模板文件中的struts.xml配置文件,拷貝到當(dāng)前項(xiàng)目的src目錄下

2. 實(shí)現(xiàn)

2.1 創(chuàng)建Web工廠
2.2 導(dǎo)入Struts2的jar包
1. 解壓下載好的Struts2壓縮包模叙,找到apps解壓Struts2提供的blank模板,更改其擴(kuò)展名為zip后解壓即可.

2. copy其中l(wèi)ib包下所有jar包到當(dāng)前工程,其中l(wèi)og4的jar包可選.

3. 這里我們不使用Struts2提供的log4j 2.x的版本,自己導(dǎo)入log4j 1.x的版本
![img02.png](http://upload-images.jianshu.io/upload_images/5303154-cd08aaecd8149b48.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
2.3 配置Struts2的前端控制器
  • Struts2的前端控制器就是一個(gè)過(guò)濾器彬犯,在這里加載Struts2的配置,將Servlet原先的一些重復(fù)的代碼在攔截器中執(zhí)行了向楼,Struts2的前端控制器需要在web.xml中進(jìn)行配置。

    1.找到剛剛解壓的struts2-blank.war.zip模板文件中的web.xml配置文件谐区,copy其中過(guò)濾器Filter配置的那一段代碼到項(xiàng)目中的web.xml

  
    前端控制器的類的路徑和名稱:
        org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter

    具體配置如下:

      <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>

2.4 模擬頁(yè)面請(qǐng)求,編寫(xiě)hello.jsp

a標(biāo)簽,點(diǎn)擊請(qǐng)求Struts2.

這里的 hello.action 我們可以認(rèn)為與 Servlet的 url-pattern 的映射路徑類似,我們?cè)趕truts.xml中
配置該 hello.action對(duì)應(yīng)的Action. 在Struts2的Action處理請(qǐng)求進(jìn)行響應(yīng).

    <a href="${pageContext.request.contextPath }/hello.action">點(diǎn)我</a>
2.5. 編寫(xiě)表現(xiàn)層Action,響應(yīng)返回跳轉(zhuǎn)到result.jsp
  • Action類是動(dòng)作類逻卖,是Struts2處理請(qǐng)求宋列,封裝數(shù)據(jù),響應(yīng)頁(yè)面的核心控制器评也。需要自己編寫(xiě)炼杖。

    編寫(xiě)Action處理請(qǐng)求:(實(shí)現(xiàn)Action接口,實(shí)現(xiàn)excute方法,Struts2訪問(wèn)Action默認(rèn)執(zhí)行excute方法) 

    import com.opensymphony.xwork2.Action;

    public class HelloAction implements Action {

        @Override
        public String execute() throws Exception {
            //------------模擬調(diào)用業(yè)務(wù)層邏輯-------------
            System.out.println("Hello Struts2....");
            
            //---------------頁(yè)面跳轉(zhuǎn)------------------
            return SUCCESS;
        }
    
    }
2.6. 根據(jù)請(qǐng)求與響應(yīng)跳轉(zhuǎn),配置Struts2的核心配置文件struts.xml
  • 根據(jù)request請(qǐng)求的路徑盗迟,表現(xiàn)層Action的響應(yīng)配置struts2.xmlStuts2的核心配置文件坤邪。

  • 這個(gè)核心配置文件struts.xml也從Stuts2提供的struts2-blank.war模板中找到,將多余的標(biāo)簽刪除留下最簡(jiǎn)單的DTD約束,package與action標(biāo)簽即可。


    1. 配置文件名稱是struts.xml(名稱必須是struts.xml)
    2. 在src下引入struts.xml配置文件(配置文件的路徑必須是在src的目錄下)

    
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
        "http://struts.apache.org/dtds/struts-2.3.dtd">
    
    <!-- 
        Struts2的核心配置文件 : 
        1. 建立請(qǐng)求與Struts2的聯(lián)系,請(qǐng)求經(jīng)過(guò)web.xml前端控制器,按照攔截器的從上而下的順序,執(zhí)行了原先Servlet中大量需要重復(fù)的代碼
        2. 根據(jù)struts.xml配置文件找到對(duì)應(yīng)的Action
        3. Action對(duì)請(qǐng)求做出響應(yīng),返回了一個(gè)String類型的值,我們將其稱為邏輯視圖,在struts.xml配置該邏輯視圖對(duì)應(yīng)的跳轉(zhuǎn)頁(yè)面
     -->
    <struts>
        <package name="default" namespace="/" extends="struts-default">
            <action name="hello" class="com.itdream.test.HelloAction">
                <result name="success">/result.jsp</result>     
            </action>
        </package>
    </struts>


三罚缕、 入門(mén)案例的細(xì)節(jié)解析

1. Struts2的運(yùn)行流程

img03.png
img04.png
前端控制器

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
它采用前端控制器模式艇纺,對(duì)用戶的請(qǐng)求進(jìn)行控制處理。在這里會(huì)默認(rèn)加載Struts2的配置文件

我們通過(guò)查看源碼可以知道,它會(huì)依次加載Struts2中的配置文件邮弹。

加載配置文件的順序:

1. init_DefaultProperties()黔衡。默認(rèn)的properties配置。
    org/apache/struts2/default.properties :默認(rèn)的配置加載項(xiàng)腌乡,struts2啟動(dòng)時(shí)加載的默認(rèn)參數(shù)
    
2. init_TraditionalXmlConfigurations()盟劫。傳統(tǒng)的xml配置。
    struts-default.xml,struts-plugin.xml,struts.xml

struts2的傳統(tǒng)xml配置:
    struts-default.xml:struts框架啟動(dòng)時(shí)加載運(yùn)行的框架默認(rèn)配置与纽。
    struts-plugin.xml: struts框架允許插件集成侣签。集成的插件配置塘装。
    struts.xml: 開(kāi)發(fā)者的配置。我們配置的請(qǐng)求與Action等配置就在這里

3. init_LegacyStrutsProperties():加載常量配置struts.properties

4. init_CustomConfigurationProviders():struts啟動(dòng)核心類創(chuàng)建的提供者影所。

5. init_FilterInitParameters():struts加載web.xml中的配置
img05.png

Interceptor攔截器【了解】
Struts2可復(fù)用的代碼功能都是基于(通過(guò))它來(lái)實(shí)現(xiàn)的氢哮。struts2有很多內(nèi)置攔截器,用來(lái)實(shí)現(xiàn)不同的功能型檀。

參考 struts-core.jar 提供 struts-default.xml 配置文件
    我們看看有哪些默認(rèn)的攔截器:

這些攔截器都會(huì)依次執(zhí)行(按照從上倒下的順序):

img06.png

Struts.xml中的配置

位于工程的src目錄下:


    <struts>
        <package name="default" namespace="/" extends="struts-default">
            <action name="hello" class="com.itdream.test.HelloAction">
                <result name="success">/result.jsp</result>     
            </action>
        </package>
    </struts>
DTD的查詢和配置
1. 到struts的核心包中可以找到struts-2.3.dtd文件
2. 到xml catelog中配置離線提示
package冗尤、action、result標(biāo)簽
package標(biāo)簽:用來(lái)管理配置包配置和Action胀溺, 實(shí)現(xiàn)包內(nèi)配置復(fù)用 (通過(guò)包繼承實(shí)現(xiàn) )

    name : 包名,在struts容器中具有唯一性(在開(kāi)發(fā)中可以用模塊名稱作為包名)
    extends : 繼承父package(中的功能)裂七,通常都繼承struts-default(默認(rèn)包內(nèi)定義大量結(jié)果集類型和攔截器)
    namespace : 名稱空間用來(lái)標(biāo)識(shí)一個(gè)路徑,來(lái)區(qū)分不同action的訪問(wèn)路徑仓坞。一般使用"/"
               和Action標(biāo)簽的name和method搭配來(lái)確定訪問(wèn)的url

    abstract:抽象背零。用來(lái)被其他package繼承的

-----------------------------------------------------------------------

action標(biāo)簽 : 用來(lái)建立請(qǐng)求與Strtus2的Action之間的聯(lián)系的。

    name : 用于配置請(qǐng)求无埃。
        相當(dāng)于Servlet中的映射路徑url-pattern徙瓶,通過(guò)namespace+name可以訪問(wèn)與它對(duì)應(yīng)的Action類

    class : action對(duì)應(yīng)的類,全包名。該類編寫(xiě)了action具體業(yè)務(wù)邏輯代碼嫉称。

    method: action類中的方法名稱侦镇,訪問(wèn)此action時(shí)調(diào)用的action類中的方法

-----------------------------------------------------------------------

result標(biāo)簽 : 結(jié)果集視圖,用于配置響應(yīng)织阅,標(biāo)簽內(nèi)的值是響應(yīng)的地址壳繁。

    name : 結(jié)果集(結(jié)果集視圖)的名字,action會(huì)根據(jù)該名字跳轉(zhuǎn)到對(duì)應(yīng)的地址荔棉。
    


小結(jié):namespace主要用來(lái)區(qū)分action闹炉,影響到action的訪問(wèn)路徑。
Constant標(biāo)簽【會(huì)配置】

default.properties定義了struts2框架的大量常量润樱,開(kāi)發(fā)者可以通過(guò)改變這些常量來(lái)滿足應(yīng)用的需求渣触。

要修改這些常量,可以通過(guò)自定義核心配置struts.xml來(lái)覆蓋默認(rèn)的值(后加載的配置文件常量壹若,可以對(duì)先加載配置文件進(jìn)行覆蓋)嗅钻,有如下三種方式(開(kāi)啟開(kāi)發(fā)者模式):

  • 配置src/struts.xml【推薦】

      <constant name = “struts.devMode” value=”true”/>
    
  • 配置src/struts.properties

      struts.devModel = false
    
  • 配置web.xml

      注意:要寫(xiě)在filter標(biāo)簽內(nèi)
    
      <filter>
      <filter-name>struts2</filter-name>
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      
      <!-- web.xml 配置常量覆蓋之前的,這是最后執(zhí)行的配置文件-->
      <init-param>
          <param-name>struts2.devMode</param-name>
          <param-value>true</param-value>
      </init-param>
    

    </filter>

常用常量:

struts.i18n.encoding=UTF-8 :
    相當(dāng)于 request.setCharacterEncoding(“utf-8”);  解決post 請(qǐng)求亂碼問(wèn)題。 
    因此舌稀,在Struts2開(kāi)發(fā)時(shí)啊犬,盡量使用post請(qǐng)求,無(wú)需關(guān)注post 亂碼問(wèn)題壁查。


**struts.devMode=true :**
    開(kāi)發(fā)模式下使用,這樣可以打印出更詳細(xì)觉至、友好的錯(cuò)誤信息
    當(dāng)設(shè)置開(kāi)發(fā)者模式devMode =true 會(huì)激活xml配置文件自動(dòng)重新加載功能。


-----------------------------------------------------------------

struts.configuration.xml.reload=true :
    修改struts.xml 配置后睡腿,無(wú)需重啟服務(wù)器语御;配置開(kāi)發(fā)者模式后自動(dòng)開(kāi)啟

struts.i18n.reload = true :
    國(guó)際化文件修改之后也不需要重啟服務(wù)器峻贮。會(huì)自動(dòng)加載生效。


struts.action.extension=action :
    Action請(qǐng)求映射路徑 默認(rèn)擴(kuò)展名 
    問(wèn)題: http://localhost:8080/struts2_day1/hello 也可以訪問(wèn) HelloAction  
          如果請(qǐng)求路徑 必須以.action結(jié)尾 
img07.png
struts.ui.theme=xhtml :
    設(shè)置頁(yè)面標(biāo)簽顯示樣式 

struts.enable.DynamicMethodInvocation=true :
    訪問(wèn)Action 支持 動(dòng)態(tài)方法調(diào)用

struts.multipart.maxSize=2097152 : 
    上傳文件的大小限制

==============================================================

小結(jié):
如果需要更改某個(gè)常量的值应闯,在default.properties中找到變量纤控,將名字復(fù)制到struts.xml中進(jìn)行覆蓋它的值。
include標(biāo)簽,配置文件的分離【了解】
【開(kāi)發(fā)場(chǎng)景】
在大部分應(yīng)用里碉纺,隨著應(yīng)用規(guī)模的增加船万,系統(tǒng)中Action的數(shù)量也會(huì)大量增加,導(dǎo)致struts.xml配置文件變得非常臃腫骨田。
為了避免struts.xml文件過(guò)于龐大耿导、臃腫,提高struts.xml文件的可讀性态贤,我們可以將一個(gè)struts.xml配置文件分解成多個(gè)配置文件舱呻,
然后在struts.xml文件中包含其他配置文件。下面的struts.xml通過(guò)<include>元素指定多個(gè)配置文件:


<!-- include標(biāo)簽引入其他配置文件 -->
<include file="struts2.xml"></include>

四悠汽、 Action類的編寫(xiě)與訪問(wèn)

Action類的編寫(xiě)

  • 自定義POJO(Plain Old Java Object簡(jiǎn)單的Java對(duì)象)箱吕,實(shí)際就是普通的JavaBean。

      編寫(xiě)excute方法必須滿足一下條件:
          public修飾符
          String返回值
          無(wú)參數(shù)
    
  • 實(shí)現(xiàn)Action接口

      Action 接口提供 execute 處理業(yè)務(wù)邏輯方法
      
      【內(nèi)置的視圖名稱】:
       Action 接口提供一組 常用的內(nèi)置的邏輯視圖名稱:
    
          SUCCESS  成功視圖
          NONE 沒(méi)有結(jié)果視圖柿冲,用戶自己生成響應(yīng)數(shù)據(jù)
          ERROR 錯(cuò)誤視圖 
          INPUT 輸入視圖 (數(shù)據(jù)輸入非法茬高,要求用戶重新輸入)
          LOGIN 登陸視圖 (如果用戶未登陸,使用登陸視圖)
    
  • 繼承ActionSupport類

      繼承ActionSupport相當(dāng)于間接實(shí)現(xiàn)Action接口姻采,該類提供了更多功能雅采,如數(shù)據(jù)校驗(yàn)、 國(guó)際化等慨亲,
      用的最多,使用的時(shí)候需要手動(dòng)覆蓋execute()宝鼓。
    

    /**
     * 自定義POJO 
     */
    public class ActionDemo1 {
    
        public String execute() {
            
            System.out.println("POJO刑棵。。愚铡。蛉签。。沥寥。");
            return "none";
        }
    }


    /**
     * 實(shí)現(xiàn)Action接口
     */
    public class ActionDemo2 implements Action {
    
        @Override
        public String execute() throws Exception {
            
            System.out.println("繼承了Action接口.........");
            return NONE;
        }
    }

    
    /**
     * 繼承ActionSupport類
     */
    public class ActionDemo3 extends ActionSupport {
    
        @Override
        public String execute() throws Exception {
            
            System.out.println("繼承了ActionSupport............");
            return NONE;
        }
    }

Action類的訪問(wèn):

在開(kāi)發(fā)中,我們?cè)谝粋€(gè)Action類中不止一個(gè)execute方法,往往需要實(shí)現(xiàn)多個(gè)方法.

struts.xml中的action標(biāo)簽中配置method屬性即可


    <action name="hello2_save" class="com.itdream.test.HelloAction2" method="save"></action>
    <action name="hello2_delete" class="com.itdream.test.HelloAction2" method="delete"></action>
    <action name="hello2_update" class="com.itdream.test.HelloAction2" method="update"></action>
    <action name="hello2_query" class="com.itdream.test.HelloAction2" method="query"></action>

但是這樣配置的話,每一個(gè)方法都要配置實(shí)在太麻煩了,因此使用通配符進(jìn)行配置

<!-- 使用通配符訪問(wèn)Action中對(duì)應(yīng)方法 -->
<!-- 
    hello_* : 這個(gè)*代表任意字符

    method屬性中的 : {1}    代表 與name 屬性中的第一個(gè) * 一樣 碍舍。

-->

<action name="hello2_*" class="com.itdream.test.HelloAction2" method="{1}"></action>

還有一種訪問(wèn)方式:動(dòng)態(tài)方法訪問(wèn):

在struts.xml中進(jìn)行常量配置,將動(dòng)態(tài)方法訪問(wèn)的配置改為true覆蓋默認(rèn)的false

<!-- 開(kāi)啟動(dòng)態(tài)方法調(diào)用 -->
<!-- <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> -->

開(kāi)啟后,在配置action時(shí),無(wú)需指定method屬性:
    <action name="hello2" class="com.itdream.test.HelloAction2"></action>

訪問(wèn)瀏覽器時(shí): 
    http://localhost:8080/Day34_Struts2_HelloWorld/hello2!save.action
    http://localhost:8080/Day34_Struts2_HelloWorld/hello2!delete.action
        ...................
就可以調(diào)用對(duì)應(yīng)感嘆號(hào)后面的方法邑雅。

五片橡、 整合Hibernate與Struts2完成CRM查詢所有客戶的操作

1. 思路

  • 創(chuàng)建Web工程
  • 導(dǎo)入Hibernate所需jar包,數(shù)據(jù)庫(kù)表,實(shí)體類,Utils工具類
  • 完成Hibernate的相應(yīng)配置,并測(cè)試
  • 導(dǎo)入Struts2所需jar包,完成相應(yīng)配置
  • 更改menu.jsp讓其請(qǐng)求訪問(wèn)Struts2的Action
  • Action接收請(qǐng)求,處理業(yè)務(wù)邏輯返回?cái)?shù)據(jù)轉(zhuǎn)發(fā)到頁(yè)面
  • 修改Strurts2的配置文件struts.xml完成請(qǐng)求Struts2Action的的對(duì)應(yīng)及響應(yīng)后的跳轉(zhuǎn)

2. 搭建環(huán)境

2.1. 創(chuàng)建Web工程
2.2. 導(dǎo)入Hibernate所需jar包
1. hibernate必須jar包 : hibernate安裝文件中required下的所有jar包

2. jdbc數(shù)據(jù)庫(kù)驅(qū)動(dòng) 

3. hibernate中優(yōu)化連接池的c3p0的jar包

2.3. 創(chuàng)建數(shù)據(jù)庫(kù)表R,實(shí)體類O
R : Relational 關(guān)系型數(shù)據(jù)庫(kù)

CREATE DATABASE struts2_crm;

USE struts2_crm;

CREATE TABLE `cst_customer` (
  `cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客戶編號(hào)(主鍵)',
  `cust_name` VARCHAR(32) NOT NULL COMMENT '客戶名稱(公司名稱)',
  `cust_user_id` BIGINT(32) DEFAULT NULL COMMENT '負(fù)責(zé)人id',
  `cust_create_id` BIGINT(32) DEFAULT NULL COMMENT '創(chuàng)建人id',
  `cust_source` VARCHAR(32) DEFAULT NULL COMMENT '客戶信息來(lái)源',
  `cust_industry` VARCHAR(32) DEFAULT NULL COMMENT '客戶所屬行業(yè)',
  `cust_level` VARCHAR(32) DEFAULT NULL COMMENT '客戶級(jí)別',
  `cust_linkman` VARCHAR(64) DEFAULT NULL COMMENT '聯(lián)系人',
  `cust_phone` VARCHAR(64) DEFAULT NULL COMMENT '固定電話',
  `cust_mobile` VARCHAR(16) DEFAULT NULL COMMENT '移動(dòng)電話',
  PRIMARY KEY (`cust_id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

--------------------------------------------------------------------

O : Object 與R對(duì)應(yīng)的持久化類(根據(jù)R完成)
img08.png

2.4. 完成ORM框架中的M,建立持久化類與數(shù)據(jù)庫(kù)表的映射關(guān)系
與實(shí)體類在同級(jí)目錄下創(chuàng)建 類名+.hbm.xml 淮野,這里為 Customer.hbm.xml :

<?xml version="1.0" encoding="UTF-8"?>

<!-- 導(dǎo)入DTD約束 -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <!-- 建立持久化類Customer與數(shù)據(jù)庫(kù)表customer的映射 -->
    <class name="com.itdream.crm.domain.Customer" table="cst_customer">
        <!-- 配置持久化類標(biāo)識(shí)符OID與數(shù)據(jù)庫(kù)表的主鍵的映射關(guān)系捧书,name和column相同省略column -->
        <id name="cust_id">
            <!-- 主鍵生成策略,native根據(jù)數(shù)據(jù)庫(kù)底層自動(dòng)三選1 : increment(MySQL),sequence(Oracle),hilo(Hibernate自定義的一種) -->
            <generator class="native"></generator>
        </id>
        
        <!-- 配置普通屬性與字段的映射 -->
        <property name="cust_name"></property>
        <property name="cust_user_id"></property>
        <property name="cust_create_id"></property>
        <property name="cust_source"></property>
        <property name="cust_industry"></property>
        <property name="cust_level"></property>
        <property name="cust_linkman"></property>
        <property name="cust_phone"></property>
        <property name="cust_mobile"></property>
    </class>
</hibernate-mapping>
2.5. 完成Hibernate的核心配置文件hibernate.cfg.xml
在src目錄下創(chuàng)建hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 導(dǎo)入Hibernate核心配置的DTD約束 -->
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!--1. 基本配置 -->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_day02</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>

        <!--2. 與本地線程綁定 -->
        <property name="hibernate.current_session_context_class">thread</property>

        <!--3. Hibernate的屬性 -->
        <!--Hibernate的方言配置,實(shí)現(xiàn)了跨數(shù)據(jù)庫(kù)  -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 顯示sql語(yǔ)句 -->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <!-- Hibernate表格的創(chuàng)建方式 -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 
            設(shè)置隔離級(jí)別:
                hibernate.connection.isolation = 4
                1-Read uncommitted isolation
                2-Read committed isolation
                4-Repeatable read isolation
                8-Serializable isolation 
        -->
        <property name="hibernate.connection.isolation">4</property>

        <!-- C3P0的供應(yīng)商 -->
        <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
        <!-- 最小連接 -->
        <property name="hibernate.c3p0.min_size">5</property>
        <!-- 最大連接數(shù) -->
        <property name="hibernate.c3p0.max_size">20</property>
        <!-- 連接超時(shí)時(shí)長(zhǎng) -->
        <property name="hibernate.c3p0.timeout">120</property>
        <!-- 每120秒檢查空閑連接 -->
        <property name="hibernate.c3p0.idle_test_period">120</property>
        <!-- 最大statments數(shù)量 -->
        <property name="hibernate.c3p0.max_statements">120</property>
        <!-- 連接用完后吹泡,每次增加的連接數(shù) -->
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <!-- 每次都驗(yàn)證連接是否可用 -->
        <property name="hibernate.c3p0.validate">false</property>

        <!--4. 加載映射文件 -->
        <mapping resource="com/itdream/domain/crm/domain/Customer.hbm.xml" />

    </session-factory>

</hibernate-configuration>

2.6. 建立包結(jié)構(gòu),編寫(xiě)HibernateUtils工具類,導(dǎo)入log4j.properties日志配置文件
img09.png
/**
 * Hibernate工具類
 * 初始化SessionFactory工廠,提供獲取Session對(duì)象的方法
 */
public class HibernateUtils {

    //單例模式的SessionFactory,確保只有一個(gè)工廠對(duì)象
    private static SessionFactory sf = null;
    
    static {
        //創(chuàng)建Hibernate的配置對(duì)象Configuration,并加載核心配置文件hibernate.cfg.xml
        Configuration configuration = new Configuration().configure();
        
        //創(chuàng)建SessionFactory工廠對(duì)象
        sf = configuration.buildSessionFactory();
        
        //程序結(jié)束銷(xiāo)毀SessionFactory對(duì)象釋放資源
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println("程序結(jié)束,銷(xiāo)毀SessionFactory");
                sf.close();
            }
        }));
    }
    
    
    /**
     * 獲取新的Session的方法
     */
    public static Session openSession() {
        return sf.openSession();
    } 
    
    /**
     * 獲取與當(dāng)前線程綁定的Session對(duì)象
     */
    public static Session getCurrentSession() {
        return sf.getCurrentSession();
    }
    
}

===========================================================================

log4j.properties日志配置文件 :

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:\\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###
log4j.rootLogger=info, stdout,file 

2.7. copy前端頁(yè)面到WebContent包下,測(cè)試Hibernate是否成功導(dǎo)入成功
copycopy前端頁(yè)面到```WebContent```包下,導(dǎo)入jstl標(biāo)簽庫(kù)的相應(yīng)jar包

@Test
//測(cè)試Hibernate是否連通
//如果數(shù)據(jù)庫(kù)中建表成功代表成功
public void test() {
    Session session = HibernateUtils.getCurrentSession();
}

2.8. Struts2環(huán)境搭建经瓷,添加Struts2的jar包
這里我們解壓Struts2的空白模板,獲得其需要的最少的jar包,13個(gè)爆哑。
由于log4j的日志jar包,之前我們已經(jīng)在hibernate中已經(jīng)使用了1.x的版本,這里Struts2的log4j 2.x.jar的版本我們就不需要了。

除此之外,Hibernate與Struts2有兩個(gè)jar包沖突,選擇最新的版本舆吮,舊版本刪除
img10.png

2.9. 在web.xml中完成Struts2的前端控制器配置
同樣在空白模板struts2-blank中直接找到web.xml的文件復(fù)制其中fiter標(biāo)簽即可揭朝。

<!--Struts2的前端控制器配置  -->
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

到這里環(huán)境搭建就基本完成了,接下來(lái)從頁(yè)面開(kāi)始完成代碼操作

3. 代碼實(shí)現(xiàn)

3.1. 修改menu.jsp頁(yè)面
<TD class=menuSmall>
    <A class=style2 href="${pageContext.request.contextPath}/customer_findListCustomer.action" target="main">- 客戶列表</A>
</TD> 

這里讓a標(biāo)簽點(diǎn)擊之后,請(qǐng)求Struts2的Action類,Action類做出響應(yīng)
3.2 編寫(xiě)Action類對(duì)請(qǐng)求做出響應(yīng)
編寫(xiě)CustomerAction類繼承ActionSupport類

public class CustomerAction extends ActionSupport {
    private static final long serialVersionUID = 1L;

    /**
     * 查找所有Customer
     */
    public String findListCustomer() {
        
        //收到請(qǐng)求,調(diào)用Service業(yè)務(wù)層
        CustomerService service = new CustomerServiceImpl();
        //獲取到了所有客戶Customer數(shù)據(jù)
        List<Customer> listCustomer = service.findListCustomer();
        
        //獲取到request對(duì)象將listCusomter數(shù)據(jù)存入request域
        ServletActionContext.getRequest().setAttribute("list", listCustomer);
        
        //邏輯視圖轉(zhuǎn)發(fā),在struts.xml配置文件中配置對(duì)應(yīng)跳轉(zhuǎn)頁(yè)面
        return SUCCESS;
    }
}   

--------------------------------------------------------------

service層業(yè)務(wù)邏輯: 

@Override
//獲取所有客戶
public List<Customer> findListCustomer() {
    //獲取Session
    Session session = HibernateUtils.getCurrentSession();
    //開(kāi)啟事務(wù)
    Transaction transaction = session.beginTransaction();
    
    List<Customer> list = null;
    try {
        //業(yè)務(wù)邏輯
        CustomerDAO dao = new CustomerDAOImpl();
        list = dao.findListCustomer();
        
    } catch (Exception e) {
        e.printStackTrace();
        //如果發(fā)生異常,Hibernate框架會(huì)幫我們處理回滾事務(wù),無(wú)需手動(dòng)回滾
        //transaction.rollback();
        
    } finally {
        //最后無(wú)論如何都提交事務(wù)從而結(jié)束事務(wù),如果發(fā)生異常就是回滾到初始狀態(tài)再提交
        transaction.commit();
    }
    //返回值
    return list;
}

-------------------------------------------------------------------


dao層使用Hibernate查詢 :

@Override
//獲取所有客戶
public List<Customer> findListCustomer() throws SQLException {
    //獲取與當(dāng)前線程綁定的Session對(duì)象
    Session session = HibernateUtils.getCurrentSession();
    
    //獲取所有客戶,這里我使用Criteria進(jìn)行單表查詢
    Criteria criteria = session.createCriteria(Customer.class);
    return criteria.list();
} 

3.3 struts.xml配置請(qǐng)求對(duì)應(yīng)的Action及響應(yīng)后的跳轉(zhuǎn)頁(yè)面等
同樣從struts2的解壓包中找到sturts2-blank的模板,賦值struts.xml到項(xiàng)目

刪除多余的標(biāo)簽。
留下<constant>常量標(biāo)簽中的 開(kāi)啟開(kāi)發(fā)者模式,這樣修改配置可以無(wú)需手動(dòng)重啟服務(wù)器,同時(shí)錯(cuò)誤提示更友好

留下<package><action>標(biāo)簽,配置請(qǐng)求對(duì)應(yīng)Action


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
    <!-- 開(kāi)啟開(kāi)發(fā)者模式 -->
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">
        <!-- 配置請(qǐng)求對(duì)應(yīng)的Action -->
        <action name="customer_*" class="com.itdream.web.action.CustomerAction" method="{1}">
            <!-- 配置邏輯視圖跳轉(zhuǎn)頁(yè)面 -->
            <result name="success" >/jsp/customer/list.jsp</result>
        </action>
    </package>
</struts>
3.4 解析result.jsp頁(yè)面【省略】
3.5 訪問(wèn)效果圖
img11.png
3.6 案例總結(jié)
1. 配置文件時(shí)小心出錯(cuò),我在配置struts.xml配置文件的action中的result標(biāo)簽時(shí)色冀,出了個(gè)錯(cuò)誤,使用了模板中的type,其實(shí)應(yīng)該用name邏輯視圖對(duì)應(yīng)的跳轉(zhuǎn)頁(yè)面

<!-- 配置邏輯視圖跳轉(zhuǎn)頁(yè)面 -->
        <result name="success" >/jsp/customer/list.jsp</result>

2. 使用action配置對(duì)應(yīng)action方法時(shí)潭袱,如果沒(méi)有method標(biāo)簽,那么Struts2默認(rèn)執(zhí)行execute方法。

3. 超鏈接上的a標(biāo)簽訪問(wèn)customer_findListCustomer.action呐伞,經(jīng)過(guò)前端控制器到struts.xml中尋找customer_*的action

4. 找到這個(gè)action后敌卓,通過(guò)class找到對(duì)應(yīng)的Action類,通過(guò)Method找到對(duì)應(yīng)的方法.執(zhí)行完Action后返回result邏輯視圖

5. 返回的result再回到struts.xml中尋找該action標(biāo)簽下的result標(biāo)簽,找到對(duì)應(yīng)邏輯視圖需要跳轉(zhuǎn)的頁(yè)面進(jìn)行跳轉(zhuǎn)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末伶氢,一起剝皮案震驚了整個(gè)濱河市趟径,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌癣防,老刑警劉巖蜗巧,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蕾盯,居然都是意外死亡幕屹,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)级遭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)望拖,“玉大人,你說(shuō)我怎么就攤上這事挫鸽∷得簦” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵丢郊,是天一觀的道長(zhǎng)盔沫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)枫匾,這世上最難降的妖魔是什么架诞? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮干茉,結(jié)果婚禮上谴忧,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好俏蛮,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布撑蚌。 她就那樣靜靜地躺著,像睡著了一般搏屑。 火紅的嫁衣襯著肌膚如雪争涌。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天辣恋,我揣著相機(jī)與錄音亮垫,去河邊找鬼。 笑死伟骨,一個(gè)胖子當(dāng)著我的面吹牛饮潦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播携狭,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼继蜡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了逛腿?” 一聲冷哼從身側(cè)響起稀并,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎单默,沒(méi)想到半個(gè)月后碘举,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡搁廓,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年引颈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片境蜕。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蝙场,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粱年,到底是詐尸還是另有隱情李丰,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布逼泣,位于F島的核電站,受9級(jí)特大地震影響舟舒,放射性物質(zhì)發(fā)生泄漏拉庶。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一秃励、第九天 我趴在偏房一處隱蔽的房頂上張望氏仗。 院中可真熱鬧,春花似錦、人聲如沸皆尔。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)慷蠕。三九已至珊拼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間流炕,已是汗流浹背澎现。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留每辟,地道東北人剑辫。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像渠欺,于是被迫代替她去往敵國(guó)和親妹蔽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容