2. Struts2 基础

1. Struts2简介

  • Struts2是一个WEB端MVC框架。作为比较早的MVC 框架之一,Struts2在使用中还是比较多的。虽然个人感受没有SpringMVC还那么的好用
  • Struts2 官网
  • 在Model2中我们使用Servlet作为控制器:
    • Servlet主要负责:
      • 接收用户发送的请求
      • 将请求参数封装为Java中的对象
      • 调用service来处理业务逻辑
      • 根据service返回的结果,选择视图

2. Struts2-HelloWorld

  • 新建一个Maven 的webapp 项目
  • 在这里我给出一个简单的 pom.xml 文件依赖
<dependencies>
     <dependency>
      <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
     </dependency>
     <!-- javax JSTL的API-->
     <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>servlet-api</artifactId>
         <version>2.5</version>
         <scope>provided</scope>
     </dependency>
     <dependency>
         <groupId>javax.servlet</groupId>
         <artifactId>jstl</artifactId>
         <version>1.2</version>
     </dependency>
    <dependency>
        <groupId>org.apache.struts</groupId>
        <artifactId>struts2-core</artifactId>
        <version>2.5.5</version>
    </dependency>
</dependencies>
  • 在web.xml 文件中,我们需要配置 Struts2 用到的 filter 过滤器
<filter>
    <filter-name>struts2</filter-name>
    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>struts2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • 编写一个Action 类 Helloworld :里面就一个方法
public String hello (){
   System.out.println("UserAction-hello...........");
   return "success";
}
  • 在 resources 文件夹下 我们需要新增一个XML文件,叫做 struts.xml 文件。需要在里面配置一个最简单的 action.
<struts>
    <constant name="struts.devMode" value="true"/>
    <package name="default" namespace="/" extends="struts-default">
     <action name="hello" class="org.pan.struts2.Helloworld">
            <result name="success">/WEB-INF/views/success.jsp</result>
        </action>
</package>
  • 我们在 index.jsp 页面写一个超链接,<a href="${pageContext.request.contextPath}/hello">HelloWorld</a> 我们发现能够正常的跳转到 success (该页面就不写了,自己添加)。说明我们struts2 的HelloWorld 正常了
  • action VS Action
    • action: 应用程序可以完成的每一个操作. 例如: 我们请求 hello
    • Action类: 普通的 Java 类, 可以有属性和方法, 同时必须遵守下面这些规则:
      • 属性的名字必须遵守与 JavaBeans 属性名相同的命名规则. 属性的类型可以是任意类型. 从字符串到非字符串(基本数据库类型)之间的数据转换可以自动发生
      • 必须有一个不带参的构造器
      • 至少有一个供 struts 在执行这个 action 时调用的方法
      • 同一个 Action 类可以包含多个 action 方法.
      • Struts2 会为每一个 HTTP 请求创建一个新的 Action 实例
  • Action接口(不常用)

    • 我们也可以通过实现Action接口来创建一个Action类。
    • 这个接口中为我们提供了几个结果类型的常量
    • 还提供了一个抽象的execute方法
  • ActionSupport:

    • 我们开发中大部情况Action类都会继承ActionSupport类。
    • ActionSupport 实现类Action等接口。
    • ActionSupport 对国际化、验证等做了很好的支持。

3. 在Action 中获取Web 资源- Servlet 相关API

  • 在 Action 类中获取 Servlet 相关的API,主要分为两种:

    • 一种是 Struts2 封装好的 Map结构:
      • Map<String, Object> session
      • Map<String, Object> application
      • Map<String,Object> requestMap
    • 另一种是 Servlet 原生的API
      • request
      • session
      • application
  • 获取 Struts2 封装的相关 Map

    • 与 Servlet API 解耦的访问方式
      • 为了避免与 Servlet API 耦合在一起, 方便 Action 做单元测试, Struts2 对 HttpServletRequest, HttpSession 和 ServletContext 进行了封装, 构造了 3 个 Map 对象来替代这 3 个对象, 在 Action 中可以直接使用 HttpServletRequest, HttpServletSession, ServletContext 对应的 Map 对象来保存和读取数据.

      • 方式一

        • Struts2 封装的API: com.opensymphony.xwork2.ActionContext
        • ActionContext 对象保存当前Action上下文内容,也就是当前Action的相关对象都可以通过ActionContext获取。
        • ActionContext 内部维护了一个Map集合,我们这些对象在Map集合中保存,可以通过key获取value。
        • 在 ActionContext 中保存对象都是域对象中的Map,而不是我们属性HttpServletRequest、HttpSession、ServletContext
        • 我们通过操作Map实际上就是间接的操作域中的属性
      • 方式二:实现XxxAware接口:

        • org.apache.struts2.interceptor.ApplicationAware;
        • org.apache.struts2.interceptor.ParameterAware; 在2.5.5版本之后,废弃了该接口,使用 org.apache.struts2.dispatcher.HttpParameters
        • org.apache.struts2.interceptor.RequestAware;
        • org.apache.struts2.interceptor.SessionAware;
        • 这四个接口都有对应set方法,当我们实现了这些接口,Struts2 会自动调用set方法,将对应的 Map 设置进Action对象
