Struts2 基础入门

什么是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.jarStruts2 框架的核心类库
xwork-core-2.3.37.jarWeb Work 核心库,Struts2 的构建基础
ognl-3.0.6.jar对象图导航语言(Object Graph Navigation Language),Struts2 框架通过其读/写对象的属性
freemarker-2.3.22.jarStruts2 标签模板使用的类库
javassist-3.11.0.GA.jarJavaScript 字节码解释器
commons-fileupload-1.4.jarStruts2 文件上传组件依赖包
commons-io-2.2.jarStruts2 的输入/输出,传文件依赖的 JAR
commons-lang-2.4.jar包含一些数据类型工具,是对 java.lang 包的增强
log4j-api-2.2.jarStruts2 的日志管理组件依赖包的 API
log4j-core-2.2.jarStruts2 的日志管理组件依赖包

从上表中可以看出,此版本的 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

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值