什么是Struts2

Struts2 是 Apache 软件组织推出的一个基于 MVC 模式的轻量级 Web 框架,自问世以来,就受到了广大 Web 开发者的欢迎。目前,Struts2 在 Java Web 开发领域中已占据了十分重要的地位。

目前为止,Struts 框架拥有两个主要版本:Struts1.x 和 Struts2.x。Struts1 是最早的基于 MVC 模式的轻量级 Web 框架,它能够合理划分代码结构,并包含验证框架、国际化框架等多种实用工具框架。

随着技术的不断进步,Struts1 的局限性也越来越多地暴露出来。为了符合更加灵活、高效的开发需求,Struts2 框架应运而生,并在逐渐取代 Struts1 框架。

Struts2 是在 Struts1 和 WebWork 技术(WebWork 是由 OpenSymphony 组织开发的、致力于组件化和代码重用的 J2EE Web 框架,它也是一个 MVC 框架)的基础上进行合并后的全新框架。

虽然 Struts2 的名字与 Struts1 相似,但其设计思想有很大不同,因为 Struts2 是以 WebWork 为核心的,它是 WebWork 技术与 Struts1 技术的结合,所以 Struts2 可以理解为 WebWork 的更新产品。

Struts2 拥有优良的设计和功能,其优势具体如下。

  • 项目开源,使用及拓展方便。
  • 通过简单、集中的配置调度业务类,使配置和修改都非常容易。
  • 提供简单、统一的表达式语言访问所有可供访问的数据。
  • 提供标准、强大的验证框架和国际化框架。
  • 提供强大、可以有效减少页面代码的标签。
  • 提供 Exception 处理机制,并且具有良好的 Ajax 支持。
  • Result 方式的页面导航,通过 Result 标签很方便地实现重定向和页面跳转。
  • 拥有智能的默认设置,不需要另外进行繁琐的设置。使用默认设置就可以完成大多数项目程序开发所需要的功能。


简单说Struts2 的作用就是通过过滤器拦截请求匹配action中对应的方法,并返回对应的结果。

Struts2目录结构和基础JAR包介绍

Struts2 的官方下载网址为 http://struts.apache.org,在该网址中可以下载最新版本的 Struts2。我们使用的 Struts2 版本为 2.3.37。

下载成功后,将 struts-2.3.37-all.zip 压缩包进行解压,解压后的目录如图所示。

Struts2 的目录介绍

名称 作用
apps 用于存放官方提供的 Struts2 示例程序,这些程序可以作为学习者的参考资料。各示例均为 war 文件,可以通过 zip 方式进行解压。
docs 用于存放官方提供的 Struts2 文档,包括 Struts2 的快速入门、Struts2 的文档,以及 API 文档等内容。
lib 用于存放 Struts2 的核心类库,以及 Struts2 的第三方插件类库。
src 用于存放该版本 Struts2 框架对应的源代码。

了解了 Struts2 的文件夹结构后,下面学习一下如何在项目中使用 Struts2 框架。将图 1 中的 lib 文件夹打开,可以看到 Struts2 开发中可能用到的所有 JAR 包(此版本有 106 个 JAR 包)。在一般的 Web 开发中,只需要将 lib 文件夹下所依赖的几个基础 JAR 包复制到 Web 项目的 WEB-INF/lib 路径下即可使用 Struts2 框架。

Struts2 项目所依赖的基础 JAR 包进

文件名 说 明
asm-3.3.jar 操作 Java 字节码的类库
asm-commons-3.3.jar 提供了基于事件的表现形式
asm-tree-3.3.jar 提供了基于对象的表现形式
struts2-core-2.3.37.jar Struts2 框架的核心类库
xwork-core-2.3.37.jar Web Work 核心库,Struts2 的构建基础
ognl-3.0.6.jar 对象图导航语言(Object Graph Navigation Language),Struts2 框架通过其读/写对象的属性
freemarker-2.3.22.jar Struts2 标签模板使用的类库
javassist-3.11.0.GA.jar JavaScript 字节码解释器
commons-fileupload-1.4.jar Struts2 文件上传组件依赖包
commons-io-2.2.jar Struts2 的输入/输出,传文件依赖的 JAR
commons-lang-2.4.jar 包含一些数据类型工具,是对 java.lang 包的增强
log4j-api-2.2.jar Struts2 的日志管理组件依赖包的 API
log4j-core-2.2.jar Struts2 的日志管理组件依赖包

