Struts2学习笔记之入门

本文详细介绍了Struts2框架的基本概念、工作流程及其核心组件。包括MVC模式下的职责划分、Struts2的配置方式、Action处理过程及其实现细节,并提供了一个简单的登录示例。

一、MVC概述

  MVC是三个单词的缩写,分别为: 模型(Model),视图(View) 和控制Controller), MVC模式的目的就是实现Web系统的职能分工。

  • Model层:实现系统中的业务逻辑,通常可以用JavaBean或EJB来实现。
  • View层:用于与用户的交互,通常用JSP来实现。
  •   Controller层:是Model与View之间沟通的桥梁,它可以分派用户的请求并选择恰当的视图以用于显示,同时它也可以解释用户的输入并将它们映射为模型层可执行的操作。

二、Struts2基础

2.1 Struts2框架结构图

 

2.2 工作流程

  1. 客户端发送请求到服务器,此时服务器接收到一个HttpServletRequest请求。
  2. HttpServletRequest请求经过一系列的过滤器,从上到下依次经过ActionContextCleanUp,,再其他过滤器(Othter Filters、SiteMesh等),最后到FilterDispatcher。FilterDispatcher是控制器的核心,就是MVC的Struts 2实现中控制层(Controller)的核心。
  3. FilterDispatcher调用ActionMapper来决定调用某个Action来处理这个(HttpServlet Request)请求。
  4. ActionMapper决定需要调用某个Action,FilterDispatcher则把请求的处理交给ActionProxy。
  5. ActionProxy通过Configuration Manager查看struts.xml,从而找到相应的Action类。
  6. ActionProxy创建一个ActionInvocation实例,ActionInvocation通过代理模式调用Action的execute方法(默认情况下)。但在调用之前,ActionInvocation会根据配置加载Action相关的所有Interceptor(拦截器)。
  7. Action执行完毕后,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果result,然后将Result内容通过HttpServletResponse返回给服务器。

需要注意的是:
1、调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用
2、Struts 2的核心控制器是FilterDispatcher,有3个重要的方法:destroy()、doFilter()和Init(),执行顺序是:init()—>doFilter() —>destroy()

2.3 Struts2:配置

2.3.1 Struts2:配置

<1> web.xml

  Struts2框架需要在web.xml文件中配置一个前端控制器FilterDispatcher,用于对Struts2框架进行初始化并处理所有的请求。FilterDispatcher是一个Servlet过滤器,它是整个Web应用的配置项。

<2> struts.properties

  Struts2提供了很多配置的属性,通过这些属性的设置,可以改变框架的行为,从而满足不同Web应用的需求。

  Struts2在default.properties文件(位于struts2-core-*.jar\org\apache\struts2下)中给出了所有属性的列表,并对其中一些属性预设了默认值。如果我们创建了struts。properties文件,那么在该文件中的属性设置会覆盖default.properties文件中的属性设置。

在开发中,可能需要修改的几个属性:

  1. struts.i18n.reload=true:激活重新载入国际化文件的功能
  2. struts.devMode=true:激活开发模式,提供更全面的调试功能
  3. struts.configuration.xml.reload=true:激活重新载入XML配置文件的功能,当文件被修改后,就不需要载入Servlet容器中的整个Web应用了。
  4. struts2.url.http.port=8080:配置服务器运行的端口
  5. struts.objectFactory=spring:把Struts2的类的生成交给Spring完成(用于集成Struts2与Spring框架)

