Struts2入门

1 Struts2简介

Struts2就是基于MVC模式的开发框架,对servlet技术的封装!!!!

1)核心原理:编写核心控制器类ActionServlet。对不同的请求加以区分,进行不同的处理。

 

2) struts2的具体功能:请求数据封装、简化国际化、简化文件上传、后台数据校验......

 

3) struts2框架的作用

strurs2是基于MVC开发模型的web框架。

struts1也是MVC开发模式的框架。struts2并不是struts1的升级版。

struts2是基于webwork的升级版。struts2=webwork+sturts1

 

2 Struts2的使用

2.1 使用步骤

1)导入strust2的支持jar

commons-beautils  [beanutils工具包]

commons-filupload.ajr    [文件上传]

commons-io.jar  

commons-lang   [struts2java.lang.*类的支持]

freemarker.jar        [视图显示技术]

javassit            [struts2对字节码运算的支持]

ognl.jar            [struts2ognl表达式的支持]

    struts2-core.jar      [ struts2的核心包 ]

    xwork-core.jar   [webwork框架的支持,struts2的前身就是webwork(webwork的封装)]

 

2)配置启动的全局的过滤器(Filter)   - ActionServlet类似!!!

 

    web.xml中配置

<!--  配置启动strut2的全局过滤器 -->

<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)编写不同的业务Action类,编写不同业务方法。默认execute方法。

 

public class LoginAction implements Action{

//默认方法

public String execute() throws Exception {

System.out.println("执行了LoginActionexecute方法");

return "success";

}

}

 

4)在src目录下(类路径的根目录下),新建一个struts.xml,配置Action对象

 

<struts>

<package name="xxx" extends="struts-default">

<!-- 配置Action http://localhost:8080/day28_struts/login.action-->

<action name="login" class="gz.itcast.action.LoginAction">

<result name="success" type="redirect">/index.jsp</result>

</action>

</package>

</struts>

5)访问Action的业务方法

http://localhost:8080/day28_struts/login.action

2.2 Struts2的执行过程

项目启动:

1)创建核心过滤器StrutsPrepareAndExecuteFilter对象

2)执行核心过滤器的init方法

  读取了依次以下的配置:

struts-default.xml      [struts2框架的默认配置文件(不需要自定修改)]

struts-plugin.xml       [struts2的插件配置文件]

struts.xml             [我们写的业务配置文件(包含配置的Action]

 

访问资源:

3) 在内存中查询对应的Action配置,得到class内容,创建Action对象。

4)读取Action配置的method内容,执行Action对象对应的方法。

2.3 struts-default.xml文件的详解

1)声明struts2框架运行过程中使用到的一些对象

 

<bean class="com.opensymphony.xwork2.ObjectFactory" name="xwork" />

2)默认包,包名叫struts-default(注意:我们自己写的package必须继承这个默认包,只有继承了这个默认包才可以使用该默认包下的功能)

<package name="struts-default" abstract="true">

2.1)跳转类型:

常用的跳转类型

redirect:   重定向到页面

dispatcher: 转发到页面

redirectAction: 重定向到Action

chain:    转发到Action

 

<result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>

 

2.2 ) 声明拦截器(Interceptor

struts2默认的拦截器(32): 完成strutrs2的核心功能。(请求封装,文件上传,国际化..

 

 拦截器(Intercptor)  vs   过滤器(Filter

过滤器: 可以过滤任何类型的请求(htmlservletjsp)和响应。加入通用的代码逻辑。

拦截器: sturts2的特有功能。只能过滤Action!!在执行Action的时候加入通用的代码。

 

2.3) 声明拦截器栈 (<interceptor-stack name="basicStack">)

默认拦截器:

<interceptor-stack name="defaultStack">    (18个拦截器)

2.4 ) 默认包当前使用的拦截器:

<default-interceptor-ref name="defaultStack"/>

注意:

我们写的包(package)就是继承struts-default默认包的,那么就继承了默认的18个拦截器

 

2.5) 当前默认包下的默认Action

<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />

2.4 struts.xml文件详解

该文件是开发者自行配置的业务配置文件。(关键是Action的配置

1)包(package),用于管理Action,一般可以按模块划分包!!

package: 代表一个包。管理action配置。在用一个包下面不能有同名的action

name: 包名.在一个项目中不能出现同名的包。

extends:  继承。类似于类的继承。如果一个包继承另一个包,那么就会把父包的功能继承下来。

      我们开发的包就必须继承struts-default包。

