1、建立一个jsp文件
1 <html>
2 <head>
3 <title>My JSP \'index.jsp\' starting page</title>
4 </head>
5 <body>
6 <%--在Struts中,控制器会默认拦截扩展名为.action的请求(以.action为后缀的url) --%>
7 <a href="${pageContext.request.contextPath }/hello.action">访问Struts2的第一个案例</a>
8 <a href="${pageContext.request.contextPath }/hello">访问Struts2的第一个案例,没有.action</a>
9 </body>
10 </html>
2、在structs.xml中配置
1 <struts>
2 <package name="p1" extends="struts-default">
3 <action name="hello" class="cn.guojie.web.action.HelloAction" method="sayHello">
4 <result name="success">/success.jsp</result>
5 </action>
6 </package>
7 </struts>
3、建立动作类和动作方法
1 public class HelloAction {
2
3 /**
4 * 在动作中指定的方法
5 * 要求
6 * 1、必须public
7 * 2、返回值必须是一个String
8 * 3、必须没有参数
9 */
10 public String sayHello() {
11 System.out.println("HelloAction中的sayHello方法执行了");
12 return "success";
13 }
14 }
4、结果视图页面success.jsp
1 <head>
2 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
3 <title>Insert title here</title>
4 </head>
5 <body>
6 操作成功
7 </body>
8 </html>
四、执行过程
servlet执行过程:客户浏览器 --> Tomcat服务器 -- > web.xml --> Servlet
Struts2执行过程:客户浏览器 --> Tomcat服务器 --> web.xml --> struts.xml --> HelloAction --> success.jsp
过滤器(web.xml)在服务器一启动就执行初始化
servlet只实例化一次,有线程安全问题;Structs实例化多次,无线程安全问题
内部执行过程
五、Struts2配置文件
当应用被 tomcat 加载的时候, struts2的配置文件就已经被加载过了
加载顺序
(1)default.properties 保存在 struts2-core-2.3.7.jar 中 org.apache.struts2包里面(常量)
(2)struts-default.xml 保存在 struts2-core-2.3.7.jar(核心,拦截器、常用结果视图、默认动作类)
(3)struts-plugin.xml 保存在struts-Xxx-2.3.7.jar(插件)
(4)struts.xml 是web应用默认的struts配置文件(自己应用中,要修改,推荐)
(5)struts.properties 是Struts的默认配置文件(自己应用中,不推荐)
(6)web.xml 是Web应用的配置文件(修改)
如果多个文件配置了同一个struts2 常量,则后一个文件中配置的常量值会覆盖前面文件配置的常量值
Struts2 提供了两种配置的方式:一种是 key=value 的方式,即使用 .properties文件。另一种是 xml 文件配置,我们推荐使用 xml 文件(它能描述层级关系)
六、Struts2 提供的常量
1、常用的常量
常量定义在了 default.properties 配置文件中,体现形式都是 key=value 。所有的struts2 应用都会用到这些常量
2、在 struts.xml中覆盖常量
使用 <constant name="" value=""></constant> 元素进行覆盖
3 、创建struts.properties 文件覆盖
在应用的构建路径中创建一个 struts.properties 的文件
4 、在web.xml 中配置过滤器参数
七、xml 配置文件的主要元素
1 、 package元素
1.1 、作用:
在 struts2的配置文件中引入了面向对象思想,使用了分包管理,易于管理动作类,便于模块化开发动作类。
1.2 、属性:
name :包的名称,必须写,且必须唯一。
extends :一般情况下需要继承 struts-default 包,但不是必须的。不过如果不继承的话,将无法使用 struts2 提供的核心功能。struts-default.xml 中定义着 struts-default 这个包。而struts-default.xml 是在我们的 struts.xml 加载之前加载。
abstract :把包声明为抽象包,抽象包就是用来被继承的。只要是没有 <action> 元素的包,就可以声明为抽象包。
namespace :名称空间。指定了名称空间之后,访问路径=名称空间 + 动作名称,当不指定该属性时,该属性有默认值“ ”,不是“/”,不写namespace就是默认
名称空间搜索顺序
第一步:找对应的名称空间
在指定的名称空间下找到了就执行第二步,在指定的名称空间下没找到,按名称空间结构向上一级查找,一直到根名称空间,只要在任何一级找到了就执行第二步
第二步:找动作名称
在指定的名称空间下,搜索对应的动作名称,找到了就执行动作类的动作方法
在指定的名称空间下没找到对应的动作名称,前往默认的名称空间下找动作名称,注意,只招动作名称,名称空间在第一步已经执行
2 、 action元素
2.1 、作用:
配置动作,用于定义动作名称,动作类和动作方法的映射,以及当前出现不同情况时前往指定的结果视图
过滤器过滤动作名称,通过动作类的字节码文件反射,拿到getter执行方法
2.2 、属性:
name :动作名称
class :动作类全名。默认的动作类是: com.opensymphony.xwork2.ActionSupport
是在 struts-default.xml中定义的
要想替换默认动作类:
在应用的 struts.xml 中,package 中加入:
method:动作类中的方法名称。默认是 public String execute(){}
要求:
1.public 的
2. 返回值必须是 String
3. 没有参数
2.3 、动作类
方式一:动作类就是一个 POJO (Plain Old Java Object 原始的 java 对象),非常简单的 javabean。
无侵入式,与struts2看不出来有关系
方式二:动作类实现 com.opensymphony.xwork2.Action接口。
常量:给动作方法返回值用的。用常量可以使你的应用规范和统一。
SUCCESS "success" 执行成功后,前往指定位置
NONE "none" 不返回任何结果视图,和return null作用一样
ERROR "error" 当执行动作方法出现异常后前往指定位置
INPUT "input" 数据回显
LOGIN "login" 一般用于返回登录页面
方式三:动作类继承 com.opensymphony.xwork2.ActionSupport接口实现类(推荐使用 )
什么都不写时,有一个默认动作方法execute()
默认动作类ActionSupport,在struts-default.xml的配置文件中定义着
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />,一般不修改
2.4 、动作方法的访问
(1)使用通配符:
*表示动作的名称,当有和动作名称相匹配的时候可以用{出现的位置}来代替
优先级:绝对匹配优先。使用通配符的按照在配置文件中的先后顺序进行匹配的
(2)动态方法调用(不安全)
八、结果类型视图 ( 逻辑结果视图 )
该部分内容指的就是 struts 配置文件中的 result元素的使用
1 、 result元素
作用:
为动作指定结果视图
属性:
name :逻辑视图的名称,对应着动作方法的返回值,当一致时前往指定的jsp。默认值是 success
type :结果类型,指的就是用什么方式转到定义的页面。默认是 dispatcher
2 、 result元素中 type 的取值
type 属性的取值在 struts-default.xml中定义
常用结果类型介绍
(1) dispatcher : (默认值 )
使用请求转发,转向一个页面。
(2)redirect :
使用重定向,转向一个页面
(3)redirectAction :注意:使用的是重定向。
1. 重定向到相同名称空间的另一个动作。
<result name="success" type="redirectAction">action2</result>
2.重定向到不同名称空间的动作
<result name="success" type="redirectAction">
使用注入的思想,在执行重定向之前,会先获得这两个参数的值,调用的就是setNamespace("/n2")和setActionName("action3")的方法
<param name="namespace">/n2</param>
<param name="actionName">action3</param>
</result>
(4)chain :注意: 使用的是请求转发。
1. 转发到相同名称空间的另一个动作。
<result name="success" type="chain">action2</result>
2.请求转发到不同名称空间的动作
<result name="success" type="chain">
使用的是注入的思想,在执行之重定向之前,会先获取这两个参数的值
调用的就是setNamespace("/n2")和setActionName("action3")
<param name="namespace">/n2</param>
<param name="actionName">action3</param>
</result>
3 、 result元素中 param 子元素
在转发或者重定向到不同包下的动作时,都用到了 result 元素的子元素 param。
param 元素的作用: 依赖注入 (Dependence Injection) 思想
我们通过 struts-default.xml 中的resultTypes 元素中配置可以看出,每个结果类型视图其实都是靠一个类来实现的。而 param 元素就是将配置的参数,注入到该类中。
调用的是对应类的 setter 方法进行注入的。
redirectAction结果视图
该类中肯定会有对 actionName 和namespace 属性的注入方法( setter 方法)
默认结果视图 dispatcher
4、自定义结果类型
通过前面的内容,我们看出,其实结果类型就是一个类,这些类都实现了com.opensymphony.xwork2.Result接口。
或者继承自该接口的实现类org.apache.struts2.dispatcher.StrutsResultSupport。
这些类都有一个doExecute方法,用于执行结果视图。
综上:我们也可以自己写一个结果视图。
输出CAPTCHA图像的结果类型
CAPTCHA(Completely Automated Public Turing Test to Tell Computers and Humans Apart 全自动区分计算机和人类的图灵测试)————>简称:验证码。
第一步:写一个类,实现接口或者继承接口的实现类
第二步:在 struts.xml 文件中配置结果类型
第三步:在 action 配置时引用
通过可配置的参数,实现图像大小的调整
5、全局视图和局部视图
5.1、局部视图
写在action内部的结果视图,只能当前动作类使用
5.2、全局视图
查找顺序,先找当前动作类的自己的,没有再去全局结果视图中查找
九、在动作类中访问Servlet的API
第一种方式:使用ServletActionContext类(推荐)
第二种方式:使用实现接口的方式
使用的是依赖注入的形式,把想要的对象注入进来,有拦截器做的
十、分文件编写框架配置文件
1、不分文件开发可能产生的问题
就类似于我们在写java类时,所有代码都写在一个类里,甚至写在一个方法里。
当3个人都checkout了struts.xml文件时,第一个人提交了,后面的人在没有更新就提交时,第一个人写的可能就白写了。
2、分文件编写Struts2的配置文件
约定优于配置
约定优于配置(convention over configuration),也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做决定的数量,获得简单的好处,而又不失灵活性。
本质是说,开发人员仅需规定应用中不符约定的部分。例如,如果模型中有个名为Sale的类,那么数据库中对应的表就会默认命名为sales。只有在偏离这一约定时,例如将该表命名为”products_sold”,才需写有关这个名字的配置。
如果您所用工具的约定与你的期待相符,便可省去配置;反之,你可以配置来达到你所期待的方式。
转发和重定向
转发:一次请求,一次响应。地址栏的url不会改变。在服务器端执行,所以必须在同一台服务器上。转发速度快。
重定向:两次请求。地址栏的url会随之改变为定向后的那个url。在客户端执行,所以可以在不同的服务器上。重定向速度慢。