<3> struts.xml文件

  struts.xml是Struts2框架的核心配置文件,主要配置和管理action。该文件通常放在src目录下,该目录下的struts.xml将被Struts2框架自动加载。

  所有标签都包含在struts标签内,其中package元素类似于Java中的包提供了将action、result、result类型、拦截器和拦截器栈组织为一个逻辑单元的方式,从而简化了维护工作,提供了重用性。与Java不同的是,Struts2中的包可以扩展另外的包,从而“继承”原有包的所有定义,并可以添加自己包特有的配置,以及修改原有包的部分配置。

  package元素中有一个必须的属性name—指定包的名字,这个名字将作为引用该包的键。需要注意的是,包的名字必须是唯一的。package元素的extends属性是可选的,允许一个包继承一个 或多个先前定义的包中的配置。package元素的abstract属性是可选的,将其设置为true,可以把一个包定义为抽象的,抽象包不能有action定义,只能作为“父”包,被其他的包继承。

  action元素是Struts2的核心功能,使用Struts2框架,主要的编码工作就是编写action类。Action类通常都要实现com.opensymphony.xwork2.Action接口,并实现该接口中的execute()方法。当然,Struts2并不要求所编写的action类一定要实现Action接口,也可以使用一个普通的Java类作为一个action,只要改类提供一个返回类型为String的无参的public方法。

  在实际开发中,action很少直接实现Action接口,通常都是从com.opensymphony.xwork2.ActionSupport类继承。ActionSupport实现了Action接口和其他一些可选的接口,提供了输入验证、错误信息存取以及国际化的支持,选择从ActionSupport继承,可以简化action的开发。

  开发好action后,就需要配置action映射,以告诉Struts2框架,针对某个URL的请求应该交由哪一个action进行处理。action元素中包含了name与class属性用来对应一个action,默认情况下调用execute(),如果要执行action中的其它方法,可以使用method属性指定。

  result元素包含在action元素中,一个result代表了一个可能的输出。当Action类的方法执行完成时,他返回一个字符串类型的结果代码,框架根据这个结果代码选择对应的result,向用户输出。

2.4 Action

Struts2控制器最重要的组成部分是Action,它是Web框架的控制中心,是链接后台业务处理的Javabean和前端JSP页面的桥梁和纽带。

2.4.1 Action的定义

  Action就是一个普通的类,上面已经接触到了。Action的类名,习惯上以Action结尾,这样更易阅读和理解。在Action中如果希望配置默认方法则定一个名为execute()的方法,注意方法不能带任何参数,且必须返回字符串类型。

在struts.xml配置文件中,将刚才创建的Action注册到这里:

<action name="类名" class="类全路径" method="方法名"></action>

如果该方法返回值为null,表示不跳转到任何地方。如果返回一个字符串,则必须配置<action>的子标签<result>,通过该标签映射一个跳转路径,如:

<result name="返回字符串">/welcom.jsp</result>

2.4.2 通过Action获取请求参数

  通过HttpServletRequest的getParameter()或getParameterValues()方法固然可以得到从客户端传送过来的请求参数,但是这样做有些麻烦,而且增加了耦合度,增强了对容器的依赖。Struts2在Action中改进了获取请求参数的方式,自动获取请求参数。在表单域的name属性值必须和Action中定义的属性名称一致,才能正确被Action接收

2.4.3 ActionSupport

  在Struts2中,Action与容器已经做到完全解耦,不在继承某个类或实现某个接口,但是在特殊情况下,为了降低编程的难度,充分利用Struts2提供的功能,定义Action时会继承类ActionSupport,该类位于Xwork2提供的包com.opensymphony.xwork2中。

ActionSupport类为Action提供了一些默认实现,主要包括:

  1.  预定义常量
  2.  从资源文件中读取文本资源
  3.  接收验证错误信息
  4.  验证的默认实现

2.5 简单示例

名称:JSP+Struts2+JDBC实现登录

2.5.1 需要的jar包

(1) 传统Struts2的5个基本类库

  • struts2-core-*.jar :Struts2框架类库
  • xwork-core-*.jar :Xwork项目,Struts2就是在此基础上构建的
  • ognl-*.jar :GONL表达式语言
  • commons-logging-*.jar :用于能够插入任何其他的日志系统
  • freemarker-*.jar :所有的UI标记末班

(2) 附加的4个库

  • commons-io-*.jar
  • commons-lang-*.jar
  • javassist-*.jar
  • commons-fileupload-*.jar
  • 外加一个数据库驱动包

2.5.2 界面

注意:我只粘贴主要的代码。