namespace:  名称空间。区分不同的包的访问路径。默认值  “/

用户访问Action的路径搜索规则:

http://localhsot:8080/day28/namespace/actionname

namespace="/user"

http://localhost:8080/day28_struts/user/a/login2.action     ok

http://localhost:8080/day28_struts/user/login2.action        ok

http://localhost:8080/day28_struts/a/user/login2.action     不行!!  

      

用户访问: http://localhost:8080/day28_struts/user/a/b/login2.action

  先搜索:  http://localhost:8080/day28_struts/user/a/b/login2.action 没有,  有就返回

  接着搜索: http://localhost:8080/day28_struts/user/a/login2.action  没有,  有就返回

  再搜索 :  http://localhost:8080/day28_struts/user/login2.action      有,  有就返回(为止)     

 

abstract: 表示当前包是否抽象。如果当前包是抽象包,那么不能含有action. 抽象包中一般用来定义拦截器,公共视图,不做具体的业务。       

2Actionresult的配置

action配置:

 name:  action的名称。用于访问该Action的路径

 class:  Action业务对象的类名。一定是全名(包名+类名),这里struts2是用反射构造Action对象的

 method: 执行的业务方法。默认:execute

result配置:

 name: 视图的标记。在一个Action中名称不要重复!默认: success

 type: 跳转的类型。

     redirect: 重定向

     dispatcher: 转发(默认值)

     redirectAction: 重定向到Action

     chain:  转发到Action。可以在不同Action中通过request共享数据

     stream: 用在下载文件的时候。

 文本内容: 跳转到的页面或者Action

3)可以通过划分不同的xml文件来管理package

       <!-- 包含读取其他xml文件 注意: 声明的顺序就是读取的顺序!!!!-->

<include file="config/struts-book.xml"></include>

<include file="config/struts-user.xml"></include>

3 struts2Action三种使用方式

1第一种方式,不实现Action接口

// 第一种方式:不需要实现或继承任何接口或类

public class UserAction2 {

public String login()throws Exception{

System.out.println("UserAction2.login()");

return "success";

}

}

2第二种方式,实现Action接口

/** 第二种方式:实现Action接口

 * 1)定义了默认的execute方法的标准

 * 2)提供了项目中常用的视图标记

 */

public class UserAction implements Action {

public String login() throws Exception {

System.out.println("执行了UserActionlogin方法");

return SUCCESS;

}

public String execute() throws Exception {

return null;

}

}

3第三种方式,继承ActionSupport类(推荐)

/** 第三种方式: 继承ActionSupport(推荐使用)

 * 好处:

 * 1)提供了常用的视图标记

 * 2)提供了数据校验功能

 */

public class UserAction3 extends ActionSupport{

public String login()throws Exception{

System.out.println("UserAction3.login()");

return SUCCESS;

}

}

4 路径通配符

<!-- 一个模块(Action对象)使用一个action配置 -->

<!-- * (星号) :表示路径的通配符。   使用通配符的内容:{1}(表示获取第一个通配符的实际内容)  

好处: 大大地减少action的配置

-->

<!--

<action name="user_*" class="gz.itcast.b_path.UserAction" method="{1}">

     <result name="{1}">/{1}.jsp</result>

</action>

-->

 

<!-- 多个模块使用一个action配置

约定前提:  第一个*代表模块Action),第二个代表方法

ser_login

-->

<action name="*_*" class="gz.itcast.b_path.{1}Action" method="{2}">

     <result name="{2}">/{1}/{2}.jsp</result>

</action>

5 strus2的常量配置

struts2的常量就是用于在strut2的程序运行过程中使用的一些常量参数。

注意:

通过struts.xml文件声明<constant name="struts.action.extension" value="action,do,,"></constant>修改常量配置。

    指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出 

    <constant name="struts.i18n.encoding" value="UTF-8"/>

    自定义后缀修改常量 

    <constant name="struts.action.extension" value="action,do,,"/>

    设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭

    <constant name="struts.serve.static.browserCache" value="false"/>

    当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开

    <constant name="struts.configuration.xml.reload" value="true"/>

    开发模式下使用,这样可以打印出更详细的错误信息

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

    默认的视图主题

    <constant name="struts.ui.theme" value="simple" />

    与spring集成时,指定由spring负责action对象的创建 

    <constant name="struts.objectFactory" value="spring" />

该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性为false

注意: 如果打开动态方法调用,那么该Action对象下的所有方法都会对外暴露。存在一定安全隐患,所以通常把它关闭调用

    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>

    上传文件的大小限制 

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

