Fork me on GitHub

Struts2框架基础

Struts2框架基础

1.Java的框架

1.1.框架简介

在大型项目开发过程中,经常会使用到一些框架,这样做好的好处是能够提高工作效率,在java中最常用的的框架就是SSH,这其实是三个框架的简称。
java web的开发也是遵循着MVC模式,从jsp代表的视图层,到servlet代表的控制层,service代码的逻辑层和dao代表的数据库层,通过一些框架,使其能够提供更加快捷的开发

框架在软件中其实就是一种半成品,有些功能已经实现了,这样,当我们的项目开发建立在框架上时,就可以提高开发效率

SSH框架在MVC模式中的位置及其作用:

这三个框架都将要学习

1.2.Struts2框架

struts框架是对应servlet控制层的框架,使用这个框架将用action取代servlet。
struts1最早是一种基于MVC模式的框架
struts2是在struts1的基础上,融合了xwork的功能,也就是说:Struts2 = struts1 + xwork
struts2框架预先实现了一些功能:
1.请求数据自动封装
2.文件上传的功能
3.对国际化功能的简化
4.数据效验功能
5.………………

2.Struts2开发流程

本处使用struts2的版本是2.3

2.1.引入jar文件

使用struts2要引入的jar文件比较多,必须引用的有八种,可以单独引用,如果是使用idea创建struts2时,可以选择下载或者执行的包含这些jar的包
必须要引入的八种jar是:

  • commons-fileupload-1.2.2.jar 【和io一起是文件上传的相关包】
  • commons-io-2.0.1.jar
  • struts2-core-2.3.4.1.jar 【struts2核心功能包】
  • xwork-core-2.3.4.1.jar 【xwork核心包】
  • ognl-3.0.5.jar 【ognl表达式功能支持包】
  • commons-lang3-3.1.jar 【struts对java.lang包的扩展】
  • freemarker-2.3.19.jar 【struts的标签模板jar文件】
  • javassist-3.11.0.GA.jar 【struts对字节码的处理相关jar 】

2.2.配置web.xml

初始化struts核心功能:

Tomcat启动时会加载自身的web.xml文件,然后加载项目所需的web.xml
Struts通过在项目的web.xml引入过滤器来完成Struts的核心功能的初始化。即Struts核心功能的初始化是通过过滤器来完成的。
前面有文章说过过滤器的方法(init,doFilter,destory)

注意过滤器写的是.StrutsPrepareAndExecuteFilte这个类,struts1.8之前也使用过其他的类,但现在一般都是.StrutsPrepareAndExecuteFilte

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
   <!-- 引入struts核心过滤器 -->
    <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>
</web-app>

2.3.开发Action

action类,也叫作动作类,一般继承ActionSupport类,即处理请求的类,Struts中的action类取代了之前的servlet

在写action类中的业务方法来处理具体请求时,要注意以下两个方面:
1.业务方法必须返回String
2.方法不能有参数

代码示例:

package action;

import com.opensymphony.xwork2.ActionSupport;

/**
 * 开发action,处理请求
 * Created by cenyu on 16-12-22.
 */
public class HelloAction extends ActionSupport {
    //处理请求
    @Override
    public String execute() throws Exception {
        System.out.println("访问到了action,正在处理请求");
        System.out.println("调用service");
        return "success";
    }
}

2.4.配置struts.xml

如果是用IDEA自动创建的Struts项目,则会自动创建struts.xml文件,如果不是就要在项目的src目录下创建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="hello" namespace="/" extends="struts-default">
        <action name="hello" class="action.HelloAction" method="execute">
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

2.5.Struts2执行流程

首先是服务器启动:
1.加载项目web.xml
2.web.xml的StrutsPrepareAndExecuteFilter过滤器被初始化,初始化过程中执行该类的init()方法,该方法中又会初始化以下几个配置文件:

struts-default.xml, 核心功能的初始化
struts-plugin.xml, struts相关插件
struts.xml, 用户编写的配置文件

如果要在该文件中创建另外的拦截器,则放在Struts的核心过滤器上面
服务器启动之后开始访问资源,继续执行以下步骤:
3.用户访问Action,服务器根据访问路径名称,找对应的action配置,创建action对象
4.执行默认拦截器栈中定义的18个拦截器
5.执行action的业务处理方法

