- Action的配置
Struts2框架的核心配置文件是struts.xml文件,该文件主要用来配置Action和请求的对应关系。
的配置
Struts2框架的核心组件是Action 和拦截器,它使用包来管理Action 和拦截器。每个包就是多个Action、多个拦截器、多个拦截器引用的集合。在struts.xml文件中,package 元素用于定义包配置,每个package元素定义了一个包配置。package 元素的常用属性,如表所示。
属性说明
name:必填属性,它指定该包的名字,此名字是该包被name其他包引用的key。
namespace:可选属性,该属性定义该包的命名空间。
extends :可选属性,它指定该包继承自其他包。继承其他extends 包,可以继承其他包中的Action定义、拦截器定义等
abstract:可选属性,它指定该包是否是一个抽象包,抽象abstract包中不能包含Action定义。
其中package元素是常用属性,在配置包时,必须指定name属性,就是包的标识。除此之外,还可以指定-一个可选的extends 属性,extends 属性值必须是另一个包的name属性值,但该属性值通常都设置为struts-default, 这样该包中的Action就具有了Struts2 框架默认的拦截器等功能了。除此之外,Struts2 还提供了一种所谓的抽象包,抽象包不能包含Action定义。为了显式指定一个包是抽象包,可以为该package元素增加abstract= " true"属性。在package中还有namespace的配置,namespace 属性与action 标签的name属性共同决定了访问路径。
namesp有如下三种配置
1、默认命名空间:默认命名空间就是namespace="";
2、根名称空间:比如namespace="/";
3、带名称的命名空间:比如namespace="/demo";
的配置
Action映射是框架中的基本“工作単元”。Action映射就是將一个请求的URL映射到一个Action类,当一个请求匹配某个Action名称吋,框架就使用这个映射来确定如何処理请求。在struts.xml文件中,通辻 元素对请求的Action和Action类进行配置。 元素中共有4个属性,这4个属性的说明如下所示。
其中name属性和namespace属性共同决定了访问路径,class 对应的是Action 类的完全路径。Method指定了执行Action的那个方法,默认是execute方法。
基本的Struts2的配置我们已经了解了,在实际的开发中我们需要大量的用到Struts2的常量,那么我们接下来学习一下Struts2的常量。
name:必填属性,标书Action,指定Action所处理的请求URL。
class:可选属性,指定Action对应的Action类。
method:可选属性,指定请求Action是调用的方法。
converter:可选属性,指定类型转换器的类。
2.Struts2 常量的配置
Struts2的这些常量大多在默认的配置文件中已经配置好,但根据用户需求的不同,开发的要求也不同,可能需要修改这些常量值,修改的方法就是在配置文件对常量进行重新配置。Struts2常量配置共有3种方式,分别如下:
在strutsxml文件中使用元素配置常量。
在struts. properties文件中配置常量。
在web.xml文件中通过<param元素配置常量。
接下来分别对它们进行讲解,具体如下。
2.1、在struts.xml文件中通过元素配置常量
在struts.xml文件中通过元素来配置常量,是最常用的方式。在struts xml文件中通过<constan…/>元素来配置常量时,需要指定两个必填的属性name和value。
name: 该属性指定了常量的常量名。
value: 该属性指定了常量的常量值。
在struts.xml配置的代码示例如下:
<struts>
<!-- i18n国际化,解决post提交乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- 指定访问Action的后缀名
http://localhost:8080/StrutsProject/hello/HelloAction.do
-->
<constant name="struts.action.extension" value="action,,"></constant>
<!-- <constant name="struts.action.extension" value="action,,"></constant> -->
<!-- 指定Struts2是否以开发模式运行
1、热加载主配置(不需要重启服务器即可生效)
2、提供更多的错误信息输出,方便开发是调试
-->
<constant name="struts.devMode" value="true"></constant>
<package name="hello" namespace="/hello" extends="struts-default">
<action name="HelloAction" class="cn.dry.action.HelloAction" method="hello">
<result name="success" type="">/hello.jsp</result>
</action>
</package>
</struts>
在上述示例代码中,配置了常量struts il8n encoding和struts devMode,用于指定Struts2 应用程序的默认编码集为UTF-8,并使用开发模式。struts properties文件能配置的常量都可以在struts xml文件中用元素来配置。
2.2、在struts.properties文件中配置常量
struts. properties文件是一个示准的properties文件,其格式是key-value対,即毎个key对应一个value, key 表示的是Struts2框架中的常量,而value則是其常量值。在struts properties文件中配置常量的方式,具体如下所示::
struts.i18n.encoding=UTF-8
上述代码中,等号左边的为key,等号右边的为与key相对应的value
2. 3、在web.xml文件中通过初始化参数配置常量
在web xml文件中配置核心过滤器StrutsPrepareAndExecuteFilter时,通过初始化参数来配置常量。通过元素的子元素指定,每个元素配置了一个Struts2 常量。在web.xml文件中通过初始化参数配置常量方式,具体如以下代码片段所示:
<!-- 配置Struts2核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
<!-- 配置Struts2常量 -->
<init-param>
<!-- 通过 <init-param>来配置Struts2的常量,配置默认字符集为UTF-8 -->
<param-name>struts.i18n.encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
在上述web.xml文件的代码片段中,当配置StrutsPrepareAndExecuteFilter时,还通过子元素配置了常量struts.i18n.encoding,指定其值为UTF-8。需要注意的是,在web xml文件中配置常量时, 标签必须放在标签下。
Struts2所支持的常量数量众多,在struts2-core-2. 3.24.jar压缩文件\org/apache/struts2 路径下有一个default properties文件,该文件里为Struts2的所有常量都指定了默认值,读者可以通过查看该文件来了解Struts2所支持的常量。Struts2的配置文件的加载顺序,后加载的配置文件的常量的值会覆盖先加载的配置文件中常量的值。所以这个地方需要注意。
2.4 分模块开发的配置
在实际开发中,通常很多人都需要修改同一个配置文件就是struts.xml。 因为这个文件是Struts2的核心配置文件。而且这个文件一旦改错了一点,那么会导致整个项目都会出现问题,所以Struts2提供了标签解决这个问题。 元素用来在一个struts.xml配置文件中包含其他的配置文件,包含配置体现的是软件工程中的“分而治之”原则。Struts2 允许将一个配置文件分解成多个配置文件,从而提高配置文件的可读性。Struts2 默认只加载WEB-INF/classes下的struts.xml 文件,但一旦通过多 个xml文件来配置Action,就必须通过struts xml文件来包含其他配置文件。为了让大家更直观地理解如何在struts.xml 文件中进行包含配置,接下来通过一段示例代码来说明,具体如下:
<struts>
<package name="hello" namespace="/hello" extends="struts-default">
<action name="HelloAction" class="cn.dry.action.HelloAction" method="hello">
<result name="success" type="">/hello.jsp</result>
</action>
</package>
<!--不指定路径时默认在src路径下-->
<include file="struts-user.xml"></include>
<!--指定配置路径时-->
<include file="cn/dry/action/struts.xml"></include>
<include file="cn/dry/action1/struts.xml"></include>
</struts>
在上述代码片段中,struts.xml 文件包含了3个配置文件,这3个配置文件都包含在元素中。配置元素时,指定了一个必需的file属性,该属性指定了被包含配置文件的文件名。上述include元素的file属性中,第一个没有指定文件所在路径时,表示该文件在项目的src路径下,如果配置文件在具体的包中,那么引入配置文件时,需要包含文件所在包的路径。
需要注意的是,每一个被包含的配置文件都是标准的Struts2 配置文件,同样包含dtd 信息、Struts2配置文件的根元素等信息。通过将Struts2的所有配置文件都放在Web项目的WEB-INF/classes路径下,struts.xml 文件包含了其他的配置文件,在Struts2框架自动加载struts.xml文件时,完成加载所有的配置信息。
3、Struts2的Action的编写方式
3.1 Action是一个POJO类
在Struts2中,Action可以不継承特殊的类或不实现任何特殊的接口,仅仅是一个POJO。POJO全称Plain Ordinary Java Object (筒単的Java対象),只要具有一部分geter/setter 方法的那种类,就可以称作POJO。一般在这个POJO类中,要有一个公共的无参的杓造方法(采用默人的杓造方法就可以)和一个execute方法。定义格式如下:
package cn.dry.action2;
/**
* Struts2action类的创建方式
* @author
*
*/
//方式1:创建一个类,可以是POJO
//POJO:不用继承任何父类,也不用实现任何接口
//使Struts2框架的代码侵入性更低
public class Demo1Action {
public String execute() {
System.out.println("POJO类");
return null;
}
}
execute(方法的要求如下:
方法的权限修饰符为public。
返回一个字符串,就是指示的下一个页面的Result。方法没有参数。也就是说,满足上述要求的POJO都可算作是Struts2的Action实现。通常会让开发者自己编写Action类或者实现Action接口或者继承ActionSupport类。
3.2 Action类实现一个Action的接口
为了让用户开发的Action类更规范,Struts2 提供一个Action接口,用户在实现Action控制类时,可以实现Struts2提供的这个Action接口。Action接口定义了Struts的Action处理类应该实现的规范,Action 接口中的具体代码如下所示。
package cn.dry.action2;
import com.opensymphony.xwork2.Action;
/**
* Struts2action类的创建方式
* @author
*
*/
//方式2:实现一个action接口
//里面有execute方法,提共和action方法的规范
//Action方法预置了一些字符串,可以下返回结果是使用
public class Demo2Action implements Action {
@Override
public String execute() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
从上述代码中可以看出,Action接口位于com. opensymphony.xwork2包中。这个接口里只定义了一个execute0方法,该接口的规范规定了Action处理类应该包含一个execute(方法,该方法返回一;个字符串。除此之外,该接口还定义了5个字符串常量,它们的作用是统一execute(方法的返回值。 Action接口中提供了5个已经定义的常量如下:
3.2 Action继承一个ActingSupport类(最常用的方式)
package cn.dry.action2;
import com.opensymphony.xwork2.ActionSupport;
/**
* Struts2 action类的创建方式
* @author
*
*/
//方式3:继承一个类 ,ActionSupport
//他实现了Validateable,ValidationAware,TextProvider,LocaleProvider
//当我们需要用到这些接口时的实现时,不需要自己实现
public class Demo3Action extends ActionSupport {
private static final long serialVersionUID = 1L;
public String execute(){
System.out.println("ActionSupport");
return null;
}
}
ActionSupport类本身实现了Action 接口,是Struts2 中默认的Action接口的实现类,所以继承ActionSupport就相当于实现了Action 接口。ActionSupport类还实现了Validateable、 ValidationAware、TextProvider、LocaleProvider 和Serializable等接口,来为用户提供更多的功能。
ActionSupport类中提供了许多默认方法,这些默认方法包括获取国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等。实际上,ActionSupport 类是Struts2默认的Action处理类,如果让开发者的Action类继承该ActionSupport类,则会大大简化Action 的开发。
4 、客户列表案例
4.1 创建一个web工程,引入相关的Struts2的jar包(基本得到开发包可以从Struts2文件下的apps文件下的struts2-blank.war得到)
4.2、创建包和相关的类
4.3、配置web.xml的核心过滤器
<!-- 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>
4.4 、引入相应的Struts.xml配置
Action中的代码
public class CustomerAction extends ActionSupport implements ModelDriven<Customer> {
private CustomerService cs = new CustomerServiceImpl();
private Customer customer = new Customer();
private static final long serialVersionUID = 1L;
public String list()throws Exception{
//1、接收参数
String cust_name = ServletActionContext.getRequest().getParameter("cust_name");
//2、创建离线查询对象
DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
//3、判断参数拼接条件
if(StringUtils.isNotBlank(cust_name)){
dc.add(Restrictions.like("cust_name", "%"+cust_name+"%"));
}
//4、调用service将离线对象传递
List<Customer> list = cs.getAll(dc);
//5、将返回的list放入request域,转发到list.jsp显示
ServletActionContext.getRequest().setAttribute("list", list);
return "list";
}
}
DAO中的代码、
public interface CustomerDao {
//查询所有客户
List<Customer> getAll();
//根据id获得客户
Customer getById(Long cust_id);
//根据条件查询所有客户
List<Customer> getAll(DetachedCriteria dc);
}
service接口代码
public interface CustomerService {
//获得所有客户
List<Customer> getAll();
//根据条件查询所有客户
List<Customer> getAll(DetachedCriteria dc);
}
实现service接口的代码
public class CustomerServiceImpl implements CustomerService {
private CustomerDao customerDao = new CustomerDaoImpl();
public List<Customer> getAll() {
Session session = HibernateUtils.getCurrentSession();
//打开事务
Transaction tx = session.beginTransaction();
List<Customer> list = customerDao.getAll();
//关闭事务
tx.commit();
return list;
}
public List<Customer> getAll(DetachedCriteria dc) {
Session session = HibernateUtils.getCurrentSession();
//打开事务
Transaction tx = session.beginTransaction();
List<Customer> list = customerDao.getAll(dc);
//关闭事务
tx.commit();
return list;
}
}
用户表sql代码
CREATE TABLE `cst_customer` (
`cust_id` BIGINT(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',
`cust_name` VARCHAR(32) NOT NULL COMMENT '客户名称(公司名称)',
`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;
引入Hibernate核心jar包和配置
添加客户Hibernate映射
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- 配置表与实体对象的关系 -->
<!-- package属性:填写一个包名.在元素内部凡是需要书写完整类名的属性,可以直接写简答类名了. -->
<hibernate-mapping package="cn.dry.domain" >
<!--
class元素: 配置实体与表的对应关系的
name: 完整类名
table:数据库表名
-->
<class name="Customer" table="cst_customer" >
<!-- id元素:配置主键映射的属性
name: 填写主键对应属性名
column(可选): 填写表中的主键列名.默认值:列名会默认使用属性名
type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
每个类型有三种填法: java类型|hibernate类型|数据库类型
not-null(可选):配置该属性(列)是否不能为空. 默认值:false
length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
-->
<id name="cust_id" >
<!-- generator:主键生成策略-->
<generator class="native"></generator>
</id>
<!-- property元素:除id之外的普通属性映射
name: 填写属性名
column(可选): 填写列名
type(可选):填写列(属性)的类型.hibernate会自动检测实体的属性类型.
每个类型有三种填法: java类型|hibernate类型|数据库类型
not-null(可选):配置该属性(列)是否不能为空. 默认值:false
length(可选):配置数据库中列的长度. 默认值:使用数据库类型的最大长度
-->
<property name="cust_name" column="cust_name" >
<!-- <column name="cust_name" sql-type="varchar" ></column> -->
</property>
<property name="cust_source" column="cust_source" ></property>
<property name="cust_industry" column="cust_industry" ></property>
<property name="cust_level" column="cust_level" ></property>
<property name="cust_linkman" column="cust_linkman" ></property>
<property name="cust_phone" column="cust_phone" ></property>
<property name="cust_mobile" column="cust_mobile" ></property>
</class>
</hibernate-mapping>
配置Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<!--
#hibernate.dialect org.hibernate.dialect.MySQLDialect
#hibernate.dialect org.hibernate.dialect.MySQLInnoDBDialect
#hibernate.dialect org.hibernate.dialect.MySQLMyISAMDialect
#hibernate.connection.driver_class com.mysql.jdbc.Driver
#hibernate.connection.url jdbc:mysql:///test
#hibernate.connection.username gavin
#hibernate.connection.password
-->
<!-- 数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 数据库url -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_32?useUnicode=true&characterEncoding=UTF8</property>
<!-- 数据库连接用户名 -->
<property name="hibernate.connection.username">root</property>
<!-- 数据库连接密码 -->
<property name="hibernate.connection.password">密码</property>
<!-- 数据库方言
不同的数据库中,sql语法略有区别. 指定方言可以让hibernate框架在生成sql语句时.针对数据库的方言生成.
sql99标准: DDL 定义语言 库表的增删改查
DCL 控制语言 事务 权限
DML 操纵语言 增删改查
注意: MYSQL在选择方言时,请选择最短的方言.
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- #hibernate.show_sql true
#hibernate.format_sql true
-->
<!-- 将hibernate生成的sql语句打印到控制台 -->
<property name="hibernate.show_sql">true</property>
<!-- 将hibernate生成的sql语句格式化(语法缩进) -->
<property name="hibernate.format_sql">true</property>
<!--
## auto schema export 自动导出表结构. 自动建表
#hibernate.hbm2ddl.auto create 自动建表.每次框架运行都会创建新的表.以前表将会被覆盖,表数据会丢失.(开发环境中测试使用)
#hibernate.hbm2ddl.auto create-drop 自动建表.每次框架运行结束都会将所有表删除.(开发环境中测试使用)
#hibernate.hbm2ddl.auto update(推荐使用) 自动生成表.如果已经存在不会再生成.如果表有变动.自动更新表(不会删除任何数据).
#hibernate.hbm2ddl.auto validate 校验.不自动生成表.每次启动会校验数据库中表是否正确.校验失败.
-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- 指定hibernate操作数据库时的隔离级别
#hibernate.connection.isolation 1|2|4|8
0001 1 读未提交
0010 2 读已提交
0100 4 可重复读
1000 8 串行化
-->
<property name="hibernate.connection.isolation">4</property>
<!-- 指定session与当前线程绑定 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- 引入orm元数据
路径书写: 填写src下的路径
-->
<mapping resource="cn/dry/domain/Customer.hbm.xml" />
<mapping resource="cn/dry/domain/LinkMan.hbm.xml" />
</session-factory>
</hibernate-configuration>
配置Struts.xml
<?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>
<!-- 指定struts2是否以开发模式运行
1.热加载主配置.(不需要重启即可生效)
2.提供更多错误信息输出,方便开发时的调试
-->
<constant name="struts.devMode" value="true"></constant>
<package name="crm" namespace="/" extends="struts-default" >
<action name="CustomerAction_*" class="cn.dry.web.CustomerAction" method="{1}" >
<result name="list" >/jsp/customer/list.jsp</result>
<result name="tolist" type="redirectAction">
<param name="actionName">CustomerAction_list</param>
<param name="namespace">/</param>
</result>
</action>
</package>
</struts>
测试结果