Struts2基础

2017-09-15

Struts2基础

[TOC]

1.简介

1-1.概念

轻量级的MVC框架,主要解决了请求分发的问题,重心在控制层和表现层。低侵入性,与业务代码的耦合度很低。Struts2实现了MVC,并提供了一系列API,采用模式化方式简化业务开发过程。

1-2.对比Servlet

 优点:业务代码解耦,提高开发效率

 缺点:执行效率偏低,需要使用反射、解析XML等技术手段,结构复杂

1-3.不同MVC框架实现

Servlet

Spring

​ 此处Servlet应该为DispatcherServlet Spring前端控制器

Struts2

2.Struts2使用

2-1.导入jar

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.5.13</version>
</dependency>
</dependencies>

2-2.web.xml中配置前端控制器Filter

1
2
3
4
5
6
7
8
9
<!--Struts2核心过滤器-->
<filter>
<filter-name>Struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

2-3.创建struts.xml(格式可以参考核心包根路径下的DTD文件,struts-default.xml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<struts>
<!--
package:包,用于对Action进行封装
name:包名,根元素下可以有多个包,彼此不能重名
extends:继承,用于指定继承的包,相当于将继承包下的配置信息复制到当前包
namespace:命名空间,用于规定Action的访问路径,必须“/”开头 -->
<package name="test01" namespace="/test01" extends="struts-default">
<!--action:业务控制器,用于注册业务控制器组件
name:action名称,用于规定Action的访问路径
class:业务控制器组件,用于指定业务控制器对应的类
method:方法,用于指定访问当前action时要调用的方法
*请求URL:http://ip:port/projectName/namespace/ActionName.action
-->
<action name="hello" class="test01.konrad.action.HelloAction" method="execute">
<!--result:输出组件,用于转发、重定向、直接输出
name:名称,一个action下可以有多个result,彼此不能重名
默认值转发,元素内设置转发的页面
-->
<result name="success">
/hello.jsp
</result>
</action>
</package>
</struts>

2-4.编写Action前端控制器

  1. 定义需要的属性,并完善getter and setter
  2. 方法public修饰
  3. 返回值类型String(返回值与struts.xml->action->result的name属性匹配,即根据此返回值找到对应result)
  4. 参数列表为空
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package action;

import com.opensymphony.xwork2.Action;

public class HelloWorldAction implements Action {
//请求中传递的参数和返回给页面的值都定义成属性
//必须要给属性写getter/setter方法
private String username;
private String message;

//getter/setter略,自己一定要写
@Override
public String execute() throws Exception {
//查看请求中传递的参数
System.out.println(username);
//改变这个message,会自动传递给页面
message = "hello:" + username;
//SUCCESS是Action中的常量,值是success
return SUCCESS;
}
}

2-5.创建JSP页面

1
2


3.参数传递

3-1.基本属性注入Action(页面,Action)

3-2.域模型/对象注入Action(页面,Action)

3-3.页面取Action数据

1.EL表达式
1
<h1>${user.name}</h1>
2.OGNL

4.OGNL

4-1.概念

Object Graph Navigation Language,是一门功能强大的表达式语言,类似于EL(JSTL表达式语言)。Strut2默认采用OGNL表达式访问Action的数据,实际上是通过ValueStack对象来访问Action。

4-2.用法

在Struts2中,OGNL表达式要结合Struts2标签来访问数据

EL:${user.userName} <==> OGNL:<s:property value=”user.userName”>

  1. 访问基本属性  <s:property value=”属性名”/>
  2. 访问实体对象  <s:property value=”对象名.属性名”/>
  3. 访问数组/集合  <s:property value=”someArray[1]”/> | <s:property value=”someList[1]”/>
  4. 访问Map  <s:property value=”someMap.key” />
  5. 运算  <s:property value=”‘My name is’ + name” />
  6. 调用方法  <s:property value=”name.toUpperCase()” />
  7. 创建集合  <s:property value=”{‘a’,’b’,’c’}” /> ArrayList
  8. 创建Map  <s:property value=”#{‘mm’:’MM’,’nn’:’NN’}” /> LinkedHashMap

5.ValueStack

5-1.概念

是Struts2中,Action向页面传递数据的媒介,封装了Action的数据,并允许JSP通过OGNL来对其访问

5-2.原理

5-3.访问ValueStack

    1.通过<s:debug>观察其结构

    2.输出栈顶:<s:property />

    3.访问Context对象:

      - OGNL表达式以”#”开头

      - 以key来访问context对象的值,即”#key”得到context中某属性值

    4.迭代集合 

  

5.按数字迭代

5-4.ValueStack栈顶的变化

    - 默认情况下栈顶为Action

    - 循环过程中,栈顶为循环变量(集合迭代时,循环变量是集合中的对象,即栈顶为实体对象,可以以实体对象为root来写OGNL表达式;数字迭代时,循环变量是数字,不能以数字为实体对象,需要通过var声明变量名,以”#变量名”来引用,此情况下,是从context对象中取出值)

    - 循环结束后,栈顶变回Action

5-5.EL表达式访问ValueStack

    a)EL也是从ValueStack中取的值

    b)EL默认的取值范围是page,request,session,application

    c)Struts2重写的request的getAttribute方法,先试图从原始request中取值,如果没取到再从ValueStack中取值

