企业框架-2 Struts2.0框架

Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。这部分内容主要包括Struts2基础、Struts2配置、OGNL和Struts2标签、拦截器与文件上传,下面依次介绍。
一、Struts2 基础

1、Struts2介绍

Struts2是一个基于MVC的Web应用框架,主要用到WebWork技术。相当于Servlet(控制层C),负责处理客户端请求。而之前学的Hibernate相当于JavaBean(模型层M),负责封装数据,访问数据库。Struts2优点:提供丰富的标签、实现松耦合,通过配置文件页面导航,便于后期维护。

2、搭建Struts2环境

(1)搭建所需jar包

(2)修改web.xml配置文件,配置过滤器

(3)添加struts.xml文件并配置action

3、Struts2流程分析

①当在浏览器中输入相应网址,会加载web.xml中的核心控制器

②核心控制器会拦截所有请求,加载struts.xml的配置文件,找到和请求名字相同的action

③创建Class属性指定类的对象

④执行method属性指定的方法,返回一个字符串结果

⑤找Name等于此字符串的result,转到相应页面或action

⑥在页面中执行相关代码:通过EL表达式或者OGNL表达式取当前类属性的值

4、创建Action的方法

(1)新建一个Java类,继承ActionSupport类或者实现Action接口

(2)编写public string execute(){}方法。方法名execute可以自定义

5、Action作用

(1)控制业务逻辑

(2)返回结果字符串

(3)方便处理数据  比如 Action中以属性的方式接收用户数据
二、Struts2配置详解

1、Action接收参数方式

  • 属性方式

Action中:表单参数名称必须在Action中有对应的setter以及getter方法

页面显示:修改form表单参数name为属性名

页面引入:<%@taglib uri=”/struts-tags” prefix=”s”>

取值 : <s:property value=”属性名”/>  或者<input type="text" name="属性名"/>

应用场景:接收的参数字段个数少。比servlet获取参数方便多了,自动传值。

  • JavaBean方式:将模型数据从Action中分离出来

第一步:定义实体类,为实体类添加属性以及setter和getter方法

Action中:为Action添加实体属性以及setter和getter方法

页面显示:

1.页面引入:<%@taglib uri=”/struts-tags” prefix=”s”>

2.取值:<s:property value="对象名.属性名"/>或<input type="text" name="对象名.属性名"/>

应用场景:字段多,可以封装为一个对象

  • ModelDriven方式

Action中:1.Action实现ModelDriven接口,重写方法getModel()方法;

                    2.Action中要添加实体属性,需要实例化new,但不需要相应的setter和getter方法

页面显示:1.页面引入:<%@taglib uri=”/struts-tags” prefix=”s”>

2.取值:<s:property value="属性名"/> 或者<input type="text" name="属性名"/>

应用场景:和JavaBean方式相似,不常用

2、Action传递参数方法

  • 本质是利用Servlet API来存储数据

传统Servlet API 类型:HttpServletRequest、HttpSession、ServletContext

Struts2中传统Servlet API类型被处理成Map类型:通过ActionContext类实例得到

  • ActionContext:Action上下文或Action环境,提供每个Action运行时与之相关的所有信息。所在包com.opensymphony.xwork2
  • 使用Servlet API获取

1.Action类中声明request session application等对象(Map类型)

Map<String,Object> request;

2.获得ActionContext实例

ActionContext ac= ActionContext.getContext();

3.由实例获取Map对象

request=(Map<String,Object>)ac.get(“request”);

4.在Map对象中保存数据

request.put(“login”,“登录地点是:北京”);    put()方法存储

request.get(“login”);                                   get()方法获取

简写:ActionContext.getContext().getSession.put("aa","12");  //session

ActionContext.getContext().put("aaa", "123");          //request

其他方式:

  • 通过servletActionContext.getRequest获得request对象。这是耦合的方法,不建议这样写
  • 实现RequestAware、 SessionAware 、ApplicationAware接口。直接通过put()和get()方法在Map类型的对象中存取数据

3、method属性及动态方法调用—DMI(dynamic method invocation)

  • method属性:指定调用的方法,访问Action时,默认调用的是execute()方法。

一个Action类中可以定义多个业务方法,method属性与定义的业务方法名一致。

  • DMI:只需要配置一个<action>标签,不需要使用method属性,调用时指出Action名和业务方法

如 http://localhost:8080/struts2/house!add

4、result的name属性

Action中的预定义的字符串常量可以和result的name对应。如 SUCCESS、INPUT、ERROR……

