Struts2干货笔记——第一天

目录

1. 什么是Struts2
2. Struts2下载
3. Struts2的目录结构
4. Struts2中用到的一些jar包简介
5. 第一个Struts2程序
6. Struts2的流程分析
7. Struts2配置
  • 7.1 Struts2的Action配置
  • 7.2 Struts2的常量配置
  • 7.3 指定多个struts配置文件
8. Action
  • 8.1 Action类的创建方式
  • 8.2 Action类的访问
  • 8.3 Action访问servlet api
9. Result结果类型

什么是Struts2

Struts2是一款优秀的MVC框架,由传统的struts1和webwork两个经典框架发展而来。

Struts2下载

下载地址:http://struts.apache.org/download.cgi

Struts2的目录结构

文件夹 内容
apps 该文件夹包含了基于struts2的示例应用
docs 该文件夹包含了struts2的文档,包括struts2快速入门、struts2的文档以及API等
lib 该文件夹包含了struts2框架核心类库,以及struts2第三方插件类库
src 该文件夹包含了struts2框架的全部源代码

Struts2中用到的一些jar包简介

  • struts2-core-2.3.15.1.jar Struts2框架的核心类库
  • xwork-core-2.3.15.1.jar Command模式框架,WebWork和Struts2都基于xwork
  • ognl-3.0.6.jar Object Graph Navigation Language 对象图导航语言,struts2框架通过它来读写对象的属性
  • freemarker-2.3.19.jar Struts2的UI标签的模板使用freeMarker编写
  • commons-logging-1.1.3.jar ASD出品的日志包,Struts2框架使用这个日志包来支持Log4J和JDK1.4+的日志记录
  • commons-lang3-3.1.jar 对java.lang包的增强
  • commons-io-2.0.1.jar 传输文件依赖的jar包
  • commons-fileupload-1.3.jar 文件上传组件,2.1.6版本后需要加入此文件
    开发中为了方便,基础的jar包可以直接导入apps\struts2-blank\WEB-INF\lib中的jar包

第一个Struts2程序

  1. 创建web应用
  2. 导入必要的jar包
  3. 编写jsp页面
  4. 编写Action服务端页面
  5. 进行框架配置web.xml和struts.xml
  6. 运行测试

本次用到的是struts-2.3.15.1,只是举一个简单的例子让大家知道什么是struts2,后面再详细介绍。

编写jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>helloword</title>
</head>
<body>
    <a href="${pageContext.request.contextPath }/hello">helloword</a>
</body>
</html>
编写一个success页面

action处理成功后跳转到success页面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>struts2</title>
</head>
<body>
    <h1>hello,struts2</h1>
</body>
</html>
编写Action处理访问的请求
package com.java.action;
public class HelloAction {
    public String execute(){
        System.out.println("hello world");
        return "success"; 
    }
}
配置Struts2核心控制器

在web.xml中配置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>
配置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="default" namespace="/" extends="struts-default">
        <action name="hello" class="com.java.action.HelloAction">
            <result name="success">/success.jsp</result>
        </action>
    </package>
</struts>
测试成功
struts2_1.1.png
struts2_1.2.png

Struts2的流程分析

简要:
用户发起请求 → StrutsPrepareAndExecuteFilter核心控制器 → interceptor拦截器 → Action类中 execute → result 结果页面 →响应

详细流程图

Struts2配置

  • default.properties:默认的常量配置。该文件保存在struts2-core-2.3.7.jar中org.apache.struts2包里面
  • struts-default.xml:Bean、拦截器、结果类型。该文件保存在struts2-core-2.3.7.jar
  • struts-plugin.xml:插件的配置信息。该文件保存在struts-Xxx-2.3.7.jar
  • struts.xml:web应用默认的struts配置文件,配置action或常量。
  • struts.properties:配置常量。该文件是Struts的默认配置文件
  • web. xml:配置struts2,监听器,过滤器,常量。该文件是 Web 应用的配置文件

后加载文件中struts2常量会覆盖之前加载文件常量内容

Struts2的Action配置

当我们编写完Action类后,就可以在struts.xml文件中配置该Action。在struts.xml中配该Action就是让Struts2容器知道该Action的存在,并且能调用该Action来处理用户请求。
Struts 2使用包来组织Action,因此,将Action定义放在包定义下完成,定义Action通过使用<package>下的<action>标签来完成。定义action同时要给出name属性和class属性。