从上表中可以看出,此版本的 Struts2 项目所依赖的基础 JAR 包共 13 个。Struts2 根据版本的不同所依赖的基础 JAR 包可能不完全相同,不过基本变化不大,我们可以视情况而定。

快速添加 Struts2 所需的 JAR 包

在 apps 目录下,找到 struts2-blank.war 文件,此文件是 Struts2 官方提供的一个空示例项目,里面包含了一些基础 JAR 包和一些 xml 配置文件。开发中为了方便快速地使用 Struts2 进行开发,我们可将此文件的扩展名改为 zip(即 struts2-blank.zip),然后以压缩包方式解压打开。

将 WEB-INF/lib 文件夹下所有的 JAR 文件复制添加到自己所建立的 Web 应用程序的 WEB-INF/lib 中,即完成了 Struts2 的添加工作,这些 JAR 文件刚好就是 Struts2 所依赖的基础包。

第一个Struts2程序

使用 Struts2 框架实现一个 HelloWorld 程序。

创建项目

在 MyEclipse 中新建一个名为 struts2Demo01 的 Web 项目,将 Struts2 框架依赖的基础 JAR 包复制到此项目的 WEB-INF/lib 路径中,然后选中所有 JAR 并右击,进行 Build Path→Add to Build Path 操作(此时所选 JAR 包会被添加到项目的 classpath 中),添加后的项目结构如下所示。

配置 Struts2 的核心过滤器 web.xml

打开项目的 web.xml 文件,在文件中添加 Struts2 的核心过滤器 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,具体如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"id="WebApp_ID" version="3.0"><!-- 配置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>
</web-app>

在 web.xml 文件中, 标签中配置的信息就是 Struts2 的核心过滤器,该过滤器的名称为 struts2,过滤器类为 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter,而 标签中配置的是该过滤器的映射。

需要注意的是,在 Struts2.1 版本之前,所使用的核心过滤器类是 org.apache.struts2.dispatcher.FilterDispatcher,从 Struts2.1 版本之后,这个过滤器类已经不推荐使用了,而是使用 org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter 类。

如果你觉得上边配置 Struts2 核心控制器麻烦,下边讲解一个快捷配置 Struts2 的核心过滤器的方法。

从上述 Web.xml 文件中可以看出,Struts2 的核心过滤器名称很长,如果手写的话,则很容易出现错误。为此,这里教读者一个快速添加 Struts2 核心过滤器的方法。

在快捷导入基础 JAR 包时解压的 struts2-blank 文件夹中,打开 WEB-INF/web.xml 文件,即可找到上述 Web.xml 中 Struts2 的核心过滤器配置的代码,将配置代码复制到自己 Web 应用程序的 web.xml 文件中,就省去了自己手动编写的麻烦。

创建 Action 类

在项目的 src 目录下,新建一个名称为 com.mengma.action 的包,在包中创建一个名为 HelloWorldAction 的类,并使其继承 ActionSupport 类(Struts2 框架所提供的类)。在 HelloWorldAction 类中定义一个 execute() 方法,返回值为 SUCCESS,编辑后的代码如下所示。

package com.mengma.action;
import com.opensymphony.xwork2.ActionSupport;
public class HelloWorldAction extends ActionSupport {public String execute() throws Exception {return SUCCESS;}
}

在上述 HelloWorldAction.java 中,execute() 方法的返回值 SUCCESS 是从父类中继承的常量字段,用于表示执行成功,并返回结果页面。

execute() 方法的返回值对应 struts.xml 文件中 标签中 name 属性的值,Struts2 框架会根据 name 属性值执行对应处理结果下的视图资源。

编写 Struts2 的配置文件 struts.xml

在 src 目录下新建一个名称为 struts.xml 的文件,编辑代码后如下所示。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 指定 Struts2 配置文件的 DTD 信息 -->
<!DOCTYPE struts PUBLIC"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN""http://struts.apache.org/dtds/struts-2.3.dtd">
<!-- Struts2配置文件的根元素 -->
<struts><!-- Struts2的Action必须放在指定的包空间下定义 --><package name="hello" namespace="/" extends="struts-default"><!-- 定义 action,该 action 对应的类为 com.mengma.action.HelloWorldAction 类--><action name="helloWorld" class="com.mengma.action.HelloWorldAction"><!-- 定义处理结果和视图资源之间的映射关系 --><result name="success">/success.jsp</result></action></package>
</struts>

