Struts2入门

Struts2入门
Struts2基本概述
    Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts 2是Struts的下一代产品,是在 struts 1和WebWork的技术基础上进行了合并的全新的Struts 2框架。其全新的Struts 2的体系结构与Struts 1的体系结构差别巨大。Struts 2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts 2可以理解为WebWork的更新产品。虽然从Struts 1到Struts 2有着太大的变化,但是相对于WebWork,Struts 2的变化很小。

WEB 层的框架都会基于前端控制器的模式
     什么是前端控制器模式呢?传统方式的开发,有一次请求就会对应一个Servlet。这样会导致出现很多 Servlet。而Struts2将所有的请求都先经过一个前端控制器,在前端控制器中实现框架的部分功能,剩下具体操作要提交到具体的Action中。那么所有的请求都会经过前端控制器,那用什么来实现前端控制器呢?过滤器就是最好的一个实现方式,因为需要所有的请求都可以被过滤器拦截 ,然后在过滤器中实现部分的功能 。所以Struts2的前端控制器也是有过滤器来实现的。


Struts入门案例
     首先到Struts2的官网:https://struts.apache.org/下载。

Struts2开发包的目录结构



创建web项目,拷入jar包
     可以解压apps目录下的struts2-blank.war文件,然后将WEB-INF目录下的lib拷贝到web项目的lib目录下就行了。其jar包如下:

Struts2项目依赖的基础JAR包说明

文件名
说 明
asm-3.3.jar
操作Java字节码的类库
asm-commons-3.3.jar
提供了基于事件的表现形式
asm-tree-3.3.jar
提供了基于对象的表现形式
struts2-core-2.3.24.jar
Struts2框架的核心类库
xwork-core-2.3.24.jar
WebWork核心库,Struts2的构建基础
ognl-3.0.6.jar
对象图导航语言(Object Graph Navigation Language),struts2框架通过其读写对象的属性
freemarker-2.3.22.jar
Struts2标签模板使用的类库
javassist-3.11.0.GA.jar
javaScript字节码解释器
commons-fileupload-1.3.1.jar
Struts2文件上传组件依赖包
commons-io-2.2.jar
Struts2的输入输出,上传文件依赖的jar包
commons-lang-2.4.jar
包含一些数据类型工具 ,是对java.lang包的增强
log4j-api-2.2.jar
Struts2的日志管理组件依赖包的api
log4j-core-2.2.jar
Struts2的日志管理组件依赖包
 
创建页面index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
     <head>
     <meta charset="UTF-8">
     <title>Struts2的案例</title>
     </head>
     <body>
     <%--
          通过超链接访问我们写的一个动作类
          动作类:就是struts2中用于处理请求的类。
          动作方法:动作类中接收请求的方法。
          struts2的核心控制器(StrutsPrepareAndExecuteFilter)默认会拦下以.action为后缀的url(或者没有任何后缀的URL),送入struts2核心内部,
      --%>
     <a href="${pageContext.request.contextPath}/hello.action">Hello Struts2.action</a>
     <br/>
     <a href="${pageContext.request.contextPath}/hello">Hello Struts2</a>
     </body>
</html>

编写一个Action
package com.pc.struts2.web.action;
/**
 * Struts测试类
 *
 * 它里面的方法都是动作方法
 * 动作方法编写规范:
 *        1、访问修饰符必须是public
 *        2、返回值类型必须是String
 *        3、方法不能有参数
 * @author Switch
 */
public class HelloAction {
     /**
      * 动作方法的作用就是负责处理请求
      * @return
      */
     public String helloworld() {
          System.out.println("Hello World");
          System.out.println("Hello Struts2");
          // 对应于struts.xml文件配置的result元素
          return "success";
     }
}

配置类根目录下的struts.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>
     <package name="pack1" extends="struts-default">
          <action name="hello" class="com.pc.struts2.web.action.HelloAction" method="helloworld">
              <result name="success" type="dispatcher">/success.jsp</result>
          </action>
     </package>
</struts>


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

PS:访问主机名/项目名/就能测试Struts2是否成功搭建了。

Struts2的执行流程





步骤:
1、客户端请求,生成相应的HttpServletRequest对象
2、Struts2核心过滤器,StrutsPrepareAndExecuteFilter进行拦截,(如果满足要求,进行拦截,不满足要求,放行)
3、ActionMapper动作映射类,将请求的路径与struts.xml中的配置进行对比,找到匹配的动作类
4、经过核心过滤器,然后创建匹配的动作类的代理类对象,进行一系列的配置,(读取配置文件struts.xml,确定执行那个方法)
5、通过一些拦截器,对数据进行预处理,比如说请求参数的封装就是在这进行
6、进入动作方法,进行业务处理
7、动作方法返回结果视图的名字,到ActionMapper找到对应的结果视图,进行结果视图预处理
8、反向经过5中的拦截器
9、生成HttpServletResponse对象,返回给客户端。