6.Action基本原理

6-1.大核心组件

img

FC:前端控制器,负责统一的分发请求

  Action:业务控制器,负责处理某一类业务

  ValueStack:Action与JSP数据交互的媒介

  Interceptor:拦截器,负责扩展Action,处理Action的共通事务

  Result:负责输出的组件

  Tags:标签,负责显示数据、生成框体

6-2.获取Session的方式

    a)ActionContext

      - ActionContext.getContext().getSesion(),返回Map<String, Object>

    b)ServletActionContext

      - ServletActionContext.getRequest().getSession(),返回HttpSession

    c)SessionAware(推荐使用)

      - 让Action实现SessionAware接口

      - 实现setSession(Map<String, Object> session)方法,Struts2会在实例化Action后调用方法,通过方法参数将Session对象注入进来

      - 定义成员变量,接收注入进来的Session对象

7.Result原理

7-1.介绍

用于做输出的组件,用于向页面输出一些内容,转发、重定向可以理解为特殊方式的输出。每一个Result实际上是一个类,这些类都实现了共同的接口Result。Struts2预置了10种类型的Result,定义在strtus-default.xml

7-2.Result类型

a)dispatcher:用于转发的result,可以将请求转发给JSP,这种类型的Result对应的类为ServletDispacherResult,通过default=”true”指定该Result为Struts2默认的Result类型。

b)stream:用于向页面输出二进制数据,此种类型的Result可以将二进制数据输出到请求发起端,对应类为StreamResult

1
2
3
4
<result name="success" type="stream">
  <!--codeStream 为定义在Action的输入流InputStream -->
<param name="inputName">codeStream</param>
</result>

c)redirectAction:用于将请求重定向给另外一个Action,对应类为ServletActionRedirectResult

1
2
3
4
5
6
7
8
9
<result name="login" type="redirectAction">
<!--若重定向的Action与当前Action在同一个namespace下,可以省略namespace-->
<param name="namespace">
/命名空间
</param>
<param name="actionName">
action名
</param>
</result>

d)json:用于向页面输出json格式的数据,可以将json字符串输出到请求发起端。对应类为JSONResult

1
2
3
4
5
6
7
8
9
10
11
<result name="success" type="json">
<!--输出一个Action属性
指定属性为基本类型,则直接返回该属性值
如果指定属性为实体对象,则返回格式{"code":"as1","name":"hk"}
-->
<param name="root">属性名</param>
<!--输出多个Action属性-->
<param name="includeProperties">属性名1,属性名2...</param>
<!--输出所有属性,不需要param标签-->

</result>

 json需要导包,修改package继承关系为json-default

