Struts2 学习笔记一

Struts:Jakarta项目 -> Apache软件基金会开源子项目 -> Struts
Struts是流行和成熟的基于MVC设计模式的Web应用程序框架。
使用Struts的目的是为了帮助我们减少运用MVC设计模式来开发Web应用的时间。

MVC是模型视图控制器,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方式组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

流程:用户通过视图输入,通过Controller控制器将用户输入的指令和数据传递给业务模型,Model模型进行业务逻辑判断、数据库存取,选择不同View视图显示反馈给用户。

MVC三层架构

  • View 视图层 展示数据给用户
  • Control 控制层 控制数据流图
  • Model 模型层 增删改查

Apache Struts2环境需求

  • Servlet API 2.*
  • JSP API 2.*
  • Java 5以上

搭建Struts2环境步骤
1.引用Jar包
https://struts.apache.org/download.cgi
需要引入以下jar包:

  • commons-fileupload-1.3.2.jar
  • commons-io-2.2.jar
  • commons-lang3-3.2.jar
  • commons-logging-1.1.3.jar
  • freemarker-2.3.22.jar
  • javassist-3.11.0.GA.jar
  • ogln-3.0.19.jar
  • struts2-core-2.3.31.jar
  • xwork-core-2.3.31.jar

2.配置web.xml

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

3.配置strut.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!--配置映射 加入action-->
	<package name="default" namespace="/" extends="struts-default">
		<action name="helloworld" class="com.imooc.action.HelloWorldAction">
			<result>/result.jsp</result>
		</action>
	</package>
</struts>

Struts2的工作原理及文件结构
web.xml:任何MVC框架都需要与Web应用整合,这就不得不借助于web.xml文件,只有配置在web.xml文件中Servlet才会被应用加载。通常所有的MVC框架都需要Web应用加载一个核心控制器,对于Struts2框架而言,需要加载StrutsPrepareAndExecuteFilter,只要Web应用负责加载StrutsPrepareAndExecuteFilter。StrutsPrepareAndExecuteFilter将加载Struts2框架。

struts.xml:Struts2的核心配置文件,在开发过程中利用率最高。该文件主要负责管理应用中的Action映射,以及该Action包含的Result定义等。
包含内容:

  • 全局属性
  • 用户请求和Action之间的对应关系
  • Action可能用到的参数和返回结果
  • 各种拦截器的配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
	<!-- include节点是struts2中组件化的方式, 可以将每个功能模块独立到一个xml配置文件中,然后用include节点引用 -->
	<include file="struts-default.xml"></include>

	<!-- 
		package提供了将多个Action组织为一个模块的方式,package的名字必须是唯一的。 
		package可以扩展,当package扩扎自另一个package时,该package会在本身配置的基础上加入扩展的package的配置, 
		父package必须在子package前配置 
		name:package名称 
		extends:继承的父package名称 
		abstract:设置package的属性为抽象,true/false,此时抽象的package不能定义action 
		namespace:定义package命名空间,该命名空间影响到url的地址,
		例如此命名空间为/test时,访问的地址是http://localhost:8080/struts2/test/xx.action 
	-->
	<package name="com.kay.struts2" extends="struts-default.xml" abstract="false" namespace="/test">
	
		<interceptors>
			<!-- 定义拦截器 name:拦截器名称 class:拦截器类路径 -->
			<interceptor name="timer" class="com.kay.timer"></interceptor>
			<interceptor name="logger" class="com.kay.logger"></interceptor>
			<!-- 定义拦截器栈 -->
			<interceptor-stack name="mystack">
				<interceptor-ref name="timer"></interceptor-ref>
				<interceptor-ref name="logger"></interceptor-ref>
			</interceptor-stack>
		</interceptors>
		
		<!-- 定义默认的拦截器,每个Action都会自动引用,如果Action中引用了其他的拦截器,默认的拦截器将无效 -->
		<default-interceptor-ref name="mystack"></default-interceptor-ref>
		
		<!-- 全局result配置 -->
		<global-results>
			<result name="input">/error.jsp</result>
		</global-results>
		
		<!-- 
			一个Action可以多次被映射(只要action配置中的name不同)
			Action配置
			name:action的名称 http://localhost:8080/ProjectName/hello.action
			class:对应类的路径
			method:调用action中的方法名
		 -->
		 <action name="hello" class="com.kay.struts2.Action.LoginAction">
		 	<!-- 引用拦截器 name:拦截器的名称或者拦截器栈的名称 -->
		 	<interceptor-ref name="timer"></interceptor-ref>
		 	
		 	<!-- 
		 		节点配置 name:result名称,和action中返回值相同
		 		type:result的类型,不写则选用superpackage的type
		 		struts-default.xml中的默认为dispatcher 
		 	-->
		 	<result name="success" type="dispatcher">/talk.jsp</result>
		 	
		 	<!-- 
		 		参数设置 
		 		name:对应action中的get/set方法
		 	-->
		 	<param name="url">www.baidu.com</param>
		 </action>
	</package>
	
	<!-- 定义全局属性,与struts.properties中为相同作用 -->
	<constant name="struts.i18n.reload" value="true"></constant>