Struts2的执行过程



Struts2配置文件的加载顺序
     首先进入StrutsPrepareAndExecuteFilter该类的init方法









从源代码可以看出加载顺序是这样的:
配置文件
作用
能否更改
default.properties
struts2默认配置文件,主要配置一些key,value类的属性
不能改
struts-default.xml
struts2默认配置文件,主要配置一些模板类的东西
不能改
struts-plugin.xml
struts2默认配置文件,配置插件
不能改
struts.xml
配置Action以及常量
能改,推荐配置(修改)这个
struts.properties
配置常量
能改
web.xml
配置核心过滤器及常量
能改

PS:在web.xml中最后加载的内容都是和struts2配置相关的。 当配置重复时,后加载的覆盖先加载的。

default.properties
struts.i18n.encoding=UTF-8
struts2中的默认字符集,它解决了post请求的中文乱码。get没解决。
struts.multipart.maxSize=2097152
上传文件的最大限制是2MB
struts.action.extension=action,,
默认拦截的URL后缀为.action和没有后缀
struts.devMode = false
开启开发者模式。好处是修改struts.xml不用重启服务器

struts-default.xml

<bean class="com.opensymphony.xwork2.ObjectFactory" name="struts"/>
指定实例化Action类的工厂


struts.xml文件的配置
     Struts2 框架的核心配置文件是struts.xrnl 文件,该文件主要用来配置Action和请求的对应关系。

package的配置
     <!-- package标签:
              作用:分包来管理动作配置。把配置文件按照面向对象的思想来管理
              属性:
                   name属性:指定包的名称。必须写,且必须唯一。
                   extends属性:指定当前包的父包。子包自动具备父包的配置。我们一般都继承struts-default包。
                                struts-default包在struts-default.xml中定义着。如果不继承该包,就不能使用struts2的核心功能。
                   abstract属性:把当前包声明为抽象包。抽象包就是用来被继承。里面可以定义一些公共的配置。
                                   只有没有action标签的包才能声明为抽象包。
                   namespace属性:它是把访问URL按照模块化来管理。
                                      以后我们在浏览器地址栏中访问的URL就变成了
                                           名称空间+动作名称(指的是action标签中name属性的取值)
                                           例如:/user/add_User.action
                                      名称空间的写法:
                                           必须以/开头。后面不能是中文。
                                           可以允许有多级。例如:/n1/n2/n3
                                      名称空间有默认值:
                                           默认值是:""
     -->

action的配置
          <!-- action标签:
                   作用:定义动作名称和动作类以及动作方法的对应关系。
                   属性:
                        name属性:指定的是动作名称。必须唯一。
                        class属性:指定的是动作类
                        method属性:指定的是动作方法名称。
                   定义动作类的三种方式:
                        第一种:无侵入式的            例如HelloAction        不用
                        第二种:实现Action接口        例如Hello2Action       不用
                        第三种:继承ActionSupport    例如Hello3Action       实际开发中采用的方式
                   访问Action的方式
                        使用通配符来访问
          -->

result的配置
            <!-- result标签:
                    作用:配置结果视图。当动作方法的返回值和该标签name属性一致时,采用type属性指定的方式,前往指定的地址。
                    属性:
                        name属性:逻辑结果视图。和动作方法的返回值保持一致。success是name属性的默认值
                        type属性:采用何种方式前往指定的地址。
                            常用取值:
                                dispatcher:请求转发(默认值)
                                redirect:重定向。它不仅可以重定向到一个页面,也可以重定向到另外一个动作。
                                redirectAction:重定向到另外一个动作
            -->

Struts2中result预定义的type
属性
说明
chain
用来处理Actíon链,被跳转的Action中仍能获取上个页面的值,如request信息。
dispatcher
用来转向页面,通常处理JSP,是默认的结果类型。
freemarker
用来整合FreeMarker模板结果类型。
httpheader
用来处理特殊的HTTP行为结果类型。
redirect
重定向到一个URL,被跳转的页面中丢失传递的信息。
redirectAction
重定向到一个Action,跳转的页面中丢失传递的信息。
stream
向浏览器发送InputStream对象,通常用来处理文件下载,还可用于Ajax数据。
velocity
用来整合Velocity模板结果类型。
xslt
用来整合XML/XSLT结果类型。
plainText
显本原始文件内容,例如文件源代码。
postback
使得当前请求参数以表单形式提交

Struts2常量的配置
     Struts2的这些常量大多在默认的配置文件中己经配置好,但根据用户需求的不同,开发的要求也不同,可能需要修改这些常量值 ,修改的方法就是在配置文件对常量进行重新配置。

