Struts2框架_快速入门

一、 Struts2概述

在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。

其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。

Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,
这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。

虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

  • 三层结构体系(来自于JavaEE规范):

    表现层(页面数据显示、页面跳转调度)jsp/servlet
    业务层(业务处理和功能逻辑、事务控制)-service
    持久层(数据存取和封装、和2交道)dao

    换句话说:
    Struts2是一个表现层框架,用来简化表现层代码开发的。
    而Hibernate是一个持久层框架,用来替代DBUtils来简化持久层的代码开发。

二、 入门案例_Hello World

1. 入门案例步骤

  1. 创建Web工程

  2. 导入Struts2的jar包

  3. 配置Struts2的前端控制器

  4. 模拟页面请求,编写hello.jsp

  5. 编写表现层Action,响应返回跳转到result.jsp

  6. 根据请求与响应跳转,配置Struts2的核心配置文件struts.xml

    1. 找到struts2-blank.war.zip模板文件中的struts.xml配置文件,拷贝到当前项目的src目录下

2. 实现

2.1 创建Web工厂
2.2 导入Struts2的jar包
1. 解压下载好的Struts2压缩包,找到apps解压Struts2提供的blank模板,更改其扩展名为zip后解压即可.

2. copy其中lib包下所有jar包到当前工程,其中log4的jar包可选.

3. 这里我们不使用Struts2提供的log4j 2.x的版本,自己导入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的前端控制器就是一个过滤器,在这里加载Struts2的配置,将Servlet原先的一些重复的代码在拦截器中执行了,Struts2的前端控制器需要在web.xml中进行配置。

    1.找到刚刚解压的struts2-blank.war.zip模板文件中的web.xml配置文件,copy其中过滤器Filter配置的那一段代码到项目中的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 模拟页面请求,编写hello.jsp

a标签,点击请求Struts2.

这里的 hello.action 我们可以认为与 Servlet的 url-pattern 的映射路径类似,我们在struts.xml中
配置该 hello.action对应的Action. 在Struts2的Action处理请求进行响应.

    <a href="${pageContext.request.contextPath }/hello.action">点我</a>
2.5. 编写表现层Action,响应返回跳转到result.jsp
  • Action类是动作类,是Struts2处理请求,封装数据,响应页面的核心控制器。需要自己编写。

    编写Action处理请求:(实现Action接口,实现excute方法,Struts2访问Action默认执行excute方法) 

    import com.opensymphony.xwork2.Action;

    public class HelloAction implements Action {

        @Override
        public String execute() throws Exception {
            //------------模拟调用业务层逻辑-------------
            System.out.println("Hello Struts2....");
            
            //---------------页面跳转------------------
            return SUCCESS;
        }
    
    }
2.6. 根据请求与响应跳转,配置Struts2的核心配置文件struts.xml
  • 根据request请求的路径,表现层Action的响应配置struts2.xmlStuts2的核心配置文件。

  • 这个核心配置文件struts.xml也从Stuts2提供的struts2-blank.war模板中找到,将多余的标签删除留下最简单的DTD约束,package与action标签即可。


    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. 建立请求与Struts2的联系,请求经过web.xml前端控制器,按照拦截器的从上而下的顺序,执行了原先Servlet中大量需要重复的代码
        2. 根据struts.xml配置文件找到对应的Action
        3. Action对请求做出响应,返回了一个String类型的值,我们将其称为逻辑视图,在struts.xml配置该逻辑视图对应的跳转页面
     -->
    <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>


三、 入门案例的细节解析

1. Struts2的运行流程

img03.png
img04.png
前端控制器

org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
它采用前端控制器模式,对用户的请求进行控制处理。在这里会默认加载Struts2的配置文件

我们通过查看源码可以知道,它会依次加载Struts2中的配置文件。

加载配置文件的顺序:

1. init_DefaultProperties()。默认的properties配置。
    org/apache/struts2/default.properties :默认的配置加载项,struts2启动时加载的默认参数
    