修改临时文件存放的目录

<constant name="struts.multipart.saveDir" value="e:/temps/"></constant>

6 struts2的全局视图配置和默认配置

1)全局视图作用: 当该包下的所有action都使用到的一些视图就是可以放到全局视图配置中

注意:

action中也有相同名称的视图,那么action的局部视图会覆盖全局视图

<!-- 全局视图配置: 把该包下的所有action共用的视图都机集中在这里写 -->

<global-results>

<result name="success">/login.jsp</result>

</global-results>

2action的默认配置

<!-- 默认配置

 name: 必填项

 class: 可选项 。默认配置:  ActionSupport类   该类继承自struts-default <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />

 method: 可选。默认配置

    result:

     name: 可选。默认配置: success

     type: 可选。默认配置: dispatcher

 -->

 <!-- 全部使用默认配置的action的作用 :专门用于转发到WEB-INF下的页面 -->

 <action name="book">

  <result>/WEB-INF/jsp/login.jsp</result>

 </action>

 

7 Action的属性注入

作用: 如果Action对象中需要把一些经常改变的参数提取到配置文件中,那么就可以使用属性注入的方法。(相当于读取配置文件)

 

Action属性注入的步骤

1)在Action类中声明一个成员变量,用于接收xml配置文件传入内容

2)在Action类提供一个该变量的setter方法,该方法接收了xml配置的内容

//1)在action中提供一个属性

private String savePath;

//2)提供属性的setter方法,用于外部的action的参数进行注入

public void setSavePath(String savePath) {

this.savePath = savePath;

}

 

3)在对应的struts.xml文件中,找到对应的action对象的配置,然后在action中使用

<param name=""></param> 这个标签来向Action对象的属性注入内容

 

<action name="upload" class="gz.itcast.d_ioc.UploadAction" method="upload">

<!-- 3)使用该配置可以往Action对象的属性注入内容(只要有setter都可以使用param进行注入)

param:name: setter方法名。(setSavePath -> savePath)

-->

<param name="savePath">e:/images/</param>

<result>/login.jsp</result>

</action>

8以后都是Struts2Action的使用

8 sruts2的数据共享的三种方式

web项目中都是使用域对象来共享数据。

 

struts2提供给开发者使用域对象来共享数据的方法一共有三种。

 

8.1 第一种方式

ServletActionContext(静态方法)

getRequest() : 获取request对象

getRequest().getSession() : 获取session对象

getServletContext() : 获取ServletContext对象

注意:

1)该方式依赖servletapi,耦合比较高

2)如果要通过域对象来获取域对象的相关信息必须使用该方式

8.2 第二种方式

ActionContext

ActionContext.getContext().getContextMap() : 获取操作request域对象数据的map集合

        ActionContext.getContext().getSession() :     获取操作session域对象数据的map集合

ActionContext.getContext().getApplication()  获取操作context域对象数据的map集合

 

注意:

1)不依赖servletapi,耦合性低

2只能用在Action对象的一个方法中。不能在所有方法中都是用同一个ActionContext

3)  Action对象的方法比较少的时候使用,一般测试用

8.3 第三种方式

使用  RequestAware  ,   SessionAware   ApplicationAware 接口

注入操作对应域对象数据的Map集合

 

注意:

1)不依赖servletapi

2)可以在Action对象的所有方法中共享Map集合

3)  Action对象的方法比较多的时候使用

 

9请求参数数据的封装

9.1 直接赋值给简单数据类型

public class UserAction extends ActionSupport{

//参数赋值(注入方式)

private String name;

private String password;

private String gender;

private String[] hobit;

//参数通过这个set方法注入到Action

public void setName(String name) {

this.name = name;

}

public void setPassword(String password) {

this.password = password;

}

public void setGender(String gender) {

this.gender = gender;

}

public void setHobit(String[] hobit) {

this.hobit = hobit;

}

9.2 赋值给一个javabean对象

<form action="${pageContext.request.contextPath }/data/user_register.action" method="post">

     用户名: <input type="text" name="user.name"/><br/>

     密码: <input type="password" name="user.password"/><br/>

     性别: <input type="radio" name="user.gender" value=""/>男

      <input type="radio" name="user.gender" value=""/>女<br/>

     爱好:

     <input type="checkbox" name="user.hobit" value="篮球"/>篮球

     <input type="checkbox" name="user.hobit" value="足球"/>足球

     <input type="checkbox" name="user.hobit" value="羽毛球"/>羽毛球<br/>

