龙空技术网

Struts2的基础入门--最早的MVC框架

JAVA油腻男 169

前言:

现在朋友们对“struts2 chain”大约比较关怀,小伙伴们都需要学习一些“struts2 chain”的相关资讯。那么小编也在网上汇集了一些有关“struts2 chain””的相关文章,希望你们能喜欢,你们一起来了解一下吧!

《爱读书系列》,本人会把技术学习中阅读过的书籍通过笔记和总结的方式与粉丝分享,此系列是在原著基础上收录和总结而来,希望大家得到更多的支持。
本书简介

书名为《轻量级JavaEE企业应用实战》,是本人在学习JavaEE框架的时候阅读的第一本书,本书对于框架及相关基础知识讲述的比较详细和浅显,适合初学者和需要全面了解JavaEE知识的人群。

本文内容为第三章的第1部分内容

MVC思想概述

1.传统Model1和Model2

Model1模式:整个Web应用几乎全部由JSP页面组成,JSP页面接收处理客户端请求,对请求处理后直接做出响应。用少量的JavaBean来处理数据库连接和访问等操作。可见JSP页面身兼View和Controller两种角色,逻辑混乱可维护性差。

Model2模式:基于MVC架构的设计。Servlet作为控制器,负责接收客户端请求,Servlet中只包含控制逻辑和简单的前端处理;然后调用后端JavaBean完成业务处理;最后转发到对应的JSP页面渲染视图。如下图:

在Model2模式下,Model层(模型)由JavaBean充当,View层(视图)由JSP充当,Controller层(控制器)由Servlet充当。

2.MVC思想及其优势

MVC思想分成三个基本部分:Model层(模型)、View层(视图)、Controller层(控制器)

MVC的优势

多个视图可以对应一个模型。可以减少代码的复制及代码维护量,一旦模型发生改变,易于维护。模型返回的数据与现实逻辑分离。模型数据可以应用任何现实技术,如JSP、Velocity等。应用被分为三层,降低了各层的耦合,提高了可扩展性。控制层可以把不同的模型与不同的视图组合在一起,以处理不同的请求。MVC更符合软件工程化管理思路,不同层各司其职,每一层组件具有相同特征。

Java Web的MVC流程如下图:

Struts2的开发流程

(1)将下载的struts2的程序包中的jar包复制到WEB应用的WEB-INF/lib目录下

(2)在web.xml文件中配置Struts2核心Filter来拦截用户请求

(3)如果需要以POST方式提交请求,则定义包含表单数据的JSP页面。如果以GET方式提交,则跳过这步。

(4)定义处理用户请求的Action类

(5)配置Action。即指定哪个请求调用哪个Action进行处理。如下图:

(6)配置处理结果和物理视图间的对应关系

Action处理请求结束后,通常会返回一个处理结果,也叫逻辑视图名。这个逻辑视图需要和物理视图关联才有意义,所以我们需要配置关联关系。如下图:

(7)编写视图资源。获取数据可以采用OGNL或JSTL表达式

Struts2常规配置

1.常量配置

struts2除了可使用struts.xml来管理配置外,还可使用struts.properties来管理常量。struts.properties是一个标准的Properties文件,该文件包含了系列的key-value对。对应着常量的键和值。

只需要将struts.properties放在应用的类加载路径下,struts2框架就可以加载该文件。

在struts2-core.jar文件的org\apache\struts2路径下有一个default.properties文件,改文件配置了所有常量的默认值

常用的常量如下:

