struts2学习笔记(三)—— struts2的常见配置
一、配置文件的加载顺序
每次从客户端发送请求到服务器都要先经过Struts2的核心过滤器StrutsPrepareAndExecuteFilter,这个过滤器有两个功能:预处理和执行。在预处理中主要就是来加载配置文件的。对应的是过滤器中的init方法,而执行是用来执行一组拦截器完成部分功能的,对应的是过滤器的doFilter方法。所以我们如果要去了解Struts2的配置文件的加载顺序,那么我们需要查询过滤器的init方法。
在init方法中,调用了init的initDispatcher方法来加载配置文件,进入到该代码中:
我们发现这个方法又调用了dispatcher的init方法,进入init方法内部:
这一系列代码就是用来加载Struts2的配置文件的
init_DefaultProperties(); // 加载org.apache.struts.default.properties,里面配置的是struts2的所有常量
init_TraditionalXmlConfigurations(); // 加载struts-default.xml、struts-plugin.xml、struts.xml
init_LegacyStrutsProperties(); // 加载用户自定义的struts.properties
init_CustomConfigurationProviders(); // 加载用户配置的提供对象
init_FilterInitParameters() ; // 加载web.xml
init_AliasStandardObjects() ; // 加载标准对象
根据上面的代码我们可以得出配置的加载顺序为
* default.properties
* struts-default.xml
* struts-plugin.xml
* struts.xml --- 配置Action以及常量(******)
* struts.properties --- 配置常量
* web.xml --- 配置核心过滤器及常量
前三个配置文件我们不用关心,是Struts2内部的配置文件,我们无法修改,能修改的文件就是struts.xml,struts.properties,web.xml。这几个配置文件的加载是有一定顺序的。这三个配置文件都可以修改Struts2的常量的值,要记住的是,后加载配置文件中常量的值会将先加载的配置文件中常量的值给覆盖。
二、struts.xml配置
struts.xml是struts2的核心配置文件,该文件主要用来配置Action和请求的对应关系。
<!-- package:将Action配置封装.就是可以在Package中配置很多action.
name属性: 给包起个名字,起到标识作用.随便起.不能其他包名重复.
namespace属性:给action的访问路径中定义一个命名空间
extends属性: 继承一个指定包,通常都设置为struts-default,这样该包中的Action就具有了Struts2框架默认的拦截器等功能了
abstract属性:包是否为抽象的; 标识性属性.标识该包不能独立运行.专门被继承
-->
<package name="hello" namespace="/hello" extends="struts-default" >
<!-- action元素:配置action类
name属性: 决定了Action访问资源名.(name属性和namespace属性共同决定了访问路径)
class属性: action的完整类名
method属性: 指定调用Action中的哪个方法来处理请求,默认是execute方法
-->
<action name="HelloAction" class="cn.itheima.a_hello.HelloAction" method="hello" >
<!-- result元素:结果配置
name属性: 标识结果处理的名称.与action方法的返回值对应.
type属性: 指定调用哪一个result类来处理结果,默认使用转发.
标签体:填写页面的相对路径
-->
<result name="success" type="dispatcher" >/hello.jsp</result>
</action>
</package>
<!-- 引入其他struts配置文件 -->
<include file="cn/itheima/b_dynamic/struts.xml"></include>
三、struts2常量配置
3.1 struts2默认常量配置位置
3.2 常量配置的方式
- 在struts.xml文件中通过<constant>元素配置常量(最常用)
<!-- i18n:国际化. 解决post提交乱码 -->
<constant name="struts.i18n.encoding" value="UTF-8"></constant>
<!-- 指定访问action时的后缀名
http://localhost:8080/struts2_day01/hello/HelloAction.do
-->
<constant name="struts.action.extension" value="action"></constant>
<!-- 指定struts2是否以开发模式运行
1.热加载主配置.(不需要重启即可生效)
2.提供更多错误信息输出,方便开发时的调试
-->
<constant name="struts.devMode" value="true"></constant>struts.properties文件能配置的常量都可以在struts.xml中用<constant>元素来配置
- 在struts.properties文件中配置常量
注意:和struts.xml一样,struts.properties文件也应该放在src目录下
- 在web.xml中通过初始化参数配置常量
<!-- 配置常量 -->
<context-param>
<param-name>struts.i18n.encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
之前我们介绍过Struts2配置文件的加载顺序(struts.xml>struts.properties>web.xml),后加载的配置文件的常量的值会覆盖先加载的配置文件中常量的值。所以这个地方要注意。
四、分模块开发的配置
在实际开发中我们更习惯使用struts.xml修改struts2的常量。但是这样就会有一个问题,如果一个项目是团队开发的,也就是很多人开发的,那么团队中的很多人就都需要去修改同一个struts.xml,因为这个文件是Struts2的核心配置文件。而这个文件一旦改错了一点,就会导致整个项目都会出现问题,所以struts2也支持分模块开发的配置,它提供了<include>标签来解决这个问题。
<include>元素用来在一个struts.xml配置文件中包含其他的配置文件,包含配置体现的是软件工程中的“分而治之”原则。Struts2允许将一个配置文件分解成多个配置文件,从而提高配置文件的可读性。
<!-- 包含了3个配置文件 -->
<!-- 不指定路径,默认在src下 -->
<include file="struts-shop.xml"/>
<include file="struts-user.xml"/>
<!-- 配置文件在具体包中 -->
<include file="cn/itcast/action/struts-product.xml"/>
上面的3个配置文件中,前两个没有指定文件的所在路径,表示该文件在项目的src路径下,如果配置文件在具体的包中,那么引入配置文件时,需要包含文件所在包的路径。
需要注意的是,每一个被包含的配置文件都是标准的Struts2配置文件,一样包含DTD信息、Struts2配置文件的根元素信息等。通过将Struts2的所有配置文件都放在web项目的WEB-INF/classes路径下,struts.xml文件包含了其他的配置文件,在Struts2框架自动加载struts.xml文件时,完成加载所有的配置信息。
五、Action类的配置
在Struts2的应用开发中,Action作为框架的核心类,实现对用户请求的处理,Action类被称为业务逻辑控制器。一个Action类代表一次请求或调用,每个请求的动作都对应一个响应的Action类,一个Action类是一个独立的工作单元。也就是说,用户的每次请求,都会转到一个响应的Action类里面,由这个Action类来进行处理。简而言之,Action就是用来处理一次用户请求的对象。
5.1 Action的编写方式
【Action是一个POJO类】
在Struts2中,Action可以不继承特殊的类或不实现任何特殊的接口,仅仅是一个POJO。POJO全称Plain Ordinary Java Object(简单的Java对象),只要具有一部分getter/setter方法的那种类,就可以称作POJO。一般在这个POJO类中,要有一个公共的无参的构造方法(采用默认的构造方法就可以)和一个execute()方法。定义格式如下:
public class ActionDemo1 { public String execute() {
System.out.println("ActionDemo1执行了。。。");
return null;
}
}
execute()方法的要求如下:
- 方法的权限修饰符为public
- 返回一个字符串,就是指示的下一个页面的Result
- 方法没有参数
也就是说,满足上述要求的POJO都可算作是Struts2的Action实现。
【Action类实现一个Action的接口】
为了让用户开发的Action类更规范,Struts2提供一个Action接口,用户在实现Action控制类时,可以实现Struts2提供的这个Action接口。
Action接口定义了Struts的Action处理类应该实现的规范,Action接口中的具体代码如下所示。
public class ActionDemo2 implements Action{ public String execute() {
System.out.println("ActionDemo2执行了。。。");
return null;
}
}
从上述代码中可以看出,Action接口位于com.opensymphony.xwork2包中。这个接口里只定义了一个execute()方法,该方法返回一个字符串。除此之外,该接口还定义了5个字符串常量,它们的作用是统一execute()方法的返回值。
由于Xwork的Action接口简单,为开发者提供的帮助较小,所以在实际开发过程中,Action类很少直接实现Action接口。
【Action类继承ActionSupport类】(推荐)
public class ActionDemo3 extends ActionSupport{ public String execute() {
System.out.println("ActionDemo3执行了。。。");
return null;
}
}
ActionSupport类本身实现了Action接口,是Struts2中默认的Action接口实现类,所以继承ActionSupport就相当于实现了Action接口。ActionSupport类还实现了Validateable、ValidationAware、TextProvider、LocaleProvider和Serializable等接口,为用户提供更多的功能。
ActionSupport类提供了许多默认方法,这些默认方法包括获取国际化信息的方法、数据校验的方法、默认的处理用户请求的方法等。实际上,ActionSupport类是Struts2默认的Action处理类,如果让开发者的Action类继承该ActionSupport类,则会大大简化Action的开发。
5.2 Action的访问
Action的访问不是难题,因为之前已经访问过了,但是出现一个问题:一次请求现在对应一个Action,那么如果请求很多就会对应多个Action。现在要处理的问题就是要让一个模块的操作提交到一个Action中。我们可以通过<action>标签中的method属性来指定Action中某个方法的执行。
【方式一:通过配置method属性完成】
- 编写页面:
<h2>客户的管理</h2>
<a href="${pageContext.request.contextPath }/saveCustomerAction.action">添加客户</a><br>
<a href="${pageContext.request.contextPath }/updateCustomerAction.action">修改客户</a><br>
<a href="${pageContext.request.contextPath }/deleteCustomerAction.action">删除客户</a><br>
<a href="${pageContext.request.contextPath }/findCustomerAction.action">查询客户</a><br> - 编写Action:
public class CustomerAction extends ActionSupport{
public String save(){
System.out.println("CustomerAction中的save方法执行了...");
return NONE;
} public String delete(){
System.out.println("CustomerAction中的delete方法执行了...");
return NONE;
}
public String update(){
System.out.println("CustomerAction中的update方法执行了...");
return NONE;
}
public String find(){
System.out.println("CustomerAction中的find方法执行了...");
return NONE;
}
} - 配置Action:
<package name="demo3" namespace="/" extends="struts-default">
<action name="saveCustomerAction" class="cn.itcast.struts2.action.CustomerAction" method="save"></action>
<action name="deleteCustomerAction" class="cn.itcast.struts2.action.CustomerAction" method="delete"></action>
<action name="updateCustomerAction" class="cn.itcast.struts2.action.CustomerAction" method="update"></action>
<action name="findCustomerAction" class="cn.itcast.struts2.action.CustomerAction" method="find"></action>
</package>但是这种方法我们发现,同一个Action类被配置了很多次,只是修改了后面的method的值。那么能不能配置简单化呢?也就是一个Action类,只配置一次就好?这个时候我们就需要使用通配符的配置方式了。
【方式二:通过通配符的配置完成】(开发中常用)
- 编写页面
<h2>联系人的管理</h2>
<a href="${pageContext.request.contextPath }/linkMan_save.action">添加联系人</a><br>
<a href="${pageContext.request.contextPath }/linkMan_update.action">修改联系人</a><br>
<a href="${pageContext.request.contextPath }/linkMan_delete.action">删除联系人</a><br>
<a href="${pageContext.request.contextPath }/linkMan_find.action">查询联系人</a><br> - 编写Action
public class LinkManAction extends ActionSupport {
public String save(){
System.out.println("保存联系人...");
return NONE;
} public String delete(){
System.out.println("删除联系人...");
return NONE;
} public String update(){
System.out.println("修改联系人...");
return NONE;
} public String find(){
System.out.println("查询联系人...");
return NONE;
}
} - 配置Action
<!-- 通配符的配置 -->
<action name="linkman_*" class="cn.itcast.struts2.action.LinkManAction" method="{1}"></action>
在<action>的name属性中使用的*代表任意字符,method中的{1}代表name属性中出现的第一个*所代替的字符。
这个时候我们就只配置一个就可以了,在上述代码中,当客户端发送/linkman_save.action这样的请求时,action元素的name属性就被设置成linkman_save,method属性就被设置成save。当客户端发送/linkman_update.action这样的请求是,action元素的name属性就被设置为linkman_update,method属性也被设置成update。
【方式三:动态方法访问】(了解)
动态方法访问在Struts2中默认是不开启的,如果想要使用,需要先去struts.xml中开启一个常量。
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
动态方法访问主要的控制是在页面端,所以编写Action和配置Action都很简单,关键是访问路径的编写。
- 编写Action
public class UserAction extends ActionSupport {
public String save(){
System.out.println("保存用户...");
return NONE;
} public String delete(){
System.out.println("删除用户...");
return NONE;
} public String update(){
System.out.println("修改用户...");
return NONE;
} public String find(){
System.out.println("查询用户...");
return NONE;
}
} - 配置Action
<!-- 动态方法访问的配置 -->
<action name="userAction" class="cn.itcast.struts2.action.UserAction"></action> - 页面路径的写法
<h2>用户的管理</h2>
<a href="${pageContext.request.contextPath }/userAction!save.action">添加用户</a><br>
<a href="${pageContext.request.contextPath }/userAction!update.action">修改用户</a><br>
<a href="${pageContext.request.contextPath }/userAction!delete.action">删除用户</a><br>
<a href="${pageContext.request.contextPath }/userAction!find.action">查询用户</a><br>
struts2学习笔记(三)—— struts2的常见配置的更多相关文章
- struts2学习笔记三
一.国际化概念(了解) 1.什么是国际化 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 2.什么需要国际 ...
- Struts2学习笔记(三):result配置的各项视图转发类型
Struts 1: <action path="/user" type="org.sunny.user.action.UserAction" ...> ...
- Struts2学习笔记(一):Struts2开发环境的配置
一.Struts2应用所需的jar文件. 开发struts2应用需要依赖的jar文件在解压目录下的lib文件夹里面.开发struts2程序最少需要的jar文件为:struts2-core-2.xx.j ...
- Struts2学习笔记(三)——Action详解
Action是用于处理请求操作的,它是由StrutsPrepareAndExceuteFilter分发过来的. 1.Action的创建方式 1) POJO类(PlainOldJavaObjects简单 ...
- Struts2学习笔记(1)---相关配置
Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架. 1创建action对象(三种) 1 创建普通的类,不继承任何类, ...
- Struts2学习笔记三:深入Action
一:Action中获取参数值 在Servlet中,我们通过doGet()/doPost()方法中的参数,获取request/response对象,然后提取参数值: 处理请求结束后,有数据需要携带返回客 ...
- Struts2学习笔记三 访问servlet
结果跳转方式 转发 <!-- 转发 --> <action name="Demo1Action" class="cn.itheima.a_result. ...
- Struts2学习笔记01 之 简介及配置
一.Struts简介 * 是轻量级的MVC框架,主要解决了请求分发的问题,重心在控制层和表现层.运用ASOP的思想,使用拦截器来扩展业务控制器 二.使用步骤: 1.引入Sturts2的相关JAR包 2 ...
- struts2学习笔记之六:struts2的Action访问ServletAPI的几种方式
方法一:通过ActionContext访问SerlvetAPI,这种方式没有侵入性 Action类部分代码 import com.opensymphony.xwork2.ActionContext; ...
- struts2学习笔记2 -struts2的开发步骤和工作原理
struts2的开发步骤: 1.先定义一个能发送请求的页面,可以是链接,也可以是表单(form) 2.开发action类,struts2对action并没有过多的要求,只要求: a 推荐实现actio ...
随机推荐
- Loadrunner Analyze
Analysis 对controller运行的结果进行分析 1.首先必须明确:光靠Analysis是不行的,只要能通过Analysis分析出部分问题就已经很不错了, 善于利用它才是最关键的. 2.如何 ...
- jquery中的cookie使用
一.检测cookie是否启用 通过navigator.cookieEnabled这个属性实现,若该值为true,则当前cookie是启用的,反之是禁用的,注意:此属性不是一个标准的属性 二.cooki ...
- 使用FileReader与FileWriter读写数据
-------------siwuxie095 工程名:TestFileRW 包名:com.siwuxie095.filerw 类名:FileReade ...
- 什么是Kali Linux?
什么是Kali Linux? Kali Linux是一个基于Debian的Linux发行版,旨在实现高级渗透测试和安全审计.Kali包含数百种工具,适用于各种信息安全任务,如渗透测试,安全研究,计算机 ...
- SQL 数据库 学习 002 如何启动 SQL Server 软件
如何启动 SQL Server 软件 我的电脑系统: Windows 10 64位 使用的SQL Server软件: SQL Server 2014 Express 如果你还没有下载 SQL Serv ...
- Swing滚动条重写
Swing滚动条重写 摘自:https://blog.csdn.net/qq_40064948/article/details/81738191 未验证 Swing滚动条重写 2018年08月16日 ...
- 第八课 ROS的空间描述和变换
1.tf的实际应用 1)在机器人的配置中 从上面可以看出激光雷达中心距离机器人底座的中心有20cm,激光雷达的中心距机器人底座中心有10cm,如果激光雷达在障碍物前面0.3米,那么机器人底座离障碍物多 ...
- C# 把本地文件上传到服务器上,和从服务器上下载文件
方法一.通过Ajax方式上传文件(input file),使用FormData进行Ajax请求 <div > <input type="file" name=& ...
- JPA注解解析
最近学习hibernate注解形式配置POJO类,将注解的解析记下来,以备以后使用. 例1. @Entity@Table(name="user") public class Fl ...
- C#序列化xml,开发常用
序列化操作对于开发人员来说最熟悉不过了. 序列化分为:序列化和反序列化. 序列化名词解释:序列化是将对象状态转换为可保持或传输的格式的过程. 与序列化相对的是反序列化,它将流转换为对象.这两个过程结合 ...