快盘下载:好资源、好软件、快快下载吧!

快盘排行|快盘最新

当前位置:首页软件教程电脑软件教程 → Java EE实用教程笔记----(2)第二章 Struts 2基础

Java EE实用教程笔记----(2)第二章 Struts 2基础

时间:2022-09-15 19:50:41人气:作者:快盘下载我要评论

好了,今天开始第二章,O(∩_∩)O哈哈~,今天这一章主要讲Struts 2的运行环境和原理,及工作流程,后面长长的文章就当是看API把,哈哈。

第一部分 Struts 2框架开发入门

2.1.1 MVC基本思想

MVC把应用程序分成3大基本模块:模型(Model,即M)、视图(View,即V)和控制器(Controller,即C),它们(三者联合即MVC)分别担当不同的任务。下图显示了这几个模块各自的职能及相互关系。

Java EE实用教程笔记----(2)第二章 Struts 2基础

传统的Java EE开发采用JSP+Servlet+JavaBean的方式来实现MVC(如【实例1.1】),但它有一个缺陷:程序员在编写程序时必须继承HttpServlet类、覆盖doGet()和doPost()方法,严格遵守Servlet代码规范编写程序,形如:

有些代码跟程序无关,但还是必须要程序员实现接口(比如Servlet的API,这就很烦了,其实这些代码每个Servlet都要写,还没实际逻辑),为了屏蔽这种不必要的复杂性,减少工作量,可以用Struts 2框架,哈哈.

用Struts 2实现的MVC系统与传统的用Servlet编写的MVC系统相比,两者在结构上的区别如下图所示。

Servlet

可见,其区别是:用Struts 2框架代替Servlet的部分作为控制器,业务处理则由用户自定义的Action去实现,与Struts2的控制核心相分离,降低了系统中各部分组件的耦合度,和编程难度.

2.1.3 简单Struts 2开发

其实之前我们有个简单的Servlet开发的项目,后续也会用到,我会把这个项目传到gitee上.

1.加载Struts 2包

登录http://struts.apache.org/,下载Struts 2,本书使用的是Struts 2.5.13,其官方下载页面如图:将下载的文件struts-2.3.16.3-all.zip解压缩,得到文件夹包含的目录结构如图2.3所示,这是一个典型的Web结构。

XML

大部分的时候,使用Struts 2的Java EE应用并不需要用到Struts 2的全部特性,开发Struts 2程序只需用到lib下的9个jar包,包括:

(1)传统Struts 2的5个基本类库。

struts2-core-2.5.13.jar

ognl-3.1.15.jar

log4j-api-2.8.2.jar

freemarker-2.3.23.jar

(2)附加的4个库。

commons-io-2.5.jar

commons-lang3-3.6.jar

javassist-3.20.0-GA.jar

commons-fileupload-1.3.3.jar

将它们一起复制到项目的WebRootWEB-INFlib路径下,右击项目名,从弹出菜单中选择“Refresh”按钮刷新即可,加载成功的项目工程目录树如图2.4所示。

其中,主要类描述如下。

struts2-core-2.5.13.jar:Struts 2.5的主框架类库。

ognl-3.1.15.jar:OGNL表达式语言。

log4j-api-2.8.2.jar:管理程序运行日志的API接口。

freemarker-2.3.23.jar:所有的UI标记模板。

2.2.1 Struts 2工作原理

XML

长话短说:

(1)客户端提交一个(HttpServletRequest)请求。

(2)请求被提交到一系列(主要是3层)的过滤器(Filter),如(ActionContextCleanUp、其他过滤器、FilterDispatcher)。

(3)FilterDispatcher接收到请求后,询问ActionMapper是否需要调用某个Action来处理这个(HttpServletRequest)请求,如果ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy。

(4)ActionProxy通过Configuration Manager(struts.xml)询问框架的配置文件,找到需要调用的Action类(该Action类一般是程序员自定义的处理请求的类)。

(5)ActionProxy创建一个ActionInvocation实例,同时ActionInvocation通过代理模式调用Action。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)。

(6)一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果Result。