</struts>

struts.properties:Struts2框架的全局属性文件,自动加载。文件位置与strurs.xml相同即可。该文件包含很对key-value对。该文件完全可以配置在struts.xml文件中,使用constant元素。
示例:

#指定默认编码集,对于请求参数中带有中文的情况应该设置为GBK或GB2312,默认值为UTF-8
struts.i18n.encoding=UTF-8

#是否每次HTTP请求到达时,都重新加载国际化资源文件,默认为false
struts.i18n.reload=true

#是否使用struts2的开发者模式,可以获得更多的报错信息,便于调试。在开发阶段设置为true,默认为false
struts.devMode=true

#指定后缀后为.action形式的请求可被struts2处理,可配置多个请求后缀,比如.do,.struts2等,配置时对个后缀名用逗号隔开
struts.action.extension=action,do,struts2

#配置服务器运行时的端口号,一般情况下该属性不修改,如果端口号被占用则重新分配端口号,默认80
struts.url.http.port=80

访问Servlet API

  • ActionContext
  • 实现***Aware接口
  • ServletActionContext

Action搜索顺序
例如:http://localhost:8080/struts2/path1/path2/paht3/student.action
第一步:判断package是否存在,如path1/path2/path3/
第二步:如果package存在,判断action是否存在,如果action不存在则去默认namespace的package里面寻找action,如果仍未找到则报错
第三步:如果package不存在,检查上一级路径的package是否存在(直到默认namespace),返回第一步,如果最后仍未找到,则报错

动态方法调用
为了解决一个action对应对个请求的处理,以免action太多。

  • 指定method的属性:在Action类中添加方法,在struts.xml中添加对应的action,并指定对应的方法以及跳转页面
public String add() {
	return SUCCESS;
}

public String update() {
	return SUCCESS;
}
<action name="addAction" method="add" class="com.imooc.action.HelloWorldAction">
		<result>/add.jsp</result>
</action>
		
<action name="updateAction" method="update" class="com.imooc.action.HelloWorldAction">
		<result>/update.jsp</result>
</action>
  • 感叹号方式(不推荐使用):在Action类中添加方法,并返回result的名称,在struts.xml文件中添加常量struts.enable.DynamicMethodInvocation,在Action标签中加入不同的result,并加上相应的名称。在使用浏览器访问时,格式如下:http://localhost:8080/HelloWorld/helloworld!add.action
public String add() {
	return "add";
}

public String update() {
	return "update";
}
<package name="default" namespace="/" extends="struts-default">
		<action name="helloworld" class="com.imooc.action.HelloWorldAction">
		<result>/result.jsp</result>
		<result name="add">/add.jsp</result>
		<result name="update">/update.jsp</result>
	</action>
</package>
	
<constant name="struts.enable.DynamicMethodInvocation" value="true"></constant>
<action name="helloworld_*" method="{1}" class="com.imooc.action.HelloWorldAction">
	<result>/result.jsp</result>
	<result name="add">/{1}.jsp</result>
	<result name="update">/{1}.jsp</result>
</action>

指定多个配置文件

<include file="helloworld.xml"></include>