login.jsp

<body>
	<form action="login.action" method="post">
		用户登录<br>
		姓名:<input type="text" name="username"/><br>
		密码:<input type="text" name="password"/><br>
		<input type="submit" value="登录"/>
	</form>
</body>

welcome.jsp

<%@	taglib prefix="s" uri="/struts-tags"%>
<html>
	<head><title>成功页面</title></head>
	<body>
		<s:property value="username"/>,您好!欢迎光临叮当书店。
	</body>
</html>

error.jsp:显示错误信息的界面

2.5.3 配置文件

web.xml

<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>

struts.xml(配置Action)

<struts>
	<package name="struts" extends="struts-default">
		<action name="login" class="org.easybooks.bookstore.action.LoginAction">
			<result name="success">/welcome.jsp</result>
			<result name="error">/error.jsp</result>
		</action>
	</package>
</struts>

2.5.4 java源码

LoginAction.java

package org.easybooks.bookstore.action;
import java.sql.*;
import org.easybooks.bookstore.jdbc.MySQLConnBean;
import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport {
	private static final long serialVersionUID = 1L;
	private String username;
	private String password;


	// 处理用户请求的execute方法
	public String execute() throws Exception {
		//Struts2框架自动注入username与password,只要表单中的定义名与其相同
		// String usr = getUsername();// 获取提交的姓名
		// String pwd = getPassword();// 获取提交的密码
		boolean validated = false;// 验证成功标识
		MySQLConnBean MySqlBean = new MySQLConnBean();// 创建连接对象
		// 查询user表中的记录
		String sql = "select * from user";
		MySqlBean.OpenConn();// 调用MySqlBean中加载JDBC驱动的方法
		ResultSet rs = MySqlBean.executeQuery(sql);// 取得结果集
		while (rs.next()) {
			if ((rs.getString("username").compareTo(username) == 0)
					&& (rs.getString("password").compareTo(password) == 0)) {
				validated = true;// 标识为true表示验证成功通过
			}
		}
		rs.close();
		MySqlBean.closeStmt();
		MySqlBean.closeConn();
		if (validated) {
			// 验证成功返回字符串"success"
			return "success";
		} else {
			// 验证失败返回字符串"error"
			return "error";
		}
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

MySQLConnBean.java

package org.easybooks.bookstore.jdbc;
import java.sql.*;

public class MySQLConnBean {
	private Statement stmt = null;
	private Connection conn = null;
	ResultSet rs = null;

	// 构造函数
	public MySQLConnBean() {
	}

	public void OpenConn() throws Exception {
		try {
			Class.forName("com.mysql.jdbc.Driver").newInstance();
			String url = "jdbc:mysql://localhost:3306/ceshi";
			String user = "root";
			String password = "root";
			conn = DriverManager.getConnection(url, user, password);
		} catch (SQLException e) {
			System.err.println("Data.executeQuery: " + e.getMessage());
		}
	}

	// 执行查询类的SQL语句,有返回集
	public ResultSet executeQuery(String sql) {
		rs = null;
		try {
			stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			rs = stmt.executeQuery(sql);
		} catch (SQLException e) {
			System.err.println("Data.executeQuery: " + e.getMessage());
		}
		return rs;
	}

	// 关闭对象
	public void closeStmt() {
		try {
			stmt.close();
		} catch (SQLException e) {
			System.err.println("Date.executeQuery: " + e.getMessage());
		}
	}

	public void closeConn() {
		try {
			conn.close();
		} catch (SQLException e) {
			System.err.println("Data.executeQuery: " + e.getMessage());
		}
	}
}

注意:Struts2可以进行自动注入,LoginAction中的两个属性:username和password命名必须与在login.jsp中使用的文本输入框的命名严格匹配。在Struts2中,类变量总是在调用execute()方法之前被设置(通过setUsername()/setPassword()方法),这意味着在execute()方法中可以使用这些类变量,因为在execute()方法执行之前,他们已经被赋予了正确的值。

参考资料:

赞赏

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值