(1)struts.locale:制定WEB应用的默认Locale,默认值en_US(2)struts.i18n.encoding:制定WEB应用的默认编码集。默认值UTF-8(3)struts.multipart.parser:制定处理multipart/form-data的MIME类型请求的框架。默认值jakarta(即common-fileupload上传框架)(4)struts.multipart.saveDir:指定文件上传的临时保存路径,默认值是tomcat的temp目录(5)struts.multipart.maxSize:指定文件上传中允许的最大字节数(6)struts.custom.properties:指定应用加载用户自定义常量文件,多个文件用逗号隔开(7)struts.action.extension:指定处理的请求后缀,默认值action。即所有匹配*.action的请求都有struts2处理,多个后缀用逗号隔开(8)struts.serve.static.browerCache:设置浏览器是否缓存静态内容(9)struts.enable.DynamicMethodInvocation:设置是否支持动态方法调用,默认值true(10)struts.devMode:设置是否使用开发模式。设置为true则应用出错时显示更多更友好的提示。开发阶段可设置为true(11)struts.i18n.reload:设置是否每次HTTP请求到达事,系统重新加载资源文件。默认值false。开发阶段可设置为true(12)struts.configuration.xml.reload:设置当struts.xml文件改变后,系统是否重新加载该文件。默认值false。开发阶段可设置为true(13)struts.ui.theme:指定视图标签默认的视图主题,默认值xhtml(14)struts.custom.i18n.resources:指定应用所需要的国际化资源文件,多个资源文件用逗号隔开

配置文件加载方式和流程

struts2默认会加载类加载路径下的struts.xml、struts-default.xml、struts-plugin.xml三类文件,其中struts.xml是开发者订的的默认配置文件,struts-default.xml是struts2框架自带的配置文件,struts-plugin.xml是struts2插件的默认配置文件。

常用配置方式:

通过struts.properties

直接在类加载路径下创建文件并通过标准属性文件的格式key=value配置

通过struts.xml通过应用的web.xml

在引入struts框架时配置

通过按照如下顺序加载常量:

(1)struts-default.xml:保存在struts2-core.jar中(2)struts-plugin.xml:保存在struts2插件的jar文件中(3)struts.xml:应用struts2默认配置文件(4)struts.properties:struts2默认属性配置文件(5)web.xml:应用配置文件

以上顺序中后面文件中常量配置信息会覆盖前面的

2.包含其他配置文件

为了避免struts.xml文件过于庞大,可以将struts.xml分解成多个配置文件,然后再主配置文件中包含其他配置文件,方式如下:

实现Action

在struts2中,Action类是框架核心,包含了对用户请求的处理逻辑,Action类被称作业务控制器。struts2中Action不需要继承任何基类或实现任何接口,Action类作为一个普通的POJO(需要包含一个execute方法),通常可直接封装HTTP请求参数并提供setter、getter方法。如下图:

(1)Action类中可以封装请求参数也可以封装处理结果

(2)execute方法用于处理用户请求,可在其中编写逻辑

1.Action接口和ActionSupport基类

为了简化和规范Action类的开发,我们可以实现Action接口或继承ActionSupport类

Action接口如下图:

Action接口中定义了逻辑试图名和请求处理方法

ActionSupport类如下图:

ActionSupport类提供了很多默认方法,包括获取国际化信息、数据校验、处理用户请求等

2.Action访问Servlet API

struts2的Action没有与任何Servlet API耦合,但如果需要访问Servlet API可以使用ActionContext类,常用方法如下:

Object get(Object key):类似于调用HttpServletRequest的getAttribute(String name)Map getApplication():获取应用的ServletContext实例ActionContext getContext():获取ActionContext实例Map getParameters():获取所有请求参数,类似于HttpServletRequest的getParameterMap()Map getSession():获取HttpSession实例void setApplication(Map application):设置application作用域内的属性值void setSession(Map session):设置session作用域内的属性值

3.Action直接访问Servlet API

为了Action中直接访问Servlet API,struts2提供了如下接口:

ServletContextAware:可直接访问应用的ServletContext实例ServletRequestAware:可直接访问HttpServletRequest实例ServletResponseAware:可直接访问HttpServletResponse实例

使用步骤

(1)实现对应接口(2)声明对应实例(3)实现对应实例的setter方法

如下图粗体:

4.使用ServletActionContext访问Servlet API

ServletActionContext工具类可直接访问Servlet API,工具类方法如下:

PageContext getPageContext():获取PageContext对象HttpServletRequest getRequest():获取HttpServletRequest对象HttpServletResponse getResponse():获取HttpServletResponse对象ServletContext getServletContext():获取ServletContext对象
配置Action

实现了Action处理类后,就需要在struts.xml中对Action进行配置了。

1.包和命名空间