默认Action
当访问的action不存在时,访问默认action

<default-action-ref name="index"></default-action-ref>

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

Struts2的后缀

  • 方法一:在struts.xml中配置
<!-- 更改后缀名 当value为空时或不设置参数时,访问时不需要后缀名 -->
<constant name="struts.action.extension" value="html,do"></constant>
  • 方法二:在struts.properties中配置
struts.action.extension=action,do,struts2
  • 方法三:在web.xml中配置
<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
	</filter-class>
	<init-param>
		<param-name>struts.action.extension</param-name>
		<param-value>do</param-value>
	</init-param>
</filter>

接收参数

  • 使用action的属性接收参数
  • 使用Domain接收参数
<form action="LoginAction.action" method="post">
	用户名:<input type="text" name="user.username">
	密码:<input type="password" name="user.password">
	<input type="submit" value="提交">
</form>
public class LoginAction extends ActionSupport {
	private User user;

	public User getUser() {
		return user;
	}

	public void setUser(User user) {
		this.user = user;
	}

	public String login() {
		System.out.println(user.getUsername());
		return SUCCESS;
	}
}
  • 使用ModelDriven接收参数
<form action="LoginAction2.action" method="post">
	用户名:<input type="text" name="username">
	密码:<input type="password" name="password">
	book1:<input type="text" name="bookList[0]">
	book2:<input type="text" name="bookList[1]">
	book3:<input type="text" name="bookList[2]">
	<br>
	user1:<input type="text" name="user[0].username">
	user2:<input type="text" name="user[1].username">
	<input type="submit" value="提交">
</form>
public class LoginAction2 extends ActionSupport implements ModelDriven<User> {
	private User user = new User(); // 使用ModelDriven必须实例化对象

	public String login() {
		System.out.println(user.getUsername());
		System.out.println(user.getBookList().get(0));
		System.out.println(user.getBookList().get(1));
		System.out.println(user.getBookList().get(2));
		
		System.out.println(user.getUser().get(0).getUsername());
		System.out.println(user.getUser().get(1).getUsername());
		return SUCCESS;
	}

	@Override
	public User getModel() {
		return user;
	}
}
  • request

处理结果类型
Struts2处理流程:用户请求 -> Struts框架解析 -> 匹配到对应的控制器(Action) -> Action将处理结果返回Struts2框架 -> 返回视图资源

Struts1返回ActionForward,Struts2返回String字符串

<action name="LoginAction" method="login" class="com.imooc.action.LoginAction">
		<result name="success">/success.jsp</result>
		<!-- 
			result元素中的name是result元素的逻辑视图名称 
			如果省略name的值,则默认name的值为success
			/success.jsp为绝对路径
			success.jsp为相对路径
		-->
</action>

处理结果类型如下:com.opensymphony.xwork2.Action(位置)

  • SUCCESS:Action正确的执行完成,返回相应的值,success是name属性的默认值
  • NONE:表示Action正确的执行完成,但是并不需要返回视图
  • ERROR:表示Action执行失败,返回到错误处理视图
  • LOGIN:Action因为用户没有登录的原因没有正确执行,将返回该登录视图,要求用户登录验证
  • INPUT:Action的执行,需要从前端界面获取参数,INPUT就是代表这个参数输入的界面,一般在应用中,会对这些参数进行验证,如果没有验证通过,将自动返回到该视图

处理结果是在struts.xml使用<result />标签配置结果。根据位置的不同,分为两种结果:

  • 局部结果:将<result />作为<action />元素的子元素
  • 全局结果:将<result / >作为<global-result />元素的子元素配置
<package name="">
	<global-results>
		<result name="ERROR404">/error404.jsp</result>
	</global-results>
</package>

<result />标签的子标签<param>具有两个属性:

  • location:该属性定义了该视图对应的实际视图资源
  • parse:该参数指定是否可以在实际视图名字中使用OGNL(Object-Graph Navigation Language)表达式

type属性的默认值为dispatcher,这个类型支持JSP视图技术。

posted @ 2017-03-07 16:40  永无乡seven  阅读(178)  评论(0编辑  收藏  举报