在 struts.xml 文件中, 标签中定义了请求路径,以及与其对应的 Action 类的映射关系,子标签 定义了处理结果和视图资源之间的映射关系。

关于 struts.xml 文件的详细配置信息,后面的教程中会进行重点讲解,此处读者可不必关心其细节问题。

在 Struts2 的配置文件需要编写的内容有很多。尤其是文件上面的 dtd 信息,如果手动编写的话十分容易出错。同样的,在解压的 struts2-blank 文件夹中,将 WEB-INF/classes 目录下的 struts.xml 文件复制到自己所建立的 Web 项目的 src 目录下,然后在此基础上进行修改和配置即可。

创建视图首页文件 index.jsp

在 WebContent 目录下创建一个名称为 index.jsp 的页面文件,在其中编写一个超链接,用于访问 Action 对象,此链接指向的地址为 helloWorld.action,如下所示。

<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>首页</title>
</head>
<body><a href="${pageContext.request.contextPath }/helloWorld.action">第一个 Struts2 程序!</a>
</body>
</html>

创建返回页面

在 WebContent 下再创建一个名称为 success.jsp 的文件,作为 Action 对象处理成功后的返回页面,如下所示。

<%@ page language="java" contentType="text/html; charset=utf-8"pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head><title>成功页面</title>
</head>
<body>您的第一个小程序执行成功,欢迎来到Struts2的世界!
</body>
</html>

启动项目并查看结果

将项目 struts2Demo01 发布到 Tomcat 服务器后启动服务器,在浏览器的地址栏中输入地址 http://localhost:8080/struts2Demo01/index.jsp 后,浏览器的显示结果如图下所示。

单击图 2 中的超链接后,浏览器会发送一个以 helloWorld.action 为结尾的请求,此时浏览器的显示结果如图下所示。


从上图的显示结果中可以看出,程序顺利返回到了 success.jsp 页面,这说明 Struts2 入门案例执行成功。

上面所讲解的 Struts2 入门程序,实际上就是一个请求发出到响应结束的过程,为了更直观地了解该案例的执行全过程,下面通过简单的执行流程图进行说明,如图下所示。

从下图可以看出

  • 在客户端浏览器上单击 index.jsp 中的超链接时,会发送一个 helloWorld.action 请求;
  • 该请求被核心过滤器拦截后,会通过 struts.xml 文件中的配置找到请求对应的 HelloWorldAction,并默认调用 HelloWorldAction 中的 execute() 方法返回逻辑视图名;
  • 然后再通过配置文件找到并转发给对应的视图页面 success.jsp 中,最后生成响应内容并输出响应的返回结果。

Struts2处理用户请求的完整流程

从上图所示的流程图中可以看出,一个请求在 Struts2 框架中的处理大概可以分为以下几个步骤。

1)首先客户端浏览器发送一个请求(HttpServletRequest)。

2)接着程序会调用 StrutsPrepareAndExecuteFilter,然后询问 ActionMapper 这个请求是否需要调用某个 Action。

3)如果 ActionMapper 决定需要调用某个 Action,StrutsPrepareAndExecuteFilter 会把请求的处理交给 ActionProxy。

4)ActionProxy 通过配置管理器(Configuration Manager)从配置文件(struts.xml)中读取框架的配置信息,从而找到需要调用的 Action 类。

5)ActionProxy 会创建一个 ActionInvocation 的实例。

6)ActionInvocation 使用命名模式调用 Action,在调用 Action 前,会依次调用所有配置的拦截器(Intercepter1、Intercepter2……)。

7)一旦 Action 执行完,则返回结果字符串,ActionInvocation 就会负责查找结果字符串对应的 Result,然后执行这个 Result。通常情况下 Result 会调用一些模板(JSP 等)呈现页面。

8)产生的 Result 信息返回给 ActionInvocation,在此过程中拦截器会被再次执行(顺序与 Action 执行之前相反)。