     <input type="submit" value="注册"/>  

    </form>

 

public class UserAction2 extends ActionSupport{

//使用一个javabean对象接收

private User user;

public User getUser() {return user;}

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

 

注意:请求参数的封装通过struts2ParametersInterceptor拦截器进行赋值

10 自定义类型转换

作用: 默认情况下,页面的日期类型只能接收 yyyy-MM-dd类型,如果要转换yyyy/MM/dd这种类型,则需要使用自定义类型转换器进行转换。

strut2提供了自定义类型转换器的基类: StrutsTypeConverter类

// 自定义日期类型转换器

public class MyDateConverter extends StrutsTypeConverter{

SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd");

/**

 * 从页面的数据到服务器的类型转换

 * 参数一: context: 值栈上下文对象

 * 参数二: values:  从页面传递过来的参数值

 * 参数三: toClass: 转换到的类型。String->java.util.Date

 */

@Override

public Object convertFromString(Map context, String[] values, Class toClass) {

System.out.println("进入了转换器");

try {

//1)判断values是否为空

if(values==null || values.length==0){return null;}

if(values.length>1){

//多个值的情况

Date[] dates = new Date[values.length];

//2)取出数据进行转换

for(int i=0;i<dates.length;i++){

Date date = sdf1.parse(values[i]);

dates[i] = date;

}

return dates;

}else{

//一个值的情况

Date date = sdf1.parse(values[0]);

return date;

}

} catch (ParseException e) {

e.printStackTrace();

}

return null;

}

//从服务器到页面的类型转换(上面相反,用于从服JavaBean转换成String向页面输出)

@Override

public String convertToString(Map context, Object o) {

return null;

}

}

绑定自定义转换器的方式:

方式一: 局部绑定(只能绑定一个Action)

1)建立一个 Action的文件名-conversion.properties

2)一定和绑定的Action放在同一个目录下。

注意:转换器绑定到具体的属性。

user.birth=gz.itcast.g_convert.MyDateConverter

方式二: 全局绑定(绑定整个项目多个Action)(推荐使用)

1)建立一个xwork-conversion.properties

2)该文件一定放在src目录下。

注意:该方法,只要转换目标是ava.util.Date,都会使用该转换器(覆盖原来的转换器)

java.util.Date=gz.itcast.g_convert.MyDateConverter

11文件上传和下载

11.1 文件上传

1)三个条件:

表单有file

post提交

enctype="multipart/form-data"

 

2)Action中接收文件内容

File attach;   (attachfile表单的name属性)

String attachContentType;  文件类型

String attachFileName;   文件名称

 

细节:

1修改上传大小

修改默认文件上传大小

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

修改临时文件存放的目录

<constant name="struts.multipart.saveDir" value="e:/temps/"></constant>

2修改允许上传的文件类型和文件后缀

<action name="upload" class="gz.itcast.h_upload_down.UploadAction" >

<!-- FileUploadInterceptor拦截器的属性注入值(调用setter方法) -->

<interceptor-ref name="defaultStack">

       <!-- 改变当前文件上传拦截器的允许文件类型 -->

       <param name="fileUpload.allowedTypes">image/jpeg,image/jpg</param>

       <!-- 允许的文件后缀 -->

       <param name="fileUpload.allowedExtensions">jpg,jpeg,gif</param>

<!-- 如果以上配置都写了,那么取他们的交集  -->

</interceptor-ref>

</action>

11.2 文件下载

视图类型一定是stream类型

<action name="down_*" class="gz.itcast.h_upload_down.DownAction" method="{1}">

<!-- 文件下载的关键: 视图类型一定是stream -->

<result name="down" type="stream">

<!--  StreamResult类中的属性注入内容 -->

      <!-- 返回给浏览器的文件类型。返回通用的二进制 -->

<param name="contentType">application/octet-stream</param>

      <!-- 返回给浏览器的输入流 -->

   <param name="inputName">inputStream</param>

         <!-- 告诉浏览器的方式下载资源。${name}: 获取Action中的getName()方法的数据-->

   <param name="contentDisposition">attachment;filename=${name}</param>

   <!-- 缓存大小 -->

    <param name="bufferSize">1024</param>

</result>

</action>

 

Action对象中提供一个对应的获取输入流的方法

 

//需要提供给struts写出数据的输入流

public InputStream getInputStream(){

FileInputStream fis = new FileInputStream(new File(serverPath+name));

return fis;

}

posted @ 2018-05-09 15:47  风拂生  阅读(242)  评论(0编辑  收藏  举报