2. init_TraditionalXmlConfigurations()。传统的xml配置。
    struts-default.xml,struts-plugin.xml,struts.xml

struts2的传统xml配置:
    struts-default.xml:struts框架启动时加载运行的框架默认配置。
    struts-plugin.xml: struts框架允许插件集成。集成的插件配置。
    struts.xml: 开发者的配置。我们配置的请求与Action等配置就在这里

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

4. init_CustomConfigurationProviders():struts启动核心类创建的提供者。

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

Interceptor拦截器【了解】
Struts2可复用的代码功能都是基于(通过)它来实现的。struts2有很多内置拦截器,用来实现不同的功能。

参考 struts-core.jar 提供 struts-default.xml 配置文件
    我们看看有哪些默认的拦截器:

这些拦截器都会依次执行(按照从上倒下的顺序):

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标签
package标签:用来管理配置包配置和Action, 实现包内配置复用 (通过包继承实现 )

    name : 包名,在struts容器中具有唯一性(在开发中可以用模块名称作为包名)
    extends : 继承父package(中的功能),通常都继承struts-default(默认包内定义大量结果集类型和拦截器)
    namespace : 名称空间用来标识一个路径,来区分不同action的访问路径。一般使用"/"
               和Action标签的name和method搭配来确定访问的url

    abstract:抽象。用来被其他package继承的

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

action标签 : 用来建立请求与Strtus2的Action之间的联系的。

    name : 用于配置请求。
        相当于Servlet中的映射路径url-pattern,通过namespace+name可以访问与它对应的Action类

    class : action对应的类,全包名。该类编写了action具体业务逻辑代码。

    method: action类中的方法名称,访问此action时调用的action类中的方法

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

result标签 : 结果集视图,用于配置响应,标签内的值是响应的地址。

    name : 结果集(结果集视图)的名字,action会根据该名字跳转到对应的地址。
    


小结:namespace主要用来区分action,影响到action的访问路径。
Constant标签【会配置】

default.properties定义了struts2框架的大量常量,开发者可以通过改变这些常量来满足应用的需求。

要修改这些常量,可以通过自定义核心配置struts.xml来覆盖默认的值(后加载的配置文件常量,可以对先加载配置文件进行覆盖),有如下三种方式(开启开发者模式):

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

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

      struts.devModel = false
    
  • 配置web.xml

      注意:要写在filter标签内
    
      <filter>
      <filter-name>struts2</filter-name>
      <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
      
      <!-- web.xml 配置常量覆盖之前的,这是最后执行的配置文件-->
      <init-param>
          <param-name>struts2.devMode</param-name>
          <param-value>true</param-value>
      </init-param>
    

    </filter>

常用常量:

struts.i18n.encoding=UTF-8 :
    相当于 request.setCharacterEncoding(“utf-8”);  解决post 请求乱码问题。 
    因此,在Struts2开发时,尽量使用post请求,无需关注post 乱码问题。


**struts.devMode=true :**
    开发模式下使用,这样可以打印出更详细、友好的错误信息
    当设置开发者模式devMode =true 会激活xml配置文件自动重新加载功能。


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

struts.configuration.xml.reload=true :
    修改struts.xml 配置后,无需重启服务器;配置开发者模式后自动开启

struts.i18n.reload = true :
    国际化文件修改之后也不需要重启服务器。会自动加载生效。


struts.action.extension=action :
    Action请求映射路径 默认扩展名 
    问题: http://localhost:8080/struts2_day1/hello 也可以访问 HelloAction  
          如果请求路径 必须以.action结尾 
img07.png
struts.ui.theme=xhtml :
    设置页面标签显示样式 

struts.enable.DynamicMethodInvocation=true :
    访问Action 支持 动态方法调用

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

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