注意:上面过滤器和action的执行顺序是:创建action-->拦截器-->业务处理方法

struts-default.xml配置文件
该配置文件目录在struts的核心包里面:struts2-core.jar/struts-default.xml
分析该文件内容:
1.bean节点指定struts在运行的时候创建的对象类型

    <bean type="com.opensymphony.xwork2.security.ExcludedPatternsChecker" name="struts" class="com.opensymphony.xwork2.security.DefaultExcludedPatternsChecker" scope="default" />

2.指定struts-default包(用户写的package(struts.xml)一样要继承此包)
package struts-default包定义了:
a.跳转的结果类型

  • dispatcher 转发,不指定默认为转发
  • redirect 重定向
  • redirectAction 重定向到action资源
  • stream (文件下载的时候用)
<result-types>
            <result-type name="chain" class="com.opensymphony.xwork2.ActionChainResult"/>
            <result-type name="dispatcher" class="org.apache.struts2.dispatcher.ServletDispatcherResult" default="true"/>
            <result-type name="freemarker" class="org.apache.struts2.views.freemarker.FreemarkerResult"/>
            <result-type name="httpheader" class="org.apache.struts2.dispatcher.HttpHeaderResult"/>
            <result-type name="redirect" class="org.apache.struts2.dispatcher.ServletRedirectResult"/>
            <result-type name="redirectAction" class="org.apache.struts2.dispatcher.ServletActionRedirectResult"/>
            <result-type name="stream" class="org.apache.struts2.dispatcher.StreamResult"/>
            <result-type name="velocity" class="org.apache.struts2.dispatcher.VelocityResult"/>
            <result-type name="xslt" class="org.apache.struts2.views.xslt.XSLTResult"/>
            <result-type name="plainText" class="org.apache.struts2.dispatcher.PlainTextResult" />
            <result-type name="postback" class="org.apache.struts2.dispatcher.PostbackResult" />
        </result-types>

b.定义所有的拦截器

  • 定义了32个拦截器
    为了拦截器引用方便,可以通过定义栈的方式引用拦截器,此时如果引用了栈,栈中的连接器都会被引用
  • defaultStack,默认的栈,其中定义默认要执行的18个拦截器
 <interceptors>
            <interceptor name="alias" class="com.opensymphony.xwork2.interceptor.AliasInterceptor"/>
            <interceptor name="autowiring" class="com.opensymphony.xwork2.spring.interceptor.ActionAutowiringInterceptor"/>
</interceptors>
<default-interceptor-ref name="defaultStack"/>

c.默认执行的拦截器栈,默认执行的action

	<default-interceptor-ref name="defaultStack"/>
               <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
<interceptor 
name="prepare" class="com.opensymphony.xwork2.interceptor.PrepareInterceptor"/>
<interceptor 
name="params" class="com.opensymphony.xwork2.interceptor.ParametersInterceptor"/>

拦截器与过滤器的区别:
拦截器和过滤器的功能是类似的
共同点:

都拦截资源!

区别:

过滤器,拦截器所有资源都可以; (/index.jsp/servlet/img/css/js)
拦截器,只拦截action请求。
过滤器是servlet的概念,可以在struts项目、servlet项目用。
拦截器是struts的概念,只能在struts中用。

3.Struts配置详解

3.1.Struts.xml文档结构

package 定义一个包,作用是管理action,通常,一个业务模块用一个包;例如用户user包,订单包等等

  • name是包的名字,包名不能重复,否则启动就出报错;
  • extends 当钱包继承自那个包,在struts中,包一定要继承struts-default,struts-default在struts核心jar中的struts-default.xml中定义的包
  • abstract表示当前包为抽象包,抽象包不能有action的定义,否则运行时期报错, 只有当前的包被其他包继承时才能用abstract=true;
  • namespace 名称空间,默认为“/”,作为路径的一部分

最终的访问路径:http://localhost:8080/项目/名称空间/action的name值

action 配置请求路径与Action类的映射关系

  • name 请求路径名称
  • class 请求处理的action类的全名
  • method 请求处理方法