这是官方文档总结下来的,初学者看了肯定很头疼啊,那么下面就结合我们上面的实例来总结一个容易理解的Struts 2开发的项目的运行流程!

XML

总结其运行流程如下:

(1)浏览器请求:“http://localhost:8080/bookManage/login.jsp”,发送到web应用服务器(如Tomcat等)。

(2)容器接收到了login.action的请求,根据web.xml中的配置,服务器将包含.action后缀的请求转到"org.apache.struts2.dispatcher.FilterDispatcher“类进行处理。

(3)框架在struts.xml配置文件中查找名为"login”的action对应的类。框架初始化该Action(就是对数据进行了封装,并数据放入栈中),并且执行该Aciton类的execute方法(默认的,可以设置),该方法可以执行一些数据处理等操作,然后返回结果(广义上的结果)。

(4)框架检查配置以查看返回成功时对应的页面,框架告诉容器来获得请求返回的结果页面main.jsp。

在Struts 2框架中,Action类的调用是通过代理类ActionProxy来完成的,代理类再创建一个ActionInvocation对象,来调用程序猿自定义的Action类,但在调用之前会先加载有关的Interceptor(拦截器),而Struts 2框架就是通过一系列拦截器来工作的!

2.3 简单Struts 2开发Dome

理论讲的再好,不如上手个实际项目,通过一个Deme让我们了解下Struts2的流程控制,可能有些地方不懂,看看代码就行,后面教程会详细讲解的!

2.3.2. 配置web.xml

Struts 2框架需要在项目web.xml文件中配置,代码如下:

<?xml version="1.0" encoding="UTF-8"?>

<web-app id="WebApp_9" version="2.4"

xmlns="http://java.sun.com/xml/ns/j2ee"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

<filter>

<filter-name>struts-prepare</filter-name>

<filter-class>org.apache.struts2.dispatcher.filter.StruTSPrepareFilter</filter-class>

</filter>

<filter>

<filter-name>struts-execute</filter-name>

<filter-class>org.apache.struts2.dispatcher.filter.StrutsExecuteFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>struts-prepare</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<filter-mapping>

<filter-name>struts-execute</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

<display-name>bookManage</display-name>

<welcome-file-list>

<welcome-file>login.jsp</welcome-file>

</welcome-file-list>

</web-app>

代码加粗部分即是Struts2.5特有的。

2.3.3. 实现控制器Action

基于Struts 2框架的Java EE应用程序使用自定义的Action(控制器)来处理深层业务逻辑,完成用户想要完成的功能。本例定义名为“login”的控制器,判断登录用户名和密码的正确性。在项目src下建立包org.action,在包里创建LoginAction类,LoginAction.java代码所示:

package org.action;

import java.util.*;

import org.model.*;

import org.dao.*;

import com.opensymphony.xwork2.*;

public class LoginAction extends ActionSupport{

private Login login;

//处理用户请求的 execute 方法

public String execute() throws Exception{

//该类为项目与数据的接口(DAO接口),用于处理数据与数据库表的一些操作

LoginDao loginDao = new LoginDao();

Login l = loginDao.checkLogin(login.getName(), login.getPassword());

if(l!=null){ //如果登录成功

//获得会话,用来保存当前登录用户的信息

Map session = ActionContext.getContext().getSession();

session.put("login", l); //把获取的对象保存在 Session 中

return SUCCESS;//验证成功返回字符串SUCCESS(此时 Session 中已有用户对象)

}else{

return ERROR; //验证失败返回字符串ERROR

}

}

//属性 login 的 get/set 方法,记住这里

public Login getLogin() {

return login;

}

public void setLogin(Login login) {

this.login = login;

}

}

2.3.4. 配置struts.xml

在编写好Action(控制器)的代码之后,还需要进行配置才能让Struts 2识别Action。在src下创建文件struts.xml(注意文件位置和大小写),输入如下的配置代码:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE struts PUBLIC

"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

"http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>

<package name="default" extends="struts-default">

<!-- 用户登录 -->

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

<result name="success">/main.jsp</result>