package的属性

  • name:包名称,在struts2的配置文件中,包名不能重复 ,name并不是真正包名,只是为了管理Action
  • namespace:namespace属性和name属性,决定 Action的访问路径 (以/开始 )
  • extends:extends表示继承自哪个包,通常开发中继承 struts-default 包 (struts-default包在 struts-default.xml定义 )

action的属性

  • name:该action的名字,同时也是也是需要处理的URL前半部分。<action>的name 和 <package>的namespace属性 共同决定 Action的访问路径
    例如 :
    <package name="default" namespace="/user" extends="struts-default">
    <action name="hello" class="com.java.struts2.HelloAction">
    访问路径 /user/hello.action
  • class:指定了该Action的实现类,如果不指定,默认ActionSupport类

Action只是一个控制器,它并不直接对浏览器生成响应,所以在Action处理完用户的请求后,Action需要将指定的视图资源展示给用户,要配置映射关系,用<result>标签。<result>元素有两个属性,name和type,系统默认name属性是success,type属性是dispatch。

每个result标签都代表了一个可能输出的结果。当Action类的方法执行完成时,它返回一个字符串作为结果,框架根据这个结果选择对应的result(result的name属性),向用户输出结果页面。在com.opensymphony.xwork2.Action接口中定义了一组标准的结果代码,可供开发人员使用,当然了只有我们的action继承ActionSupport 这个类才可以使用下面的结果代码,后面再来详细总结结果类型

public interface Action{
       public static final String SUCCESS = “success”;
       public static final String NONE = “none”;
       public static final String ERROR = “error”;
       public static final String INPUT = “input”;
       public static final String LOGIN = “login”;
  }

name属性值

返回结果 解释
SUCCESS Action执行成功,返回相应的视图,success是 name属性的默认值
NONE Action执行成功,但并不返回任何视图
ERROR Action执行失败,返回到 错误处理视图
INPUT Action在执行时需要从前端界面获取参数,INPUT就是代表这个输入参数的界面,通常会对这些参数进行验证,如果验证没有通过,将自动返回到该视图
LOGIN Action因为用户没有登陆,将返回该登陆视图,要求用户进行 登陆验证

Struts2的常量配置

在default.properties文件中声明了许多常量
手动设置常量:

  • 1.struts.xml(应用最多)
    <constant name="常量名称" value="常量值"></constant>
  • 2.struts.properties(基本不使用)
  • 3.web.xml(了解)
    配置常量,是使用StrutsPrepareAndExecuteFilter的初始化参数来配置的.
    <init-param>
    <param-name>struts.action.extension</param-name>
    <param-value>do,,</param-value>
    </init-param>
    常用常量
  • <constant name="struts.i18n.encoding" value="UTF-8"/>
    相当于request.setCharacterEncoding("UTF-8"); 解决post请求乱码
  • <constant name="struts.action.extension" value="action"/>
    访问struts2框架Action访问路径扩展名struts.action.extension=action,默认以.action结尾,不写扩展名也会分发给 Action
  • <constant name="struts.serve.static.browserCache" value="false"/>
    false不缓存,true浏览器会缓存静态内容,产品环境设置true、开发环境设置false
  • <constant name="struts.devMode" value="true" />
    提供详细报错页面,修改struts.xml后不需要重启服务器

指定多个struts配置文件

随着网站规模增加,Action数量也会增加,导致struts.xml配置文件非常臃肿,可以用一个struts.xml文件包含其他配置文件。

<struts>
  <include file=""struts1.xml>
  <include file=""struts2.xml>
</struts>

Action

HTTP请求提交给Struts2的StrutsPrepareAndExecuteFilter 核心控制器,根据请求分发给不同Action

Action类的创建方式

  1. 创建一个POJO类
    POJO类指简单的java对象(Plain Old Java Objects),指的是没有实现任何借口,没有继承任何父类的类(除object)。
    优点:无耦合
    缺点:所有功能都要自己完成
  2. 创建一个类,实现Action接口.com.opensymphony.xwork2.Action
    优点:耦合低,提供了五种结果视图,定义了一个行为方法。
    public static final String SUCCESS = "success"; // 数据处理成功 (成功页面)
    public static final String NONE = "none"; // 页面不跳转 return null; 效果一样
    public static final String ERROR = "error"; // 数据处理发送错误 (错误页面)
    public static final String INPUT = "input"; // 用户输入数据有误,通常用于表单数据校验 (输入页面)
    public static final String LOGIN = "login"; // 主要权限认证 (登陆页面)
    缺点:所以工作都要自己实现。
  3. 创建一个类,继承ActionSupport类(经常使用). com.opensymphony.xwork2.ActionSupport
    ActionSupport类已经实现了Action接口。
    优点:表单校验、错误信息设置、读取国际化信息 三个功能都支持.
    缺点:耦合度高