struts2使用包来组织Action,定义Action通过使用<package> 下的<action>子元素来完成。每个package元素配置一个包,每个包是多个Action、多个拦截器、多个拦截器引用的集合。

package元素属性

name:必须属性,该属性指定了该包的名字,需要唯一,该名字是该包被其他包引用的keyextends:可选属性,该属性指定该包继承其他包的名称,可继承Action和拦截器namespace:可选属性,该属性指定该包的命名空间abstract:可选属性,指定该包是否是抽象包,不能包含Action定义

举个例子,如下图:

(1)第一个package继承的struts-default,是定义在struts2-core.jar中的抽象包,包含了(2)大量的结果类型定义、拦截器定义、拦截器引用定义

当某个包指定了命名空间后,该包下的所有Action处理的URL是命名空间+Action名;如果未指定命名空间,则为默认的命名空间

(3)用namespace="/"来指定根命名空间,默认命名空间会处理未在指定命名空间下找到的Action请求,而根命名空间只会处理在根命名空间下的Action请求

2.Action的基本配置

name:该属性既是Action的名称,也指定了Action所处理的请求的URLclass:指定了Action的处理类

如下图:

配置Action时需同时配置逻辑视图和物理视图的对应关系,通过<result>

<action name="index">    <result name="success" type="dispatcher">/admin/main.jsp</result></action>

3. 使用Action的动态方法调用

有时我们需要使用Action的不同方法来处理不同的用户请求,此时可以采用动态方法调用来处理请求

使用动态方法调用前必须设置struts.enable.DynamicMethodInvocation=true来开启

4.指定method属性

如果在配置<action>元素时,可以指定method属性,让action调用指定方法,而不是execute方法来处理用户请求。通过这种方式可以将一个action类定义成多个逻辑action,即Action类的每个处理方法都映射成一个逻辑Action。

<action name="login" class="org.LoginAction" method="login"></action>

5.配置默认Action

当用户请求找不到对应Action时,系统默认的Action将处理用户请求。如下图:

将默认Action配置在默认命名空间里就可以让Action处理所有用户请求,因为默认命名空间的Action可以处理任何命名空间的请求

6.配置Action默认处理类

配置<action>元素时可以不指定class属性,如果没有指定class属性,则系统默认使用ActionSupport作为Action处理类。Struts2允许定义开发者自己配置Action默认处理类,如下:

<package name="">    <default-class-ref class="Action默认处理类"/></package>
配置处理结果

1.处理结果解析

Action处理完用户请求后,将返回一个普通字符串,这个普通字符串就是一个逻辑试图名,struts2通过配置逻辑试图名和物理试图名之间的映射关系,一旦系统收到Action返回的某个逻辑试图名,系统就会把对应的物理视图呈现给浏览者。

2.配置结果

Struts2在struts.xml文件中使用<result>元素来配置结果,根据元素所在的位置不同,提供了两种结果。

局部结果:将<result>作为<action>元素的子元素配置全局结果:将<result>作为<global-results>元素的子元素配置

配置<result>元素有两个属性:

name:指定所配置的逻辑试图名,默认值为successtype:指定结果类型,默认值为dispatcher

3.Struts2支持的结果类型

chain:Action链式处理的结果类型dispatcher:用于指定使用JSP作为视图的结果类型redirect:用于直接跳转到其他URL的结果类型redirectAction:用于直接跳转到其他Action的结果类型stream:用于向浏览器返回一个InputStreamxslt:用于与XML/XSLT整合的结果类型plainText:用于显示某个页面的原始代码的结果类型

4.全局结果

当在<global-results>元素中配置<result>元素时,该元素配置了一个全局结果,全局结果将对所有Action有效。如下图:

如果一个Action里包含了与全局结果同名的结果,则Action里的局部Result会覆盖全局Result

5.使用PreResultListener

PreResultListener是一个监听器接口,它可以在Action完成控制处理之后,系统转入实际的物理视图之间被回调。如下如粗体:

争议与思考

Struts2作为一个MVC框架,已逐渐在国内互联网公司失宠,很多人认为它跟SpringMVC比起来有很多缺点。Struts2还有优势吗?你还会使用吗?在评论区留下你的观点吧!

标签: #struts2 chain