<result name="error">/error.jsp</result>

</action>

</package>

<constant name="struts.i18n.encoding" value="gb2312"></constant>

</struts>

struts.xml一定不要弄错地方哦:

Java

2.3.5. 编写JSP

本例login.jsp(登录页)、main.jsp(欢迎主页)这两个JSP文件均使用Struts 2的标签进行了重新改写。登录页login.jsp,代码为:

<%@ page language="java" pageEncoding="gb2312"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

<html>

<head>

<title>图书管理系统</title>

</head>

<body bgcolor="#71CABF">

<s:form action="login" method="post" theme="simple">

<table>

<caption>用户登录</caption>

<tr>

<td>登录名<s:textfield name="login.name" size="20"/></td>

</tr>

<tr>

<td>密  码<s:password name="login.password" size="21"/></td>

</tr>

<tr>

<td>

<s:submit value="登录"/>

<s:reset value="重置"/>

</td>

</tr>

</table>

</s:form>

</body>

</html>

欢迎主页main.jsp,代码如下:

<%@ page language="java" pageEncoding="gb2312"%>

<%@ taglib prefix="s" uri="/struts-tags"%>

<html>

<head>

<title>欢迎使用</title>

</head>

<body>

<s:set name="login" value="#session['login']"/>

<s:property value="#login.name"/>,您好!欢迎使用图书管理系统。

</body>

</html>

好了,这里我们运行,效果图还是和上一篇文章的一样,这个Demo只是让我们认识一下Struts2的工作流程,下面我们会详细讲解Struts2的配置,也是对这个Demo的问题释疑!因为下面要写的东西很多(虽然很枯燥,但是要好好看哦,下一章很重要的),这样也让大家对Struts2更加了解!

第二部分 Struts 2基础

2.3 Struts2的控制器Action类

2.3.1 使用ActionSupport

Struts2的核心功能就是Action。对于开发人员来说,使用Struts2框架,主要编码工作就是编写Action类。一般情况下我们的Action类都会继承这个ActionSupport类,ActionSupport类实现了5个接口:

1.Action接口 实现了5个常量及一个execute()方法,如下:

Linux

如果Action类继承了ActionSupport类,就可以直接应用这几个常量,比如在【我们前面的实例】中的Action代码:

XML

2.Validateable接口:该接口提供了一个validate()方法用于校验表单数据,在实际应用中只要在Action类中重写该方法即可,该方法是在执行execute()方法之前执行的

3.ValidationAware接口:该接口定义了一些方法用来对Action执行过程中产生的信息进行处理。例如,该接口中提供了addFieldError(String fieldname,String errorMessage)方法用来在验证出错时保存错误信息。

4.TextProvider接口:该接口中提供了一系列getText()方法可以用key来获得相应的value值,用于获得对应的国际化信息资源。

5.LocaleProvider接口:该接口提供了一个getLocale()方法,用于国际化时获得语言/地区信息。

2.3.2 使用Action传值

Action可以通过其属性获取页面上表单文本框中用户输入的值,在运行login.jsp时候,Struts2框架会根据页面的文本框名(代码:<s:textfield name="name" size="20"/>)在Action类中寻找其set方法(setName)来进行赋值,这叫字段传值代码如下:

但是如果字段比较多的话,就需要在Action中写很多属性,增加了代码的耦合性,非常麻烦也,这个时候可以用模型传值的方法,要把字段封装成一个类,并生成其get和set方法,就是通常说的JavaBean了。因【实例】的项目中已编写好了JavaBean类Login.java,须在Action中改变写法:

XML

而且在前端页面中也要改变用法,改为“模型对象名.属性名”:<s:textfield name="login.name" size="20"/>

注意:在实际项目开发中,当项目的“.java文件-需重新编译”或者一些配置文件如 “.xml文件-需框架重新读”经过修改后,一定要重启Tomcat服务器才会生效,而前端页面“login.jsp”则刷新页面即可。

2.3.3 Action访问ServletAPI