Action类的访问

  1. 通过设置method的值,来指定访问action类中的哪一个方法
    如果没有指定method指,默认执行execute方法.
    <action name="regist" class="com.java.struts2.RegistAction">
    如果设置method,则执行相应方法
    <action name="regist" class="com.java.struts2.RegistAction" method="regist">
  2. 使用通配符来简化配置
    在配置<action>元素时,允许在指定name属性时,使用通配符*来代表一个或多个任意字符,在class、method属性以及<result>子元素中通过{N}形式代表前面第N个*匹配字符串。
    简单案例:
<action name="*" class="com.java.struts.HelloAction" method="{1}">
      // * 匹配访问字符串,例如 http://localhost:8080/struts/add,则匹配add
      //   method中的{1}指前面第一个匹配的字符串 :method="add"
      <result name="success">/{1}.jsp</result>
      //   /add.jsp
</action>

复杂案例:

<action name="*_*" class="com.java.struts.{1}" method="{2}">
      // 匹配两个字符串 访问http://localhost:8080/struts/UserAction_login,
      // {1}则匹配UserAction  {2}则匹配login
      <result name="success">/{2}.jsp</result>
      //  /login.jsp
</action>
  1. 动态方法调用(了解)
    可以通过url动态的指定调用Action哪个方法而无需配置<action>的method属性。使用 !方法名 指定调用Action中哪个方法。
    访问:localhost:8080/struts2/user!add 会执行UserAction中add的方法
    前提是struts.enable.DynamicMethodInvocation = true 常量值 为true
<action name="add" class="com.java.struts2.UserAction">
  <result>/success.jsp</result>
</action>

Action访问servlet api

在struts2中获取servlet api有三种方式:

1. 通过ActionContext来获取(重点)
Servlet API最常见操作就是表单提交请求参数获取,向request、session、application三个范围存取数据
actionContext = ActionContext.getContext(); 返回actionContext实例对象

  1. actionContext.getParameters(); 获得所有请求参数Map集合
  2. actionContext.put("name", "小明");存一个值,相当于setAttribute方法
  3. actionContext.get("name") 获得request对应的key值
  4. actionContext.getSession(); 获得session数据Map
  5. actionContext.setSession(Map);将该Map里的key-value保存为HttpSession中的属性名和值
  6. actionContext.getApplication(); 获得ServletContext数据Map
  7. actionContext.setApplication(); 将该Map里的key-value保存为ServletContext中的属性名和值

2. 接口注入方式获取(IOC)
struts2在实例化一个action对象时,如果发现他实现了相关的Aware接口,就会把相应的资源通过Aware接口方法注入进去,所以叫做注入方式(IOC方式),以request为例,实现了ServletRequestAware接口,就会有一个setServletRequest()方法获取request对象,Aware接口实际上是一种拦截器,他会在执行Action前执行,把相关的servlet对象设置进来

  • 要求action类必须实现提定接口
  • 重写接口中的方法
  • 声明一个对象,使用接口中的方法的参数对声明的对象赋值
  private HttpServletRequest request;
  public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }

原理是由struts2中的一个interceptor完成的
<interceptor name="servletConfig" class="org.apache.struts2.interceptor.ServletConfigInterceptor">

 if (action instanceof ServletRequestAware) { 
         //判断action是否实现ServletRequestAware接口
HttpServletRequest request = (HttpServletRequest) context.get(HTTP_REQUEST); 
        //得到request对象.
((ServletRequestAware) action).setServletRequest(request);
        //将request对象通过action中重写的方法注入。
}

3. 通过ServletActionContext获取
在ServletActionContext中的方法都是static
ServletActionContext.getRequest() 获得request对象
ServletActionContext.getResponse() 获得response 对象
ServletActionContext.getServletContext() 获得ServletContext对象

Result结果类型

Action处理完用户请求后,将返回一个普通字符串,struts2根据这个字符串来决定响应哪个结果,处理结果使用<result>元素来配置。

  • 局部结果:将<result>作为<action>的子元素进行配置
    <action name="result" class="com.java.struts2.ResultAction">

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

  • 全局结果:将<result>作为<global-results>的子元素进行配置
    <global-results>

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

配置<result>有两个属性:name和type
name:该属性配置的逻辑视图名
type:该属性的结果类型

在struts-default.xml文件中定义了type可以取的值

<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" />

重点:chain dispatcher redirect redirectAction stream

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

推荐阅读更多精彩内容