9)最后产生一个 HttpServletResponse 的响应行为,通过 StrutsPrepareAndExecuteFilter 反馈给客户端。

获取表单数据

创建form表单页面,放在webcontnet下面

在struts2中配置文件

action中的HttpServletRequest 的方式获取前端传输的值

Action是如何接受请求参数的?

属性驱动和模型驱动

Struts2内部提供了参数封装功能,不需要使用BeanUtils进行封装。Struts2大部分内置功能都是拦截器实现的。

当点击登录提交表单时,就会被下面的拦截器进行封装,进行set注入值,实现参数封装。

<interceptor name="params"
class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

第一种 :Action 本身作为model对象,通过成员setter封装 (属性驱动 )

主要用于参数较少的封装,如果分层,不利于将数据传递到业务层。

页面:

用户名:<input type="text" name="username" /> <br/>

Action:

public class RegistAction1 extends ActionSupport {private String username;public void setUsername(String username) {this.username = username;}
}

Struts2 action是多实例,不会有线程安全问题,使用这种数据封装方式,数据封装到action属性中,不能将action对象传递给业务层,我们需要再单独定义javabean,将action属性封装到javabean。

第二种 :创建独立model对象,页面通过ognl表达式封装 (属性驱动)

具体封装流程如下:传递username,调用setUsername,把username注入User中,将会新建一个User对象,当第二个参数password传递过来时,struts框架将首先调用getUser方法询问User是否为空,如果为空,将会新建一个User,否则不会新建,直接注入值。如果只有一个Set方法,那么每set一次数据,就会新建一个User对象,那么就是把username、password封装在两个不同的User对象中了。这样封装失败。

<!--基于OGNL表达式的写法-->用户名:<input type="text" name="user.username" /> <br/>密  码:<input type="password" name="user.password" /> <br/>

model(User):


public class User {private String username;private String password;
}

由params的拦截器完成参数的封装

<interceptor name="params"class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

第三种 :使用ModelDriven接口,对请求数据进行封装 (模型驱动 ) ----- 企业开发的主流(模型驱动有很多特性)

<interceptor name="modelDriven"
class="com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor"/>

为模型驱动提供了更多特性

页面:

用户名:<input type="text" name="username" /> <br/>

model(User):
Action :

public class RegistAction3 extends ActionSupport implements ModelDriven<User> {// 模型对象必须手动实例化private User user = new User();public User getModel() {return user;}}

对比第二种、第三种 : 第三种只能在Action中指定一个model对象(返回一个model对象),第二种可以在Action中定义多个model对象

<input type="text" name="user.username" /> <input type="text" name="product.info" />

书写Action的时候有哪几种方式?有什么区别?

有三种方式:

①普通POJO(简单Java对象),这种方式我们不需要继承任何父类,实现任何接口。Struts2框架读取struts.xml文件,获得完整的action类名。

obj = Class.forName("完整类名").newInstance();
Method m = Class.forName("完整类名").getMethod("execute");
m.invoke(obj); //通过反射 执行execute()方法

②编写Action实现Action接口

Action接口中,定义默认五种 逻辑视图名称

// 数据处理成功 (成功页面)
public static final String SUCCESS = "success";// 页面不跳转 return null; 效果一样
public static final String NONE = "none";// 数据处理发送错误 (错误页面)
public static final String ERROR = "error";// 用户输入数据有误,通常用于表单数据校验 (输入页面)
public static final String INPUT = "input";// 主要权限认证 (登陆页面)
public static final String LOGIN = "login";

③编写Action继承ActionSupport(推荐)

在Action中使用表单校验、错误信息设置、读取国际化信息三个功能

代理模式,控制目标对象访问,hello.action 请求时 StrutsPrepareAndExecuteFilter的 doFilter一定执行

//判断配置文件中有没有对应Action
ActionMapping mapping = prepare.findActionMapping(request, response, true);
//根据配置创建代理对象
ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(namespace, name, method, extraContext, true, false);

执行时:先执行interceptor的intercept拦截方法, 最后指向action的execute

Struts2 基础入门相关推荐

  1. 最详细Struts2基础入门

    struts2 1 框架概述 1.1什么是框架 1.2 三大框架 1.3 三层架构 1.4 MVC回顾 2 Struts简介 2.1 Struts2概述 2.2 Struts2的来历 3 Struts ...