Struts2常量配置共有3种方式,分别如下:
  • 在 struts.xm1文件中使用<constant>元素配置常量。
  • 在 struts.properhes文件中配置常量。
  • 在web.xml文件中通过<init-param>元素配置常量。
<?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>
     <!-- 开启开发者模式:用到的标签constant。属性name:配置文件的key。属性value:配置文件的值 -->
     <constant name="struts.devMode" value="true"/>

     <!-- 设置默认访问url的后缀为.struts2 -->
     <constant name="struts.action.extension" value="struts2"/>

     <package name="pack1" extends="struts-default">
          <action name="hello" class="com.pc.struts2.web.action.HelloAction" method="helloworld">
              <result name="success" type="dispatcher">/success.jsp</result>
          </action>
     </package>
</struts>

struts.action.extension=do

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <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>html</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

分模块开发的配置
<struts>
     <!--包含了4个配置文件-->
     <!--不指定路径默认在src下找--〉
     <include file="struts-1.xml"/>
     <include file="struts-2.xml"/>
     <include file="struts-3.xml"/>
     <!--配置文件在具体包中时的方式-->
     <include file="com/pc/action/struts4.xml"/>
<Istruts>

Action的三种编写方式

简单的POJO类
package com.pc.struts2.web.action;
/**
 * Struts测试类
 *
 * 它里面的方法都是动作方法
 * 动作方法编写规范:
 *        1、访问修饰符必须是public
 *        2、返回值类型必须是String
 *        3、方法不能有参数
 * @author Switch
 */
public class HelloAction {
     /**
      * 动作方法的作用就是负责处理请求
      * @return
      */
     public String helloworld() {
          System.out.println("Hello World");
          System.out.println("Hello Struts2");
          // 对应于struts.xml文件配置的result元素
          return "success";
     }
}

实现Action接口
package com.pc.struts2.web.action;

import com.opensymphony.xwork2.Action;

/**
 * 创建方式2,实现Action接口
 * @author Switch
 */
public class Hello2Action implements Action{

     @Override
     public String execute() throws Exception {

          return SUCCESS;
     }
}


Action接口中提供了 5个己经定义的常量如下:
  • SUCCESS 代表成功
  • NONE 代表页面不跳转
  • ERROR 代表跳转到错误页面
  • INPUT 数据校验的时候跳转的路径
  • LOGIN 用来跳转到登录页面

继承ActionSupport类
package com.pc.struts2.web.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 实现方法三:继承ActionSupport类
 * @author Switch
 */
public class Hello3Action extends ActionSupport{

     public String sayHello(){
          return SUCCESS;
     }
}

Action的访问

struts.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>
     <!-- 开启开发者模式:用到的标签constant。属性name:配置文件的key。属性value:配置文件的值 -->
     <constant name="struts.devMode" value="true"/>

     <!-- 设置默认访问url的后缀为.action -->
     <constant name="struts.action.extension" value="action"/>
     <!-- package标签:
              作用:分包来管理动作配置。把配置文件按照面向对象的思想来管理
              属性:
                   name属性:指定包的名称。必须写,且必须唯一。
                   extends属性:指定当前包的父包。子包自动具备父包的配置。我们一般都继承struts-default包。
                                struts-default包在struts-default.xml中定义着。如果不继承该包,就不能使用struts2的核心功能。
                   abstract属性:把当前包声明为抽象包。抽象包就是用来被继承。里面可以定义一些公共的配置。
                                   只有没有action标签的包才能声明为抽象包。
                   namespace属性:它是把访问URL按照模块化来管理。
                                      以后我们在浏览器地址栏中访问的URL就变成了
                                           名称空间+动作名称(指的是action标签中name属性的取值)
                                           例如:/user/add_User.action
                                      名称空间的写法:
                                           必须以/开头。后面不能是中文。
                                           可以允许有多级。例如:/n1/n2/n3
                                      名称空间有默认值:
                                           默认值是:""
     -->
     <package name="myDefault" extends="struts-default" abstract="true">
          <!-- 定义一些公共的配置:针对当前web工程的 -->
     </package>

     <package name="pack1" extends="myDefault" namespace="">
          <!-- action标签:
                   作用:定义动作名称和动作类以及动作方法的对应关系。
                   默认class是ActionSupport,默认method是execute
                   属性:
                        name属性:指定的是动作名称。必须唯一。
                        class属性:指定的是动作类
                        method属性:指定的是动作方法名称。
                   定义动作类的三种方式:
                        第一种:无侵入式的            例如HelloAction        不用
                        第二种:实现Action接口        例如Hello2Action       不用
                        第三种:继承ActionSupport    例如Hello3Action       实际开发中采用的方式
                   访问Action的方式
                        使用通配符来访问
          -->
          <action name="hello" class="com.pc.struts2.web.action.HelloAction" method="helloworld">
              <result name="success" type="dispatcher">/success.jsp</result>
          </action>
     </package>

     <!-- 访问动作的最原始方式 -->
     <!--      <package name="crud" extends="myDefault" namespace="/crud">
          <action name="add_User" class="com.pc.struts2.web.action.UserAction" method="addUser">
              <result name="success">/success.jsp</result>
          </action>

          <action name="update_User" class="com.pc.struts2.web.action.UserAction" method="updateUser">
              <result name="success">/success.jsp</result>
          </action>

          <action name="delete_User" class="com.pc.struts2.web.action.UserAction" method="deleteUser">
              <result name="success">/success.jsp</result>
          </action>

          <action name="find_User" class="com.pc.struts2.web.action.UserAction" method="findUser">
              <result name="success">/success.jsp</result>
          </action>
     </package> -->

     <!-- 使用通配符来访问动作   通配符是* -->
     <package name="crud" extends="myDefault" namespace="/crud">
          <!-- 动作名称格式为*_*,可以匹配如add_User,add_Product -->
          <!-- 可以通过{第几个通配符}来代表相应字符串 -->
          <action name="*_*" class="com.pc.struts2.web.action.{2}Action" method="{1}{2}">
              <result name="success" type="dispatcher">/success.jsp</result>
          </action>
     </package>