Struts2中没有与任何的ServletAPI相关联,这样大大降低了程序的耦合性,但是有时候我们的程序必须要用这些:如“request、response、application、session”等,为此,Struts2提供了两种方法访问ServletAPI:

1.通过ActionContext

ActionContext类提供了一个静态的getContext()方法来获得ActionContext对象,然后根据其对象来获得一些Servlet API的对象。例如:

XML

由于“request”和“response”比较特殊,也是在开发中经常会用到的,所以Struts 2提供了专门的类来获取,即“ServletActionContext”:

Servlet

2.通过实现*Aware接口

Java

例如,要获得Application对象,Action类就可以编写如下:

Struts

2.3.3 Action返回结果

在一个Action类中,有时会返回多个结果,如判断一件事情,如果为真就返回SUCCESS,否则返回ERROR(或"error")。在【实例】中,对DAO接口执行checkLogin()方法获取到Login对象l的值进行判断,然后返回不同结果:

XML

这里判断l对象不为空(数据库中有这个用户信息)就返回成功,然后根据配置文件的返回跳转到欢迎页面,如果l为空则返回出错页面,所以还要在struts.xml文件中配置两种不同的返回结果跳转到的页面,如下:

XML

2.3.3 在Action中定义多方法

如果程序中功能越来越多,那就要定义越来越多的Action类,所以一般不采取这样的方式,而是把相关的功能定义在同一个Action类中,用多个方法来实现不同的功能。例如,在LoginAction类中定义两个方法:

XML

2.4 解密Struts 2框架的程序文件

2.4.1 web.xml文件

所有过滤器必须实现java.Serlvet.Filter接口,这个接口中含有3个过滤器类必须实现的方法:

init(FilterConfig):这是Servlet过滤器的初始化方法。

doFilter(ServletRequest,ServletResponse,FilterChain):这个方法完成实际的过滤操作。FilterChain参数用于访问过滤器链上的下一个过滤器。

destroy():Servlet容器在销毁过滤器实例前调用该方法。

过滤器类编写完成后,必须在web.xml中进行配置,格式如下:

Java

过滤器的关联方式有3种:与一个URL关联、与一个URL目录下的所有资源关联、与一个Servlet关联。

Java

2.4.2 struts.xml文件

Struts 2.5.13版本下的struts.xml的大体格式如下:

Linux

几个常用的子标签:

include:用于导入其他xml配置文件。

Servlet

constant:配置一些常量信息。

Java

package:配置包信息。

bean:由容器创建并注入的组件。

2.4.3 struts.properties文件

该文件用于用户单独需要更改的默认设置之类的,放在src/下,Struts框架会默认加载该文件,一些常用配置:

Servlet

2.5 Struts 2配置详解

一个简单的struts.xml文件解析图:

Struts

2.5.1 <action>配置详解

name:该属性是必需的,对应请求的Action的名称

class:该属性不是必需的,指明处理类的具体路径,如“org.action.LoginAction”。

method:该属性不是必需的,若Action类中有不同的方法,该属性指定请求对应应用哪个方法。

converter:该属性不是必需的,指定Action使用的类型转换器(类型转换内容会在类型转换部分讲解)。

在一般情况下,都会为<action>设置name和class属性,如果没有设置method属性,系统会默认调用Action类中的execute方法。若在Action中存在多个方法,请求其某个方法的时候就要通过这里的method属性来指定所请求的方法名。例如在2.3.1节中的第5点的Action类中有execute和regist两个方法,如果要在请求中应用regist方法,就要在相应的action中配置method属性:

XML

2.在<action>中应用通配符

Linux

这个*的意思就相当于定义变量,{1}就是使用变量,form中的action传递的参数就给了*。所以传入regist就是*为regist,而{1}就是使用了*,所以{1}也为regist。不仅方法可以使用通配符这样匹配,返回的值也可以。例如,如果应用regist方法返回“error”时就跳转到“regist.jsp”界面。<action>配置修改为:

XML

使用通配符可以很大程度地减少struts.xml的配置内容,但是可以发现,在编写时也会对Action类中的方法命名有限制,必须和请求名称对应,返回视图的名称也同样要对应。比如上面例子的意思就是:传入regist.action的请求,则会交给org.action.LoginAction类中的regist方法来处理,如果返回error,则进入regist.jsp页面。