小结:
如果需要更改某个常量的值,在default.properties中找到变量,将名字复制到struts.xml中进行覆盖它的值。
include标签,配置文件的分离【了解】
【开发场景】
在大部分应用里,随着应用规模的增加,系统中Action的数量也会大量增加,导致struts.xml配置文件变得非常臃肿。
为了避免struts.xml文件过于庞大、臃肿,提高struts.xml文件的可读性,我们可以将一个struts.xml配置文件分解成多个配置文件,
然后在struts.xml文件中包含其他配置文件。下面的struts.xml通过<include>元素指定多个配置文件:


<!-- include标签引入其他配置文件 -->
<include file="struts2.xml"></include>

四、 Action类的编写与访问

Action类的编写

  • 自定义POJO(Plain Old Java Object简单的Java对象),实际就是普通的JavaBean。

      编写excute方法必须满足一下条件:
          public修饰符
          String返回值
          无参数
    
  • 实现Action接口

      Action 接口提供 execute 处理业务逻辑方法
      
      【内置的视图名称】:
       Action 接口提供一组 常用的内置的逻辑视图名称:
    
          SUCCESS  成功视图
          NONE 没有结果视图,用户自己生成响应数据
          ERROR 错误视图 
          INPUT 输入视图 (数据输入非法,要求用户重新输入)
          LOGIN 登陆视图 (如果用户未登陆,使用登陆视图)
    
  • 继承ActionSupport类

      继承ActionSupport相当于间接实现Action接口,该类提供了更多功能,如数据校验、 国际化等,
      用的最多,使用的时候需要手动覆盖execute()。
    

    /**
     * 自定义POJO 
     */
    public class ActionDemo1 {
    
        public String execute() {
            
            System.out.println("POJO。。。。。。");
            return "none";
        }
    }


    /**
     * 实现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类的访问:

在开发中,我们在一个Action类中不止一个execute方法,往往需要实现多个方法.

struts.xml中的action标签中配置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>

但是这样配置的话,每一个方法都要配置实在太麻烦了,因此使用通配符进行配置

<!-- 使用通配符访问Action中对应方法 -->
<!-- 
    hello_* : 这个*代表任意字符

    method属性中的 : {1}    代表 与name 属性中的第一个 * 一样 。

-->

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

还有一种访问方式:动态方法访问:

在struts.xml中进行常量配置,将动态方法访问的配置改为true覆盖默认的false

<!-- 开启动态方法调用 -->
<!-- <constant name="struts.enable.DynamicMethodInvocation" value="true"></constant> -->

开启后,在配置action时,无需指定method属性:
    <action name="hello2" class="com.itdream.test.HelloAction2"></action>

访问浏览器时: 
    http://localhost:8080/Day34_Struts2_HelloWorld/hello2!save.action
    http://localhost:8080/Day34_Struts2_HelloWorld/hello2!delete.action
        ...................
就可以调用对应感叹号后面的方法。

五、 整合Hibernate与Struts2完成CRM查询所有客户的操作

1. 思路

  • 创建Web工程
  • 导入Hibernate所需jar包,数据库表,实体类,Utils工具类
  • 完成Hibernate的相应配置,并测试
  • 导入Struts2所需jar包,完成相应配置
  • 更改menu.jsp让其请求访问Struts2的Action
  • Action接收请求,处理业务逻辑返回数据转发到页面
  • 修改Strurts2的配置文件struts.xml完成请求Struts2Action的的对应及响应后的跳转

2. 搭建环境

2.1. 创建Web工程
2.2. 导入Hibernate所需jar包
1. hibernate必须jar包 : hibernate安装文件中required下的所有jar包

2. jdbc数据库驱动 

3. hibernate中优化连接池的c3p0的jar包

2.3. 创建数据库表R,实体类O
R : Relational 关系型数据库

CREATE DATABASE struts2_crm;

USE struts2_crm;

CREATE TABLE `cst_customer` (
  `cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
  `cust_name` VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
  `cust_user_id` BIGINT(32) DEFAULT NULL COMMENT '负责人id',
  `cust_create_id` BIGINT(32) DEFAULT NULL COMMENT '创建人id',
  `cust_source` VARCHAR(32) DEFAULT NULL COMMENT '客户信息来源',
  `cust_industry` VARCHAR(32) DEFAULT NULL COMMENT '客户所属行业',
  `cust_level` VARCHAR(32) DEFAULT NULL COMMENT '客户级别',
  `cust_linkman` VARCHAR(64) DEFAULT NULL COMMENT '联系人',
  `cust_phone` VARCHAR(64) DEFAULT NULL COMMENT '固定电话',
  `cust_mobile` VARCHAR(16) DEFAULT NULL COMMENT '移动电话',
  PRIMARY KEY (`cust_id`)
) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

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

O : Object 与R对应的持久化类(根据R完成)
img08.png

2.4. 完成ORM框架中的M,建立持久化类与数据库表的映射关系
与实体类在同级目录下创建 类名+.hbm.xml ,这里为 Customer.hbm.xml :

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

<!-- 导入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与数据库表customer的映射 -->
    <class name="com.itdream.crm.domain.Customer" table="cst_customer">
        <!-- 配置持久化类标识符OID与数据库表的主键的映射关系,name和column相同省略column -->
        <id name="cust_id">
            <!-- 主键生成策略,native根据数据库底层自动三选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目录下创建hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!-- 导入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的方言配置,实现了跨数据库  -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- 显示sql语句 -->
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>

        <!-- Hibernate表格的创建方式 -->
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 
            设置隔离级别:
                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的供应商 -->
        <property name="hibernate.connection.provider_class">org.hibernate.c3p0.internal.C3P0ConnectionProvider</property>
        <!-- 最小连接 -->
        <property name="hibernate.c3p0.min_size">5</property>
        <!-- 最大连接数 -->
        <property name="hibernate.c3p0.max_size">20</property>
        <!-- 连接超时时长 -->
        <property name="hibernate.c3p0.timeout">120</property>
        <!-- 每120秒检查空闲连接 -->
        <property name="hibernate.c3p0.idle_test_period">120</property>
        <!-- 最大statments数量 -->
        <property name="hibernate.c3p0.max_statements">120</property>
        <!-- 连接用完后,每次增加的连接数 -->
        <property name="hibernate.c3p0.acquire_increment">2</property>
        <!-- 每次都验证连接是否可用 -->
        <property name="hibernate.c3p0.validate">false</property>

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

    </session-factory>

</hibernate-configuration>

2.6. 建立包结构,编写HibernateUtils工具类,导入log4j.properties日志配置文件
img09.png
/**
 * Hibernate工具类
 * 初始化SessionFactory工厂,提供获取Session对象的方法
 */