result

  • name action处理方法返回值
  • type 跳转的结果类型
  • 标签体中指定跳转的页面

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="hello" namespace="/" extends="struts-default">
        <action name="hello" class="action.HelloAction" method="execute">
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>

最佳实践方式是可以将配置文件放在不同的包下,如登录的配置文件就放在登录的包下,地址的配置文件就放在地址的包下,每个包下的配置文件的写法只需要写自己的那部分,其他部分的不用写,具体配置的写法跟上面是一样的。
然后在src/struts.xml的总配置文件中使用include将各个配置文件引入进来,总的配置文件的写法如下:

<?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>
<!--struts在运行时候会加载这个总配置文件:src/struts.xml-->
    
    <!--总配置文件中引入其他所有的配置文件-->
    <include file="action/login.xml"></include>
    <include file="add/address.xml"></include>
</struts>

3.2.Struts2的action开发的几种方式

方式一继承ActionSupport

package a_config;

import com.opensymphony.xwork2.ActionSupport;


/**
 * 对action开发方式一:
 * 使用继承ActionSupport类开发action
 */
public class UserAction extends ActionSupport{

    //Action中的业务处理方法
    public String login(){
        System.out.println("UserAction.login");
        return "success";
    }
}

注意:如果要用Struts的数据效验功能,必须继承此类

方式二:实现Action接口(com.opensymphony.xwork2.Action)
Action接口的源码如下:

public interface Action {
    String SUCCESS = "success";
    String NONE = "none";
    String ERROR = "error";
    String INPUT = "input";
    String LOGIN = "login";

    String execute() throws Exception;
}

使用Action接口实现action类的方式是:

package a_config;

import com.opensymphony.xwork2.Action;

/**
 * 对action开发方式二:
 * 使用实现Action接口开发action类
 */
public class UserAction2 implements Action{
    public String login(){
        System.out.println("UserAction2.login");
        return SUCCESS;
    }
    public String execute() throws Exception {
        return null;
    }
}

方式三:不继承任何类,不实现任何接口
此方式就是直接写类,不继承不实现,配置文件没有变化,使用这种方式时,拦截器对请求数据的自动封装仍然有效

package a_config;

/**
 * 对action开发方式三:
 * 不继承任何类,不实现任何接口
 */
public class UserAction3 {
    public String login(){
        System.out.println("UserAction2.login");
        return "success";
    }
}

注意,三种方法中,经常使用的是第一种继承的方式

3.3.通配符

在Struts的配置信息中,可以用*与{1}来优化配置!

<?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="config" namespace="/user" extends="struts-default" abstract="false">
        <!--当一个action类中有不同的业务处理方法时-->
        <!--<action name="login" class="a_config.UserAction" method="login">-->
            <!--<result name="success">/index.jsp</result>-->
        <!--</action>-->

        <!--<action name="register" class="a_config.UserAction" method="register">-->
            <!--<result name="success">/index.jsp</result>-->
        <!--</action>-->

        <!--使用通配符优化上面的步骤操作-->
        <action name="user_*" class="a_config.UserAction" method="{1}">
            <result name="{1}">/{1}.jsp</result>
        </action>
    </package>
</struts>

3.4.Struts中路径匹配原则

在上面修改的struts.xml配置文件中,名称空间(namespace)设置的为:/user。action的访问名称(action下的name)为“user_*"。则

访问路径:http://localhost:8080/Struts02/user/user_login 成功
访问路径:http://localhost:8080/Struts02/user/a/b/user_login 成功
访问路径:http://localhost:8080/Struts02/a/b/user_login 失败

Tomcat路径分析:
localhost:找到访问那一台机器
8080:找到tomcat
Struts02: 找到项目名称
/user/a/b: 先看有没有这个名称空间,没找到,继续向下,找到就返回
/user/a : 再看有没有这个名称空间,没找到,继续向下,找到就返回
/user : 再看有没有这个名称空间,没找到,继续向下,找到就返回
/ : 默认名称空间,还没找到,报错! 找到就返回

所以struts中的路径中,名称空间和action名称之间可以多出几个路径,也可以访问到资源,开发的时候要注意这个问题

3.5.Struts常量