3.访问Action类中方法的其他方式

仍以前面的LoginAction为例,<action>配置可以用正常情况,只需配置name和class(会有默认对应的方法execute):

Struts

这样配置完全不知道要访问LoginAction类中的哪个方法,但是可以在请求中指明,请求的form表单要改为:

Linux

其中,“login!regist.action”中“!”前面的“login”对应<action>中name属性值,“!”后面的“regist”对应要使用的LoginAction类中的方法名。

该方法是在请求中指定应用Action类中的哪个方法,还有一种办法是在提交按钮中设置的,<action>不用做任何改变,不过提交按钮需要用Struts 2的标签来实现,并且指定method:

4.使用默认类

<action>中如果未指明class属性,则系统将会自动引用<default-class-ref>标签中所指定的类,即默认类。在Struts 2中,系统默认类为ActionSupport,当然也可以自己定义默认类,例如:

Servlet

若<action>中指定了自己的class属性,则上面定义的默认类在该<action>中将不起作用。

2.5.2 <result>配置详解

<result>是为Action类的返回值指定跳转方向的,在Struts 2框架中,一个完整的<result>配置为:

Servlet

<result>包含两个属性name和type。name属性与Action类中返回的值进行匹配,type属性指定了将要跳转的结果类型,在实际应用中不一定都要跳转到一个页面,有可能会从一个action跳转到另一个action,这时就要指定type属性。<param>是为返回结果设置参数的。

Struts 2中支持多种结果类型如下:

Linux

1.dispatcher类型--转发:属于同一请求,可以传递参数,浏览器地址栏不变化。

定义该类型时,物理视图为JSP页面,并且该JSP页面必须和请求信息处于同一个Web应用中。还有一点值得注意的是,请求转发时地址栏不会改变,也就是说,属于同一请求,所以请求参数及请求属性等数据不会丢失,该跳转类似于JSP中的“forward”。从前面的例子中也可以看出,跳转到“main.jsp”页面后,仍可以取出“name”的值。在应用该类型时,一般都会省略不写。配置该类型后,<result>可以指定以下两个参数:

location:指定请求处理完成后跳转的地址,如“/main.jsp”。

parse:指定是否允许在location参数值中使用表达式,如“/main.jsp?name=${name}”,在实际运行时,这个结果信息会替换为用户输入的“name”值,该参数默认值是true。

2.redirect类型--重定向:不同请求,不可传参数,浏览器地址会发生变化。

该结果类型可以重定向到JSP页面,也可以重定向到另一个Action。该类型是与dispatcher类型相对的,当Action处理用户请求结束后,将重新生成一个请求,转入另一个界面。例如,在【实例】中,当用默认值“dispatcher”时,请求完成,转向“main.jsp”界面,如图所示。

Java

可以发现,请求没变,还是“login.action”,但页面已经跳转到“main.jsp”,并且可以取出“name”的值--注意这里仍是解释的dispatcher类型。如果把<result>中的内容改为:

<result name="success" type="redirect">main.jsp</result>

则请求完成,重定向到main.jsp欢迎主页,如图2.8所示,可以看出URL已变为“main.jsp”。

Struts

置redirect类型后,<result>也可指定location和parse两个参数。

3.redirectAction类型:也是重定向,多用于重定向到一个新的Action。

actionName:该参数指定重定向的action名。

namespace:该参数指定需要重定向的action所在的命名空间(命名空间会在后面讲解)。

Servlet

此段代码释义:有regist.action请求,由org.action.LoginAction的regist的方法处理,若返回值为success,则重定向到/test2/login.action,然后。。。。

4.chain类型

前面的redirect及redirectAction虽然都可以重定向到另外的action,但是它们都不能实现数据的传递,在重定向过程中,请求属性等都会丢失,这样有的时候就不利于编程了。chain可以跳转到另外的action而且数据不丢失,通过设置chain类型,可以组成一条action链,action跳转可以共享数据的原理是处于同一个action链的action都共享同一个值栈,每个action执行完毕后都会把数据压入值栈,如果需要就直接到值栈中取。