public class HibernateUtils {

    //单例模式的SessionFactory,确保只有一个工厂对象
    private static SessionFactory sf = null;
    
    static {
        //创建Hibernate的配置对象Configuration,并加载核心配置文件hibernate.cfg.xml
        Configuration configuration = new Configuration().configure();
        
        //创建SessionFactory工厂对象
        sf = configuration.buildSessionFactory();
        
        //程序结束销毁SessionFactory对象释放资源
        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println("程序结束,销毁SessionFactory");
                sf.close();
            }
        }));
    }
    
    
    /**
     * 获取新的Session的方法
     */
    public static Session openSession() {
        return sf.openSession();
    } 
    
    /**
     * 获取与当前线程绑定的Session对象
     */
    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前端页面到WebContent包下,测试Hibernate是否成功导入成功
copycopy前端页面到```WebContent```包下,导入jstl标签库的相应jar包

@Test
//测试Hibernate是否连通
//如果数据库中建表成功代表成功
public void test() {
    Session session = HibernateUtils.getCurrentSession();
}

2.8. Struts2环境搭建,添加Struts2的jar包
这里我们解压Struts2的空白模板,获得其需要的最少的jar包,13个。
由于log4j的日志jar包,之前我们已经在hibernate中已经使用了1.x的版本,这里Struts2的log4j 2.x.jar的版本我们就不需要了。

