学习一门新技术,最好是先看到实际的效果,所以接下来的几篇文章里,我们就来个先睹为快,看看Struts2的边边角角到底是怎么使用的,等我们有了一定的作战经验,再来透彻地分析它的运行原理。
准备就绪,咱们现在就开始问候struts2吧!
Step1:新建Web项目
用Eclipse创建一个名为strut2Demo的动态Web工程。
Step2:导入Struts 2类库
在Struts 2安装目录下的lib子目录中,有很多JAR包,不同的应用需要的JAR包是不同的。表1给出了开发Struts 2程序最少需要的JAR包。
表1 基于Struts 2的Web应用程序所需要的最少类库
文 件 名 | 说 明 |
struts2-core- 2.0.11 .jar | Struts 2框架的核心类库 |
xwork- 2.0.4 .jar | XWork类库,Struts 2在其上构建 |
ognl- 2.6.11 .jar | 对象图导航语言(Object Graph Navigation Language),Struts 2框架使用的一种表达式语言 |
freemarker- 2.3.8 .jar | Struts 2的UI标签的模板使用FreeMarker编写 |
commons-logging- 1.0.4 .jar | ASF出品的日志包,Struts 2框架使用这个日志包来支持Log4J和JDK 1.4+的日志记录。 |
Step3:在web.xml文件中配置FilterDispatcher
Struts 2框架是基于MVC模式开发的,它提供了一个核心控制器,用于对所有的请求进行统一处理,这个控制器是由一个名为FilterDispatcher的Servlet过滤器来充当的。
你需要在web.xml文件中配置FilterDispatcher过滤器,指定要映射到FilterDispatcher的URL样式,匹配这个URL样式的所有请求,都将被Web容器交由FilterDispatcher进行处理。以下为web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" 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">
<display-name>strut2(1)</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.FilterDispatcher
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
Step4:编写Action类
一个action就是一段只有特定的URL被请求时才会执行的代码。FilterDispatcher根据请求URL的不同,来执行对应的action。在Struts 2中,action执行的结果(成功或者失败)通常都对应着一个要呈现给用户的result,这个result可以是HTML页面,也可以是一个PDF文件,或者Excel电子表格。所有的result都是通过字符串名字来标识的,FilterDispatcher根据action返回的结果字符串来选择对应的result显示给用户。action与其对应的result是在一个名为struts.xml的配置文件中进行配置的,参见Step6。
在Struts 2中,可以用一个普通的Java类作为Action类,只要这个类提供如下的方法实现即可:
public String execute();
不过,通常情况下,我们所写的action类会选择实现com.opensymphony.xwork2.Action接口,在这个接口中除了定义了上述的execute()方法外,还定义了5个字符串类型的静态常量,如下:
/*
* Copyright (c) 2002-2006 by OpenSymphony
* All rights reserved.
*/
package com.opensymphony.xwork2;
public interface Action {
//action执行成功,要向用户显示成功页面,返回SUCCESS常量
public static final String SUCCESS = "success";
//action执行成功,但不需要向用户显示结果页面,使用NONE常量
public static final String NONE = "none";
//action执行失败,要向用户显示失败页面,返回ERROR常量
public static final String ERROR = "error";
//action的执行需要用户输入更多信息,要向用户显示输入页面,返回INPUT常量
public static final String INPUT = "input";
//由于用户没有登录,action不能执行,要向用户显示登录页面,返回LOGIN常量
public static final String LOGIN = "login";
public String execute() throws Exception;
}
Strtus 2中,所有的action必须返回一个字符串类型的结果代码,以标识要呈现给用户的result。
Action接口中定义的常量字符串,从语义上为你定义好了在action执行的不同情况下应该向用户呈现的result的名字,当然你可以为result取其他的名字,不过这种行为是不建议的,除非上述定义的字符串常量不能满足你的应用需求。
下面我们编写一个Action类HelloAction,实现com.opensymphony.xwork2.Action接口。
package org.leno.struts2.action;
import com.opensymphony.xwork2.Action;
public class HelloAction implements Action {
private String message;
public String getMessage() {
return message;
}
public String execute() throws Exception {
message = "Hello,Struts2!";
return SUCCESS;
}
}
在HelloWorldAction类中,我们定义了一个字符串类型的message实例变量,并给出了一个JavaBean风格的getter方法——getMessage(),用于获取message字段的内容。在execute()方法中,我们构造了一个问候语“Hello,Struts2!”,保存到message字段中,最后返回SUCCESS静态常量(在Action接口中定义),说明action已经成功执行。
Action返回的结果代码不一定非要对应一个要执行的result,例如,Action.NONE结果代码就没有对应任何的result。
Action已经创建完毕,接下来我们编写一个JSP页面,向用户显示问候信息。
Step5:编写结果页面
hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html PUBLIC "-//W 3C //DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1><s:property value="message" /></h1>
</body>
</html>
注意代码中以粗体显示的部分。与Struts 1相同,Struts 2框架也提供了一套标签库。在使用Struts 2标签时,通常为标签库指定前缀“s”。属性uri的值“/struts-tags”是固定的,书写时不要忘了前导的斜杠“/”。
Struts 2的property标签带有一个value属性,在这里,我们给它的值是“message”。还记得HelloAction中的getMessage()方法吗,此处的property标签将获取到getMessage()方法调用后的返回值,即“Hello,Struts2!”,这个问候语将作为2级标题向用户显示。
Step6:在struts.xml文件中配置action
一个action创建完成后,还需要为其配置一个URL,只有这样,FilterDispatcher才知道哪一个URL对应着哪一个action,当截获到访问该URL的请求时,FilterDispatcher就调用对应的action对请求进行处理。
除了为action配置一个URL外,还需要为action关联一个或多个结果页面,当action执行完毕后返回一个结果代码(一个字符串值,例如“success”),这个结果代码对应的页面就会被呈现给用户。
要对action进行配置,需要创建struts.xml文件。struts.xml是Struts 2框架的核心配置文件,默认的路径是WEB-INF/classes/struts.xml。我们只需在项目的src目录(源文件目录)下创建struts.xml文件即可。
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="hello"
class="org.leno.struts2.action.HelloAction">③
<result name="success">/hello.jsp</result>④ </action>
</package>
</struts>
① 这是struts.xml配置文件的文档类型声明,注意不要写错了。
② package元素将多个action元素组织为一个逻辑单元,从而简化了维护工作,提高了可重用性。name属性指定包的名字,可选的extends属性指定要扩展的包。Struts 2中的package可以扩展另外的package,从而“继承”原有包的定义。struts-default包的定义在struts-default.xml文件中,该文件已经包含在Struts 2的核心JAR包(即struts2-core- 2.0.11 .jar)中了。
③ action元素用于对action进行配置。name属性为action指定一个名字,这个名字即用户访问的URL,class属性指定action的完整类名。任何对“/hello.action”的请求都会调用HelloAction类。读者要注意的是:在为action取名时,一是不要在名字前面添加斜杠(/);二是不要在名字后面添加“.action”后缀名。
④ result子元素用于建立action和result之间的关联,name属性指定result映射的名字,值“success”和HelloAction的execute()方法返回的静态常量SUCCESS(值为“success”)是一致的。要注意的是,如果result的名字是“success”,那么可以省略name属性,即④处的代码等价于
<result>/hello.jsp</result>
Step7:发布并测试
现在是万事俱备,只欠东风了,我们只需将Hello World程序发布到Tomcat服务器中,然后启动服务器,打开浏览器,输入访问action的URL
http://localhost:8080/strut2Demo/hello.action,就可以看到举世闻名的“Hello World!”了。☺
Struts 2项目开发总结
Struts 2的开发步骤主要分为:
1.准备类库。不同的开发需求所用的类库是不一样的,但至少需要如下的5个类库。
struts2-core- 2.0.11 .jar
xwork- 2.0.4 .jar
ognl- 2.6.11 .jar
freemarker- 2.3.8 .jar
commons-logging- 1.0.4 .jar
2.在web.xml文件中配置FilterDispatcher。
3.开发action。针对每一个功能点,编写一个action类。
4.编写相关的结果页面。针对action返回的结果代码,编写相应的结果页面。
5.在src目录下创建struts.xml,对action进行配置,将action与结果页面关联在一起。
大家把这个例子跑出来,Struts2就算入门了。怎么样,并不太难吧!将Struts2和Struts1.x对比着学习,弄清楚它们的异同,重点关注struts2里面新的概念和思想。相信很快就能够掌握它!