result的name可以是定义的任意字符串,和Action返回结果一致

result配置一般使用绝对路径,绝对路径以斜杠(/)开头

5、result的type属性

默认取值dispatcher,将请求转发到本应用程序里指定的资源

可以在struts-default.xml中查看result的类型

redirect:         请求重定向到指定的Action或URL

redirectAction:   请求重定向到指定的Action

chain:            处理,将请求转发到指定的Action

json:             实现Ajax时返回json对象

stream:           文件的上传和下载

6、全局结果

全局结果(global-results):可以满足多个Action共享一个结果

方法:使用<result>来配置,在<global-results>中嵌套

<global-results><result name="error">/error.jsp</result></global-results>

注意:全局结果的影响范围为整个包的所有Action!

7、动态结果

有些执行结果在运行时才能确定

方法:在配置结果时使用表达式:${},在运行时,Struts2框架解析并计算表达式,根据表达式的值来动态确定要执行的结果。

8、命名空间

一般以模块进行命名,配置了命名空间namespace,访问时需要加上命名空间

取值:默认为“”或“/”根目录;代表不管路径有多深,只要Action的名字匹配上就可以

Action搜索顺序:http://localhost:8080/p1/p2/p3/login,从最具体开始搜索,如果都找不到会从默认namespace的package里面去搜索

9、模块拆分 与 异常机制

模块拆分:struts.xml

<constant name="struts.devMode" value="true" />

<include file="struts-house.xml"></include>

异常机制:

<exception-mapping>:局部异常映射

指定在Action方法抛出指定异常(exception属性配置)的时候跳转到哪个指定的结果视图(result属性配置)

<global-exception-mappings>:全局异常映射

要配置一个全局结果<global-results>,<global-results>在<global-exception-mappings>之前
三、OGNL简介和Struts2标签

1、OGNL定义

OGNL:Object Graph Navigation Language,称对象图导航语言。是Struts2默认的表达式语言,开源,功能更强大

主要作用:存取对象的属性、调用对象的方法; 访问值栈以及栈上下文

操作集合对象;支持赋值、运算操作、字段类型转化等

2、OGNL访问值栈(Value Stack)

值栈:存放数据的内存空间,其存放action的实例和调用。所以OGNL可以直接访问值栈中的值。

值栈Root 用#访问的时候需要用#root[*].格式(简写可去掉#root[*])

3、OGNL访问栈上下文(Stack Context)

栈上下文:存放数据的内存空间,其存放page、request、session、application、attr、parameters的参数、属性;

栈上下文Context 用必须用#访问:#context.格式访问(简写可去掉context)

4、Value Stack与Stack Context

值栈保存的数据也存放在栈上下文中,但是在栈上下文中调出值栈的信息语法不一样而已。

默认步骤:先创建栈上下文,再创建值栈,最后创建一个Action对象放到值栈中

5、OGNL访问集合(List)

(1)指明索引即可访问List中的指定元素

如:<s:property value="streetsList[1]"/>

(2)访问List的方法

如:<s:property value="streetsList.size()"/>

(3)直接在OGNL中构造List

如:{1,2,3}

6、OGNL访问集合(Map)

(1)Map名称['键的名称'] 或者 Map名称.键的名称  访问特定元素

如:<s:property value="streetsMap['m1']"/>

如:<s:property value="streetsMap.m1"/>

(2)访问Map的方法

如:<s:property value="streetsMap. isEmpty()"/>

(3)直接在OGNL中构造Map  注意构造Map时有#,而构造list没有

如:#{'first':'zhangsan','second':'lisi'}

#{'first':'zhangsan','second':'lisi'}.first

7、OGNL访问集合(Set)

(1)转换为数组再通过索引访问指定元素

如:<s:property value="streetsSet.toArray()[0]"/>

(2)访问Set的方法

如:<s:property value="streetsSet.size()"/>

8、OGNL访问静态方法、静态属性

@类的完全限定名@静态方法名

@类的完全限定名@静态属性名

前提:修改struts.xml配置

<constant name="struts.ognl.allowStaticMethodAccess"value="true" />

9、OGNL选择和投影