8.UI标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1.表单  <s:form action="" method="" theme="simple" ></s:form>

  2.文本框  <s:textfield name="userName" />

  3.布尔框  <s:checkbox name="marry" />

  4.单选框  <s:radio name="sex" list="#{'M':'男','F':'女'}"/> 静态初始化

        <s:radio name="favoriteCities" list="cities" listKey="cityCode" listValue="cityName" /> 动态初始化

  5.多选框  <s:checkboxlist name="travelCities" list="#{'01':'北京','02':'上海','03':'广州'}" /> 静态初始化

        <s:checkboxlist name="travelCities" list="cities" listKey="cityCode" listValue="cityName" /> 动态初始化

  6.下拉选  <s:select name="home" list="#{'01':'北京','02':'上海','03':'广州'}" /> 静态初始化

        <s:select name="home" list="cities" listKey="cityCode" listValue="cityName" /> 动态初始化

9.拦截器

9-1.用途

拦截器适合封装一些通用处理,便于重复利用。例如请求参数传递给Action属性,日志的记录,权限检查,事务处理等。拦截器是通过配置方式调用,因此使用方法比较灵活,便于维护和扩展。

9-2.使用步骤

1.创建拦截器组件

(创建一个类,实现Interceptor接口,并实现intercept方法;也可以继承MethodFilterInterceptor,这种方式可以使action中某个方法不进行拦截)

1
2
3
4
5
public String intercept(ActionInvocation invocation){
//拦截器--前部分处理
invocation.invoke();
//拦截器--后续处理
}
2.注册拦截器
1
2
3
4
5
6
<package>
<interceptors>
<interceptor name="别名" class="实现类"/>
<!--其他拦截器-->
</interceptors>
</package>
3.引用拦截器

(哪个Action希望被拦截器扩展,需要在此action配置下,引用拦截器)

1
2
3
4
5
6
7
<action>
   <!--手动的使用一次系统默认的拦截器-->
   <interceptor-ref name="defaultStack"/>
<interceptor-ref name="拦截器别名"/>
<!--可以写多个-->
   <!--可以使用excludeMethods参数属性,设置不过滤的方法-->
</action>
4.拦截器栈
1
2
3
4
<interceptor-stack name="myStack">
<interceptor-ref name="拦截器别名1"/>
<interceptor-ref name="拦截器别名2"/>
</interceptor-stack>
5.FileUpload拦截器

a)原理:首先FileUpload拦截器将表单中提交的文件,以临时文件的形式保存到服务器临时路径下。之后FileUpload拦截器将该临时文件对象注入给Action,Action自主处理该临时文件。最后FileUpload拦截器删除临时文件。

1
2
3
4
5
6
7
8
9
10
b)使用步骤
导包 commons-io.jar

Action:定义File类型属性(如some),接受拦截器注入的临时文件对象。若想要获取原始文件名,要定义String类型属性,属性名为File类型属性+FileName(如someFileName)

表单设置:method="post", enctype="multipart/form-data"
    

c)设置限制(Struts2文件上传默认最大值为2097152B,即2M)
在struts.xml中重置默认限制值  <constant name="struts.multipart.maxSize" value="5000000" />

10.数据校验

Action类继承ActionSupport,ActionSupport中有一个validate方法进行数据校验

11. 国际化

12.返回JSON

12-1.导入jar包

1
2
3
4
5
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.5.13</version>
</dependency>

12-2.Action类

1
2
3
4
5
6
7
8
9
10
public class JsonAction extends ActionSupport {
private Map<String, Object> resultMap;
//getter/setter略
public String getJson() {
resultMap=new HashMap<>();
resultMap.put("key1",123);
resultMap.put("key2","abc");
return SUCCESS;
}
}

12-3.xml中继承

1
2
3
4
5
6
<package name="default" namespace="/" extends="struts-default,json-default">
<action name="json" class="action.JsonAction" method="getJson">
<result type="json">
<param name="root">resultMap</param>
</result>
</action>

…查询文档吧(눈‸눈)写不动了,下次更新

古老的传送门

SSH传送门:http://www.cnblogs.com/konrad/p/6901273.html

hibernate知识点梳理:http://www.cnblogs.com/konrad/p/6391962.html