除此之外,Hibernate与Struts2有两个jar包冲突,选择最新的版本,旧版本删除
img10.png

2.9. 在web.xml中完成Struts2的前端控制器配置
同样在空白模板struts2-blank中直接找到web.xml的文件复制其中fiter标签即可。

<!--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>

到这里环境搭建就基本完成了,接下来从页面开始完成代码操作

3. 代码实现

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

这里让a标签点击之后,请求Struts2的Action类,Action类做出响应
3.2 编写Action类对请求做出响应
编写CustomerAction类继承ActionSupport类

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

    /**
     * 查找所有Customer
     */
    public String findListCustomer() {
        
        //收到请求,调用Service业务层
        CustomerService service = new CustomerServiceImpl();
        //获取到了所有客户Customer数据
        List<Customer> listCustomer = service.findListCustomer();
        
        //获取到request对象将listCusomter数据存入request域
        ServletActionContext.getRequest().setAttribute("list", listCustomer);
        
        //逻辑视图转发,在struts.xml配置文件中配置对应跳转页面
        return SUCCESS;
    }
}   

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

service层业务逻辑: 

@Override
//获取所有客户
public List<Customer> findListCustomer() {
    //获取Session
    Session session = HibernateUtils.getCurrentSession();
    //开启事务
    Transaction transaction = session.beginTransaction();
    
    List<Customer> list = null;
    try {
        //业务逻辑
        CustomerDAO dao = new CustomerDAOImpl();
        list = dao.findListCustomer();
        
    } catch (Exception e) {
        e.printStackTrace();
        //如果发生异常,Hibernate框架会帮我们处理回滚事务,无需手动回滚
        //transaction.rollback();
        
    } finally {
        //最后无论如何都提交事务从而结束事务,如果发生异常就是回滚到初始状态再提交
        transaction.commit();
    }
    //返回值
    return list;
}

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


dao层使用Hibernate查询 :

@Override
//获取所有客户
public List<Customer> findListCustomer() throws SQLException {
    //获取与当前线程绑定的Session对象
    Session session = HibernateUtils.getCurrentSession();
    
    //获取所有客户,这里我使用Criteria进行单表查询
    Criteria criteria = session.createCriteria(Customer.class);
    return criteria.list();
} 

3.3 struts.xml配置请求对应的Action及响应后的跳转页面等
同样从struts2的解压包中找到sturts2-blank的模板,赋值struts.xml到项目

删除多余的标签。
留下<constant>常量标签中的 开启开发者模式,这样修改配置可以无需手动重启服务器,同时错误提示更友好

留下<package><action>标签,配置请求对应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>
    <!-- 开启开发者模式 -->
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">
        <!-- 配置请求对应的Action -->
        <action name="customer_*" class="com.itdream.web.action.CustomerAction" method="{1}">
            <!-- 配置逻辑视图跳转页面 -->
            <result name="success" >/jsp/customer/list.jsp</result>
        </action>
    </package>
</struts>
3.4 解析result.jsp页面【省略】
3.5 访问效果图
img11.png
3.6 案例总结
1. 配置文件时小心出错,我在配置struts.xml配置文件的action中的result标签时,出了个错误,使用了模板中的type,其实应该用name逻辑视图对应的跳转页面

<!-- 配置逻辑视图跳转页面 -->
        <result name="success" >/jsp/customer/list.jsp</result>

2. 使用action配置对应action方法时,如果没有method标签,那么Struts2默认执行execute方法。

3. 超链接上的a标签访问customer_findListCustomer.action,经过前端控制器到struts.xml中寻找customer_*的action

4. 找到这个action后,通过class找到对应的Action类,通过Method找到对应的方法.执行完Action后返回result逻辑视图

5. 返回的result再回到struts.xml中寻找该action标签下的result标签,找到对应逻辑视图需要跳转的页面进行跳转
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容