</struts>

user.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
     <head>
          <meta charset="UTF-8">
          <title>用户操作</title>
     </head>
     <body>
          <a href="${pageContext.request.contextPath}/crud/add_User.action">添加用户</a>
          <a href="${pageContext.request.contextPath}/crud/update_User.action">修改用户</a>
          <a href="${pageContext.request.contextPath}/crud/delete_User.action">删除用户</a>
          <a href="${pageContext.request.contextPath}/crud/find_User.action">查询用户</a>
     </body>
</html>

product.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
     <head>
          <meta charset="UTF-8">
          <title>商品操作</title>
     </head>
     <body>
          <a href="${pageContext.request.contextPath}/crud/add_Product.action">添加商品</a>
          <a href="${pageContext.request.contextPath}/crud/update_Product.action">修改商品</a>
          <a href="${pageContext.request.contextPath}/crud/delete_Product.action">删除商品</a>
          <a href="${pageContext.request.contextPath}/crud/find_Product.action">查询商品</a>
     </body>
</html>

package com.pc.struts2.web.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 产品Action
 *
 * @author Switch
 * @data 2016年11月16日
 * @version V1.0
 */
public class ProductAction extends ActionSupport {

     public String addProduct() {
          System.out.println("添加产品");
          return "success";
     }

     public String updateProduct() {
          System.out.println("更新产品");
          return "success";
     }

     public String deleteProduct() {
          System.out.println("删除产品");
          return "success";
     }

     public String findProduct() {
          System.out.println("查找产品");
          return "success";
     }
}

package com.pc.struts2.web.action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 用户Action
 *
 * @author Switch
 * @data 2016年11月16日
 * @version V1.0
 */
public class UserAction extends ActionSupport {

     public String addUser() {
          System.out.println("添加用户");
          return "success";
     }

     public String updateUser() {
          System.out.println("更新用户");
          return "success";
     }

     public String deleteUser() {
          System.out.println("删除用户");
          return "success";
     }

     public String findUser() {
          System.out.println("查找用户");
          return "success";
     }
}

package com.pc.struts2.web.action;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
/**
 * 访问ServletAPI的方式
 *
 * 使用Struts2框架提供了一个工具类:
 *         ServletActionContext
 * 它里面提供了对应的静态方法,可以直接获取ServletAPI
 *
 * 有一个需要注意的问题:
 *        org.apache.struts2.dispatcher.StrutsRequestWrapper@4637b3
 *        org.apache.catalina.connector.ResponseFacade@1f2f2f7
 *        org.apache.catalina.session.StandardSessionFacade@12d77c1
 *        org.apache.catalina.core.ApplicationContextFacade@1133ff
 *       
 *        requet对象已经不是原来tomcat提供的了,而是被struts2框架包装过了。
 *         包装使用的是装饰者模式。
 *        装饰者模式的作用是对方法进行增强。
 *
 * @author Switch
 */
public class ActionAPITest extends ActionSupport {
    /**
     * 在Struts2框架中使用ServletAPI
     * @return
     */
    public String useServletAPI() {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        HttpSession session = request.getSession();
        ServletContext application = ServletActionContext.getServletContext();
        System.out.println(request);
        System.out.println(response);
        System.out.println(session);
        System.out.println(application);
        return "success";
    }
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值