/**
* 方式二: 实现 XxxxAware 的接口的方式来 Set 各种解耦的ServletAPI
*/
public class UserAction extends ActionSupport implements ApplicationAware, SessionAware, RequestAware, HttpParametersAware {
    /**
    * 方式二可以在多个方法中公用这些 ServletAPI
    */
    private Map<String, Object> application;
    public void setApplication(Map<String, Object> application) {
        this.application = application;
    }
    private HttpParameters parameters;
    public void setParameters(HttpParameters parameters) {
        this.parameters = parameters;
    }
    private Map<String, Object> request;
    public void setRequest(Map<String, Object> request) {
        this.request = request;
    }
    private Map<String, Object> session;
    public void setSession(Map<String, Object> session) {
        this.session = session;
    }
    /**
    * 方式一: 通过 ActionContext 的方式获取解耦的 ServletAPI
    *
    * @return
    */
    public String getServletAPI_ActionContext() {
        //与Servlet 解耦的方式获取 Struts2 封装的 API
        ActionContext actionContext = ActionContext.getContext();
        Map<String, Object> session = actionContext.getSession();
        //注意session的真实类型是SessionMap,它的内部保存一个Session对象
        //可以通过该对象invalidate方法来使session失效
        SessionMap sessionMap = (SessionMap) session;
        sessionMap.invalidate();
        Map<String, Object> application = actionContext.getApplication();
        // requestMap 获取比较特殊,使用get 方法获取
        Map<String, Object> request = (Map<String, Object>) actionContext.get("request");
        HttpParameters parameters = actionContext.getParameters();
        Map<String, String[]> parametersMap = parameters.toMap();
        session.put("seeesionKey", "sessionValue");
        application.put("applicationKey", "applicationValue");
        request.put("applicationKey", "applicationValue");
        parametersMap.put("parametersMapKey", new String[]{"parametersMapValue"});
        return SUCCESS;
    }
}
  • 与 Servlet API 耦合的访问方式
    • 直接访问 Servlet API 将使 Action 与 Servlet 环境耦合在一起, 测试时需要有 Servlet 容器, 不便于对 Action 的单元测试
      • 方式一: 通过 org.apache.struts2.ServletActionContext
      • 方式二:ServletXxxAware :
        • 让 Action 实现 ServletRequestAware , ServletContextAware, ServletRequestAware 三个接口
        • 这两个接口中定义相关对象 set 方法,当我们这些接口时,Struts2 会自动调用方法设置相应的对象
/**
 * 方式二: 实现 ServletXxxxAware 接口的方式
 */
public class ServletAPITest extends ActionSupport implements ServletRequestAware, ServletContextAware, ServletResponseAware{
    private HttpServletRequest request;
    private ServletContext context;
    private HttpServletResponse response;
    private HttpSession session;
    public void setServletRequest(HttpServletRequest request) {
        this.request = request;
    }
    public void setServletContext(ServletContext context) {
        this.context = context;
    }
    public void setServletResponse(HttpServletResponse response) {
        this.response = response;
    }
    /**
     * Session 比较特殊,我们可以在用的时候通过 request 来获取
     */
    private void testGetSession(){
        if (request != null){
            session = request.getSession();
        }
    }
    /**
     * 方式一: 通过 org.apache.struts2.ServletActionContext 的静态方法来获取这些原生的 ServletAPI
     * @return
     */
    public String testServletAPI_ServletActionContext(){
        ActionContext context = ServletActionContext.getContext();
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();
        //Session 可以通过 request 来获取
        HttpSession session = request.getSession();
        return SUCCESS;
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,976评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,249评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,449评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,433评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,460评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,132评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,721评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,641评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,180评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,267评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,408评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,076评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,767评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,255评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,386评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,764评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,413评论 2 358

推荐阅读更多精彩内容