Struts中默认访问后缀
struts1中默认访问后缀 *.do
struts2中默认访问后缀 *.action
这个后缀平常可以省略,在xml配置文件中不可以写,在jsp脚本中的链接可以写

如何修改默认访问后缀:
1.Struts2的.action访问后缀在哪里定义呢?
定义后缀的配置文档在:struts2-core-2.3.4.1.jar!/org/apache/struts2/default.propertiesstruts.action.extension=action,,指定
2.修改方式
修改的话不用在default.propertiesh中修改,直接在项目struts.xml配置文件中修改对应的全局变量就可以了
此处修改为指定访问后缀为action/do/没有访问后缀都可以。
要注意后面的逗号是不能少的

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

    <!--1.全局配置-->
    <!--修改Struts默认的访问后缀-->
    <constant name="struts.action.extension" value="action,do,"></constant>



    <!--2.总配置文件,引入其他所有配置文件-->

    <include file="a_config/struts.xml"></include>
</struts>

对于上面修改后缀名称的时候:
value="action,do," : 后缀可以使用action或do或不带后缀
value="action,do" : 后缀只能使用action或do后缀

其他一些常用的全局变量,可以现在一个constant.xml常量配置文件中定义好,然后在总是的src/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>

    <!--一.全局配置常量-->
    <!--1.指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法 和freemarker 、velocity的输出-->
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <!--2.自定义后缀修改常量-->
    <constant name="struts.action.extension" value="action,do,"/>
    <!--3.设置浏览器是否缓存静态内容,默认值为true(生产环境下使用),开发阶段最好关闭-->
    <constant name="struts.serve.static.browserCache" value="false"/>
    <!--4.当struts的配置文件修改后,系统是否自动重新加载该文件,默认值为false(生产环境下使用),开发阶段最好打开-->
    <constant name="struts.configuration.xml.reload" value="true"/>
    <!--4.开发模式下使用,这样可以打印出更详细的错误信息-->
    <constant name="struts.devMode" value="true" />
    <!--5.默认的视图主题-->
    <constant name="struts.ui.theme" value="simple" />
    <!--6.与spring集成时,指定由spring负责action对象的创建-->
    <constant name="struts.objectFactory" value="spring" />
    <!--7.该属性设置Struts 2是否支持动态方法调用,该属性的默认值是true。如果需要关闭动态方法调用,则可设置该属性默认为 false-->
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    <!--8.上传文件的大小限制-->
    <constant name="struts.multipart.maxSize" value="10701096"/>

</struts>

动态方法调用语法:
actionName+!+业务处理方法名。即为动态方法调用

3.6.全局配置,配置的各项默认值

1.配置全局跳转视图:
例如当返回值都是success全部要返回到一个指定的页面index.jsp时,可以使用全局配置。

<?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="config" namespace="" extends="struts-default" abstract="false">
        <!--配置全局跳转视图-->
        <global-results>
            <result name="success">/index.jsp</result>
        </global-results>



        <action name="login" class="a_config.UserAction" method="login">
            <result name="success">/index.jsp</result>
        </action>

        <action name="register" class="a_config.UserActio2n" method="register">
            <!--返回结果标记success对应的页面在当前action中没有配置,
            所有会去找全局配置是否有success标记对应的页面-->
        </action>




    </package>
</struts>

2.配置各项默认值

<?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="config" namespace="" extends="struts-default" abstract="false">
        <!--配置全局跳转视图-->
        <global-results>
            <result name="success">/index.jsp</result>
        </global-results>

        <!--配置各项默认值-->
        <!--
            name: 配置了访问路径名称
            class: 默认执行的action在struts-default有配置
                       <default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
            method: 默认为excute
            默认的excute返回值是success,对应的页面去全局视图中查询,此处我们定义了全局视图为index.jsp
        -->
        <action name="login" class="a_config.UserAction" method="login">
            <result name="success">/index.jsp</result>
        </action>

        <!--什么情况不配置class?即处理的action-->
        <!--答案:当只是需要跳转到WEB-INF下资源的时候-->
        <action name="test">
            <result name="success">/WEB-INF/index.jsp</result>
        </action>
    </package>
</struts>
posted @ 2016-12-25 16:58  洋葱源码  阅读(631)  评论(0编辑  收藏  举报