5.全局结果

假如都返回到同一页面,而且在不同的action请求中都会用到,那么配置局部结果就显得冗余了。所以,Struts 2提供了全局结果的配置,例如,如果返回“error”,都跳转到错误页面:

Linux

2.5.3 <package>配置详解

1.可配置的属性

(1)name属性:该属性必须指定,代表包的名称,由于struts.xml中可以定义不同的<package>,而且它们之间还可以互相引用,所以必须指定名称。

(2)extends属性:该属性是可选的,表示当前定义的包继承其他的包,继承了其他包,就可以继承其他包中的action、拦截器等。由于包信息的获取是按照配置文件中的先后顺序进行的,所以父包必须在子包之前被定义。

(3)namespace属性:该属性是可选的,用来指定一个命名空间,如在前面讲redirectAction类型时已经用到了,定义命名空间非常简单,只要指定“namespace="/*"”即可,其中“*”是我们自定的,如果直接指定“"/"”,表示设置命名空间为根命名空间。如果不指定任何namespace,则使用默认的命名空间,默认的命名空间为“" "”,也就是空。当指定了命名空间后,相应的请求也要改变,例如:

Java

而且请求就不能是“login”,而必须改为“user/login”。当Struts 2接收到请求后,会将请求信息解析为namespace名和action名两部分,然后根据namespace名在struts.xml中查找指定命名空间的包,并且在该包中寻找与action名相同的配置,如果没有找到,就到默认的命名空间中寻找与action名称相同的配置,如果再没找到,就给出错误信息。

(4)abstract属性:该属性是可选的,如果定义该包是一个抽象包,则该包不能包含<action>配置信息,但可以被继承。

2.可配置的标签

<action>:action标签,其作用前面已经详细讲解。

<default-action-ref>:配置默认action,如果配置了默认action,则若请求的action名在包中找不到与之匹配的名称就会应用默认action。

<default-interceptor-ref>:配置默认拦截器。

<default-class-ref>:配置默认类。

<global-exception-mappings>:配置发生异常时对应的视图信息,为全局信息,与之对应还有局部异常配置,局部异常配置要配置在<action>标签中,局部异常配置用<exception-mapping>进行配置:

<exception-mapping>中可以指定3个属性,分别为name:可选属性,用来标识该异常配置信息;result:该属性必须指定,指定发生异常时显示的视图信息,必须配置为逻辑视图;exception:该属性必须指定,用来指定异常类型。

下一章讲的就是Struts2的标签库了,稍微有意思了那么一丢丢,哈哈,别急,慢慢学,学的东西多了,才有能力做好玩的程序嘛,n(*≧▽≦*)n,加油↖(^ω^)↗,共勉。

写文不易,点个赞⑧。

本系列所有教程均上传至码云,链接如下:

https://gitee.com/jahero/bookManage

相关文章

  • Linux配置HTTP服务

    Linux配置HTTP服务,配置Linux初级httpd服务...
  • Linux系统上安装Zookeeper

    Linux系统上安装Zookeeper,Zookeeper的安装:第一步:安装jdk(必须先安装jdk,否则启动不成功)第二步:解压缩zookeeper压缩包第三步:将conf文件夹下zoo_sample.cfg复制一份,改名为zoo.cfg第四步:修改配置dataDir属性,指定一个真实目录(进入zookeeper解压目录,创建data目录:mkdirdata)&nbsp;&nbsp;第五步:启动zookeeper:bin/zkSe...

网友评论

快盘下载暂未开通留言功能。

关于我们| 广告联络| 联系我们| 网站帮助| 免责声明| 软件发布

Copyright 2019-2029 【快快下载吧】 版权所有 快快下载吧 | 豫ICP备10006759号公安备案:41010502004165

声明: 快快下载吧上的所有软件和资料来源于互联网,仅供学习和研究使用,请测试后自行销毁,如有侵犯你版权的,请来信指出,本站将立即改正。