  2. (转)Struts2快速入门

    http://blog.csdn.net/yerenyuan_pku/article/details/66187307 Struts2框架的概述 Struts2是一种基于MVC模式的轻量级Web框架, ...

  3. 网络安全之基础入门(一)

    前言:好久没有更新了,主要看了我之前的文章,觉得有些滥竽充数,以后我尽量保证每篇文章的质量,所以更新周期可能慢一点 基础入门 壹.基础概念 域名 1.什么是域名 域名(英语:Domain Name), ...

  4. 一、SpringMVC基础入门,创建一个HelloWorld程序

    一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...

  5. 用python循环语句求素数_Python基础入门_3条件语句和迭代循环

    Python 基础入门前两篇: Python 基础入门--简介和环境配置 Python基础入门_2基础语法和变量类型 这是第三篇内容,主要简单介绍条件语句和迭代循环语句,内容也比较简单,目录如下: 条 ...

  6. MAYA 2022基础入门学习教程

    流派:电子学习| MP4 |视频:h264,1280×720 |音频:AAC,48.0 KHz 语言:英语+中英文字幕(根据原英文字幕机译更准确)|大小解压后:3.41 GB |时长:4.5小时 包含 ...

  7. Blender 3.0基础入门学习教程 Introduction to Blender 3.0

    成为Blender通才,通过这个基于项目的循序渐进课程学习所有主题的基础知识. 你会学到什么 教程获取:Blender 3.0基础入门学习教程 Introduction to Blender 3.0- ...

  8. 三维地形制作软件 World Machine 基础入门学习教程

    <World Machine课程>涵盖了你需要的一切,让你有一个坚实的基础来构建自己的高质量的电影或视频游戏地形. 你会学到什么 为渲染或游戏开发创建高分辨率.高细节的地形. 基于Worl ...

  9. SketchUp Pro 2021基础入门学习视频教程

    SketchUp Pro 2021基础入门学习视频教程 1280X720 MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 流派:电子学习|语言:英语+中文字幕( ...

  10. Maya基础入门学习教程

    Maya基础入门学习教程 视频:.MKV, 1280x720, 共57节课 时长 4小时25分钟,3GB 语言:英语+中文字幕(根据原英文字幕机译更准确)+原英文字幕 指导老师:Shane Whitt ...

最新文章

  1. 《深入理解ElasticSearch》——2.4 批量操作
  2. jdb java_JDB - 介绍
  3. pytorch转caffe
  4. Java事件处理机制和适配器
  5. GCD LCM 欧几里得算法 扩展欧几里得算法
  6. winform 实现qq代理_会一百种引流方法,还不如会用一个QQ引流群控
  7. c语言逻辑运算符编程,C语言之逻辑运算符详解
  8. oracle基本的查询语句,Oracle基本查询语句
  9. scala 字段覆盖_Scala中的字段覆盖
  10. 1000道Python题库系列分享一(17道)
  11. mysql+复制诊断_诊断Mysql复制问题
  12. 我的电脑已经禁ping,应该如何启用该功能?
  13. java中utilities类_Java SwingUtilities类
  14. 经典特别好用的局域网传输文件聊天工具飞秋和飞鸽传书
  15. 进程上下文切换 – 残酷的性能杀手(上)
  16. 如何在D盘以管理员身份,运行cmd
  17. 关闭WIN7交互式服务检测提示
  18. 12星座之追女必杀技~
  19. OpenNLP学习笔记1
  20. 分享几个免费书籍的网站

热门文章

  1. 2021-2022年中国冰雪季旅游行业发展概况及发展趋势分析[图]
  2. Kubernetes中文文档
  3. 软件开发标准(文档模板)
  4. python config方法_Python config.Configuration方法代码示例
  5. 2018年第九届蓝桥杯真题C/C++B组
  6. 手把手教你使用VGG19做图像风格迁移
  7. 拆解一探电路设计:小米路由器3C拆解
  8. 泛函分析 04.02 有界线性算子 - 有界线性算子空间的收敛与完备性
  9. 吊打面试官了解一下?2021年字节跳动春招面试题详解(附详细答案)
  10. diabetes影响因子2017_DIABETES