选择:过滤满足选择条件的集合元素。如:persons.{?#this.age>25}

投影:选出集合中每个元素的相同属性组成新的集合。

?是把所有满足条件的元素都取出来的意思,所以

stus.{?#this.grade>=60}.{username}[0]输出的是张三,它是一个字符串。

^是开始的意思,即取符合条件的数据索引中第一条数据,所以

stus.{^#this.grade>=60}.{username}输出的是[张三],包含括号,它是一个列表

$是结束的意思,即取符合条件的数据索引中最后一条数据,所以

stus.{$#this.grade>=60}.{username}输出的是[王五],包含括号。

10、Struts2标签分类

(1)通用标签(Generic Tags):标签前缀一般使用“s”

  包括 数据标签( Data Tags )和 控制标签( Control Tags )

(2)UI标签( UI Tags )            :标签前缀一般使用“s”

(3)Ajax标签( Ajax Tags )    : 标签前缀一般使用“sx"

11、数据标签

主要作用是提供对各种数据访问的相关功能,常用的有property、debug等

<s:property>:输出指定值 ,主要属性有

value:用来获取值的OGNL表达式 ag:<s:property value="#session.ok"/>

default:如果返回空值,可以使用default来指定输出的默认内容

escapeHtml:是否转义HTML ,默认取值true

<s:debug>:查看值栈以及Stack Context中所有能访问的值

<s:date> :格式化输出一个日期数据,主要属性有

name :被格式化的值,必须设置

format :指定日期格式,如:yyyy-MM-dd HH:mm:ss

<s:set> :定义一个特定作用域的变量,并赋值

var:变量名

value:变量的值,可以是常量,也可以是OGNL表达式

scope:变量的生存周期

<s:url> :用来生成一个url,或者说生成一个字符串

var:该url的引用名称。如果指定该属性,则url标签不会在页面显示value内容

action:要访问的Action的名字

value:要访问的目标地址,如果action不提供,就使用value作为URL的地址

<s:a> :用来生成HTML的<a>标签,或者说直接生成一个超链接

href:默认值是字符串常量。可以是超链接的url或者用ognl表达式 "%{#url}”

注意:字符串转OGNL:使用%{}       OGNL转字符串:使用单引号‘’

<s: param> :用来为其它标签添加参数化设置的功能。一般作为其他标签的子标签

name:参数的名称

value:参数的值

<s:include> :把其他页面包含到当前的页面上,类似于<jsp:include>

value:用来指定其他可以被引用的URL的名字,必须要设置

比如:<s:include value="page.jsp">

12、OGNL中%、#以及$的使用场景

#:   取栈上下文中的值  如:<s:property value="#request.name"/>

%{}:取出保存在值栈中的值,将字符串按照OGNL表达式来处理

比如:<s:property value="%{#house.title}"/>

$:   在国际化资源文件或struts.xml文件中,引用OGNL表达式

比如:validation.require=${getText(fileName)} is required

13、控制标签

主要用来完成分支流程、循环流程的控制。控制标签本身不会在页面输出内容。

(1)<s: if> 、 <s: elseif> 、 <s: else>用来处理分支判断

test:表示是否符合条件,本身是一个OGNL表达式,运算结果为一个boolean值

(2)<s:iterator> 用来处理循环,遍历集合对象

value :用来指明到底循环的是谁,这个属性的值是个OGNL表达式

var :变量名称,用来引用被循环的对象

status :返回当前循环的各种信息

count :集合含有多少个对象

index :正在循环的这一项的索引

even :当前遍历到的对象是不是处于列表的偶数索引位置

odd :当前遍历到的对象是不是处于列表的奇数索引位置

14、UI标签

用来生成Web界面,或者为Web界面提供某些功能支持。实现是基于模板和主题的

模块代码主要是用于将标签转换为HTML,而主题是将共同风格和观感模块组织到一起,实现不同主题生成不同的HTML风格。

Struts2内建主题: simple、xhtml、css_xhtml、ajax。

主题修改:设置标签的theme属性 或者 修改struts.xml配置:设置<constant name="struts.ui.theme" value="simple" />

(1)<s:form>表单标签  与HTML标签相对应

属性:name、action:处理表单的URL、method:get、post提交

(2)<s:textfield>单行文本框

属性:name、value、maxlength:最大字符数、readonly

(3)<s:textarea>多行文本框

属性:name、value、cols:文本域宽度、rows:文本域高度、readonly

(4) <s:submit>提交按钮  对应<input type="submit">

(5)<s:select>下拉框

name:下拉框的名字

list:生成下拉框的集合

listKey :生成的选项的value值的集合对象的属性

listValue :生成的选项显示的文字的集合对象的属性

(6)<s:doubleselect>两个联动的下拉框

name/doubleName:第一个/第二个下拉框的名字

list/doubleList:生成第一个/第二个下拉框的集合

listKey/doubleListKey :生成第一个/第二个下拉框的选项的value值的集合对象属性

listValue/doubleListValue :生成第一个/第二个下拉框的选项显示的文字的集合对象属性

15、Ajax标签

(1)datetimepicker标签:日期、时间

name:名称

label :用来显示组件前的文本

(2)使用步骤

在项目中引入struts2-dojo-plugin-2.3.4.1.jar

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

<sx:head parseContent="true" />

<sx:datetimepicker name="timer" label="发表时间"/>

UI标签、Ajax标签实际使用并不多,通过帮助文档了解即可
四、拦截器与文件上传

1、Struts2实现服务端验证

  • 使用ActionSupport编码实现验证

1.在Action类的业务方法中直接验证

  重写validate()方法; 使用validateXxx()方法

2.添加错误信息

  addFieldError(String fieldName,StringerrorMessage)

  addActionError(String anErrorMessage)

3.在页面输出验证结果

  <s:fielderror/>输出一个或所有字段的错误信息

  <s:actionerror/>输出所有Action的错误信息

4.<action>的配置

<result name="input">x.jsp</result>

  • 使用验证框架实现验证
    1. 编写JSP数据输入页面
    2. 编写Action类及其配置文件
    3. 在Action类同目录下创建验证文件ActionName-validation.xml
    4. 编写验证规则
    ActionName-validation.xml可对Action类中所有业务方法起作用
    ActionName-alias-validation.xml可对Action类中某一业务方法起作用

2、拦截器

拦截器也是一个类。通过拦截器拦截Action请求,在访问的Action执行之前和执行之后执行代码实现某项功能

框架的很多核心功能是拦截器实现的.如:接收输入的参数、数据验证、文件上传、国际化等

3、自带拦截器

params拦截器: 负责将请求参数设置为Action属性

servletConfig拦截器: 将源于Servlet API的各种对象注入到Action

fileUpload拦截器: 对文件上传提供支持

modelDriven拦截器: 如果Action实现了ModelDriven接口,则将getModel()返回的结果压入值栈

validation拦截器: 调用验证框架进行数据验证

workflow拦截器: 调用Action类的validate(),执行编码验证

4、拦截器栈:就是一组拦截器

默认拦截器

struts-default.xml中定义一个defaultStack拦截器栈,并将其指定为默认拦截器

只要在定义包的过程中继承struts-default包,那么defaultStack将是默认的拦截器

拦截器配置方法:

1.为Action指定拦截器引用

2.定义拦截器:在<interceptors>定义

3.定义拦截器栈

4.指定引用的拦截器

 

拦截器栈有多个<interceptor-ref>,谁在前,谁先起作用

拦截器起作用的顺序(先<action>,再本包,再父包)

5、自定义拦截器

继承AbstractInterceptor抽象类

提供了init()和destroy()方法的空实现

只需要重写intercept()方法即可

6、拦截器与过滤器

拦截器用于拦截对Action请求,而过滤器几乎可以过滤所有的请求

拦截器中可以获取Action的当前执行状态,而过滤器不可以

过滤器是Servlet中概念,在web.xml中配置;拦截器是Struts2/Webwork中概念,在struts.xml中配置

7、文件上传

  • 实现步骤

1、在JSP页面实现在客户端选择上传文件

2、配置struts.xml,拦截器会自动接收上传的文件

3、在Action中写代码把上传的文件存入服务器中

4、跳转至新页面展示上传的文件

  • 关键点

1.<form>需要添加enctype="multipart/form-data"属性

2.在Action中添加接收文件的成员,成员的setter命名规则如下:(X为上传文件的name)

setX(File file);setXContentType(String contentType);setXFileName(String fileName)

3.设置文件保存路径的时候使用

ServletActionContext.getServletContext().getRealPath("/") 取得项目真实路径

4.限制上传文件的大小

在<struts>节点下配置常量:实现对所有action的文件上传大小限制

<constant name="struts.multipart.maxSize" value= "5000000" />

在<action>下配置拦截器:限制单个<action>的文件上传

<param name="maximumSize">5000000</param>
5.限制上传文件的类型 —在<action>下配置拦截器:

<param name="allowedTypes">image/pjpeg,image/jpeg</param>

8、基于struts2实现ajax

1、使用struts2-json-plugin,将jar包拷贝入WEB-INF/lib文件夹

2、编写action代码              自定义一个public string getData(){ return SUCCESS;}方法

3、在struts.xml中的配置,包要继承自json-default,然后resultType是json。<result>元素没有name属性,也没有跳转值

<result type="json"><param name="includeProperties">name,user.*</param>

Visant

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: