JAVAEE框架学习——Struts2——介绍、搭建、配置

Struts2介绍

Struts2是一种基于MVC模式的轻量级Web框架。本质上相当于一个Servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。

Struts2优势

  • 自动封装参数
  • 参数校验
  • 结果的处理 转发 重定向
  • 国际化
  • 显示等待页面
  • 防止重复提交


    Struts2优势

WEB层框架基于的前端控制器模式

在传统的开发中,有一次请求就会对应一个Servlet。这样会导致出现很多的Servlet。而Struts2将所有请求都先经过一个前端控制器,在前端控制器中实现框架的部分功能。具体的操作交到具体的Action中。


传统开发方式
前端控制器模型

快速入门

下载Struts2开发包

解压开发包

  • 解压后的目录结构如下:


    解压后的目录
  • apps:该文件夹用于存放官方提供的Struts2示例程序。
  • docs:该文件夹用于存放官方提供的Struts2文档
  • lib:该文件夹用于存放Struts2的核心类库。以及Struts2的第三方插件类库

创建一个web工程引入相应jar包

可以参考apps下的一些示例代码,其中struts2-blank.war是struts2的空工程,我们可以查看它的lib目录


基本开发包

这些就是基本的开发包了,具体含义如下:


基本开发包解释

创建一个页面:放置一个链接

首先需要在WebContent下创建一个目录demo1,在demo1下创建一个新的jsp 在jsp中编写

创建Action

/**
 * @Auther: wxblack-mac
 * @Date: 2018/5/23 16:49
 * @Description: Struts2 Action类
 */
public class HelloAction {
    
    public String hello() {
        System.out.println("hello world");
        return "success";
    }
}

编写配置文件 struts.xml

引入dtd约束文件

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

将struts2配置到web.xml中

由于Struts2是基于filter,所以需要配置Struts2的核心过滤器

  <!--配置Struts2核心过滤器-->
    <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>

Struts2框架架构演示

访问过程

架构图.png

AOP思想

核心配置详解

Struts2 核心配置 Struts.xml

<struts>
    <!--
        package:将Action配置封装,可以在Package中配置很多action
        name属性:给包起个名字,起到标识作用,不能与其他包名重复
        namespace属性:给action定义一个访问前缀,指定一个命名空间
        extends属性:继承一个指定包,struts2默认提供一个struts-default用于继承,必须继承
        由于struts2的配置文件是从上到下处理的,所以父包应该在子包前面定义
        abstrac属性:包是否为抽象的;标识性属性。抽象包意味着该包不能包含Action定义
    -->
    <package name="hello" namespace="/hello" extends="struts-default">
        <!--
        action:配置Action类
               name属性:决定了action访问的资源名 指定该Action所处理的请求的URL
               class属性:指定action资源完整类名
               method:指定具体调用action的哪个方法
        -->
        <action name="HelloAction" class="cn.probuing.struts2lesson.action.HelloAction"
                method="hello">
            <!--
                result:结果配置
                        name属性:标识结果处理的名称与action方法的返回值对应
                        type属性:指定调用哪一个Result类来处理结果 默认使用转发处理结果
                        标签体:填写处理页面的相对路径
            -->
            <result name="success">/hello.jsp</result>
        </action>
    </package>
</struts>

Struts2常量配置

Struts默认常量配置位置

默认常量配置

修改Struts2常量配置

第一种 在struts.xml文件中使用<constant> 标签 开发中常用

struts.xml

第二种 在src下创建strtus.properties文件

struts.properties

struts.properties

第三种 在项目的web.xml中

web.xml

以上的顺序 也是配置文件的加载顺序 后加载的会覆盖先加载的

常量配置

基本常量配置

<!--常量配置-->
    <!--
        国际化常量配置 可以解决POST提交乱码
    -->
    <constant name="struts.i18n.encoding" value="utf-8"/>
    <!--
    指定访问action时的后缀名,两个逗号表示分割后缀名 两个逗号间为空 表示可以不加后缀
    -->
    <constant name="struts.action.extension" value=",,"/>

    <!--
        开发模式
        提供热加载主配置
        提供更多的错误信息输出,方便开发的时候调试
    -->
    <constant name="struts.devMode" value="true"/>
  • 通常 Struts2框架按如下搜索顺序加载Struts2常量:
    • struts-default.xml 该文件保存在struts2-core-2.5.14.jar文件中
    • struts-plugin.xml Struts2等插件中
    • struts.xml web应用默认的Struts2配置文件
    • struts.properties Struts2默认的配置文件
    • web.xml 该文件是Web应用的配置文件
      如果在多个文件中配置了同一个Struts2常量,则后一个文件中配置的常量会覆盖前面文件中配置的常量值

配置进阶

Struts2动态方法调用

动态方法调用指的是:
我们在配置struts.xml需要配置method属性 代表调用的方法,如果调用的方法过多则会出现复杂且冗余的method配置,这样显然是不合理的。Struts2提供了动态的方法调用,可以让我们在调用方法时 指定方法的名称 调用对应的方法。这样可以大大简化我们的配置

方式一:
  • 需要开启动态方法调用
  <!--配置动态方法调用常量 false: 关闭 true 开启 默认关闭-->
    <constant name="struts.enable.DynamicMethodInvocation" value="true"/>
  • 不需要配置method属性
  <package name="dynamic" namespace="/dynamic" extends="struts-default">
        <action name="Demo1Action" class="cn.probuing.strutsLesson.dynamic.Demo1Action">
            <result name="success">/hello.jsp</result>
        </action>
    </package>
  • 在调用时 通过 !方法名 来指定方法的调用
http://localhost:8080/ss/dynamic/Demo1Action!add
> 表示调用Demo1Action中的add方法

这种方式有一个弊端:由于地址路径的特殊,对SEO优化不友好

方式二:
  • 通配符方式 动态方法调用
<package name="dynamic" namespace="/dynamic" extends="struts-default">
        <!--
            指定name 为 xxx_*时 在前缀匹配到的时候 *代表任何字符
            Struts2会将*号的值记录下来 填充到{1}中
        -->
        <action name="Demo1Action_*" class="cn.probuing.strutsLesson.dynamic.Demo1Action" method="{1}">
            <result name="success">/hello.jsp</result>
        </action>
    </package>

http://localhost:8080/ss/dynamic/Demo1Action_find 这个地址中 *代表"find" 相当于配置了 method="find"

使用PreResultListener

PreResultListener是一个监听器接口,可以在Action完成控制处理之后,系统转入实际的物理视图之间被回调
Struts2应用可由Action、拦截器添加PreResultListener监听器,添加PreResultListener监听器通过ActionInvocation的addPreResultListener()方法完成。一旦为Action添加了PreResultListener监听器,该监听器就可以在应用转入实际物理视图之前回调该监听器的beforeResult()方法

  • 一旦为拦截器添加了PreResultListener监听器,该监听器会对该拦截器所拦截的所有Action都起作用
ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
invocation.addPreResult(ActionInvocation invocation,String resultCode)
{
  .....处理逻辑
  invocation.getInvocationContext().put("extra",new Date());
}

Struts2默认配置

Struts2的很多配置都有默认值,在不配置的时候就以默认值来指定

 <!--
            默认值:
                method属性:默认值 execute 如果配置文件中没有找到method会去对应的类中找execute方法
                class属性:com.opensymphony.xwork2.ActionSupport 
        -->
        <!--
            如果找不到命名空间下的action会使用默认的action处理 也就是DefaultDemo处理请求
        -->
        <default-action-ref name="DefaultDemo"></default-action-ref>
        <action name="DefaultDemo" class="cn.probuing.strutsLesson.defaultconf.DefaultDemo">
            <!--
                result的name属性:success
                result的Type属性:dispatcher 转发
            -->
            <result name="success">/hello.jsp
            </result>
        </action>

配置默认Action

当用户请求找不到对应的Action时,系统默认的Action即将处理用户请求
配置默认Action通过<default-action-ref.../>元素完成

<package name = "lee" extends="struts-default">
      <default-action-ref name="simpleViewResultAction"/>
      <!--通过action元素配置默认的Action-->
      <action name="simpleViewResultAction" class="........">
          <result..../>
       </action>

配置默认Action使用<default-action-ref.../>元素即可,配置该元素时需要制定一个name属性,该name属性指向容器中另一个有效的Action,该Action将成为容器中默认的Action

配置Action默认处理类

在配置<action.../>元素时可以不指定class属性,如果没有指定class属性则系统默认使用ActionSupport作为Action处理类

自定义Action默认处理类

配置默认Action处理类使用<default-class-ref.../>元素,配置该元素时只需要指定一个class属性,该属性指定的类就是Action的默认处理类

action类的详解

action的创建方式

方式一:直接创建一个类,可以是POJO(不用继承任何父类 也不需要实现任何接口)

这种方式并不好,使得Struts2框架的代码浸入性更低

方式二:实现一个接口Action

/**
 * Action的详解
 * @author wx-blackmac
 * @create 2018-05-23 22:34
 * bestwishes for you
 * good luck!
 * Action接口预置了一些字符串
 * SUCCESS
 * NONE
 * 
 **/
public class Demo3Action implements Action {

    /**
     * execute是提示Action方法规范
     * @return
     * @throws Exception
     */
    @Override
    public String execute() throws Exception {
        return SUCCESS;
    }
}

方式三:继承ActionSupport

ActionSupport帮我们实现了 Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable 这些接口 当我们使用这些接口时,不需要自己实现

/**
 * Action的详解
 * @author wx-blackmac
 * @create 2018-05-23 22:34
 * bestwishes for you
 * good luck!
 *
 **/
public class Demo3Action extends ActionSupport {

}

因为ActionSupport完全符合一个Action的要求,所以也可直接使用ActionSupport作为业务控制器,如果配置Action没有指定class属性(没有用户提供Action类),系统自动使用ActionSupport类作为Action处理类

配置异常处理

Struts2的异常处理我们一般希望如果出现异常1的时候系统转入视图资源1,如果出现异常2系统转入视图资源2。我们可以采用如下的方式

public class XxxAction
{
  public String execute(){
    try{
        ....
    }catch(异常1 e){
    return 结果1;
  }catch(异常2 e){
    return 结果2;
}

  }
}

但是,这样的方式会出现大量的try-catch块,完全手动处理异常,非常烦琐。
我们可以声明execute()抛出全部异常,将异常直接抛给Struts2框架。Struts2框架接收到Action抛出的异常之后,根据struts.xml配置异常映射。转入指定的视图

<interceptors>
  <!--执行异常处理的拦截器-->
<interceptor name="exception" class="自定义异常处理类"/>
<!--struts2默认的拦截器栈-->
<interceptor-stack name="defaultStack">
<!--引用异常映射拦截器-->
<interceptor-ref name="exception"/>
</interceptor-stack>
</interceptors>

声明式异常捕捉

Struts2的异常处理机制是通过在struts.xml文件中配置<exception-mapping.../>元素完成的。

  • exception:此属性指定该异常映射所设置的异常类型
  • result:指定Action出现该异常时,系统返回Result属性值对应的逻辑视图名
异常映射分类
  • 局部异常映射
    将<exception-mapping.../>元素作为<action.../>元素的子元素配置
    局部异常映射进队该异常映射所在的Action内有效。
  • 全局异常映射
    将<exception-mapping.../>元素作为<global-exception-mapping>元素的子元素配置
    全局异常映射对所有的Action都生效

如果局部异常映射和全局异常映射配置了同一个异常类型,在该Action内部局部异常映射会覆盖全局异常映射

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,780评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,424评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,397评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,576评论 0 218
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,997评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,945评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,107评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,850评论 0 208
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,625评论 1 250
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,804评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,285评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,613评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,291评论 3 242
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,164评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,963评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,096评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,886评论 2 278

推荐阅读更多精彩内容

  • 概述 什么是Struts2的框架Struts2是Struts1的下一代产品,是在 struts1和WebWork的...
    inke阅读 2,182评论 0 50
  • spring mvc 工作机制(原理): DispatcherServlet主要用作职责调度工作,本身主要用于控制...
    java大湿兄阅读 1,861评论 5 24
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,297评论 18 399
  • 概述 Struts就是基于mvc模式的框架!(struts其实也是servlet封装,提高开发效率!) Strut...
    奋斗的老王阅读 2,841评论 0 51
  • 我有一首诗 写在了陈年里 曾经的诗意现在流转不息 妄图抚动瑶琴 声传十里 青鸟舞动的竹林 布满我的明迹和足印 林深...
    原小吾阅读 222评论 0 3