• 配置Struts2及Struts2访问servlet api的方式


    Struts2的起源与背景

      在很长的一段时间内,在所有的MVC框架中,Struts1处于绝对的统治地位,无论是从市场的普及范围,还是具体的使用者数量。 其他MVC框架都无

    法与其相比,作为一一款优秀的MVC框架、虽然Struts1可以很好地实现将控制与业务逻辑相分离, 但是其自身也存在一定的缺陷,这些缺陷体

    现在以下几方面。

    1.表现层支持单

      Struts1框架只支持JSP作为其表现层使用,而很多的Java应用,在表现层技术选择时并不一定只使用JSP-种技术,如FreeMarker. Velocity 等。这是

    因为Struts1框架的出现远在这些页面技术出现之前。而当多形式的视图技术出现后,Stuts 1又无法与这些视图技术进行整合.从而限制了Stuts 的发展。

    2.对Serwet AP的依赖

      SstSteteaveten方式属于Mosel的开发模式,Struts1框架正是基于Model模式开发而成的。因此在其中会应用到大量的Sever API.而Servlet需要通过web
    容器完成初始化。 从而进一步对web容器产生依赖。一旦股离了 web容器整个程序很难完成测试

    3.不利于代码重用

      在Seuts 1开发的代码中除了自己定义的类外,还必须使用Struts1中的某些类(如ActionForm),这样带来的弊端是,与Struts1的类耦合在一起的代码很难在其他的系统中进行重用。
      针对Sruts 1框架在设计时存在的一些问题, Struts 2以WebWork的设计思想为核心,吸收了Strus 1的部分优点,建立了一个兼容WebWak和Strus 1的MVC框架
      WebWork相对于Struts 1来说,虽然名气不大,但是在设计上避免了Struts 1存在的弊端。它更加强调系统之间松耦合,使用拦截器来实现控制。由于不再依赖
    Web容器,从而解决了框架对Servlet API的紧密耦合,使得测试更加方便。同时,在表现层支持更多的视图技术,开发更加灵活。
      Struts 2在设计之初,更多地是以WebWork的设计思想为核心,从应用角度也更接近WebWark的使用习惯,因此Struts 2框架结构与Struts 1框架结构有
    着明显的区别,Sruts 1与WebWak的优势互补使得Struts2拥有更加广阔的前景。Struts2不仅自身更加强大,而且对其他框架下开发的程序提供了很好的兼容性。

    Struts所需jar

      第一步首先创建一个web项目并导入jar

    创建项目和导入就不多说了,jar地址如下

    链接:https://pan.baidu.com/s/1gnf_15iSkl-2Xu6YmzV17g
    提取码:bcl5

    配置web.xml

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

    创建一个页面如下

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <!-- 导入标签库 -->
    <%@taglib prefix="s" uri="/struts-tags" %>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'helloWorld.jsp' starting page</title>
      </head>
      <body>
        <div>
            <!-- 获取action中的message属性 -->
            <h1><s:property value="message"/></h1>
        </div>
        <div>
            <form action="helloWorld.action" method="post">
                请输入您的用户名:<input type="text" name="name" >
                <input type="submit" value="提交"> 
            </form>
        </div>
      </body>
    </html>

    创建类 用于对用户的请求做出处理

     

    package cn.ssh.ch08;
    
    import com.opensymphony.xwork2.Action;
    
    public class HelloWorldAction implements Action {
        
        //用户输入的名字 对应jsp页面input框的名称
        private String name="";
        //向用户显示的信息 对应jsp页面的 message
        private String message="";
        
        /* 
         * 当处理用户请求时,默认配置下调用的方法
         */
        @Override
        public String execute() throws Exception {
            // TODO Auto-generated method stub
            this.setMessage("Hello !" +this.getName());
            return Action.SUCCESS;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }

    上面不实现Action接口继承ActionSupport类也可以

    Action接口中常量字符的逻辑含义

     

    常量

    逻辑含义

    SUCCESS

    “success”

    表示程序正常处理,并返回给用户成功后的结果

    NONE

    “none”

    表示处理正常结束,但不返回给用户任何显示

    ERROR

    “error”

    表示处理结果失败

    INPUT

    “input”

    表示需要更多用户输入才能执行

    LOGIN

    “login”

    表示需要用户正确登录后才能执行

     

     

     

     

     

     

     

     

     

    需要其他的结果也可以自己去写

    创建Struts2的配置文件

      在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>    
        <!-- 创建一个default包,继承Struts2的struts-default包 -->
        <package name="default" namespace="/" extends="struts-default">
            <!-- 接收处理用户的/helloworld.action请求,并根据返回结果进行跳转 -->
            <action name="helloWorld" class="cn.ssh.ch08.HelloWorldAction">
            <!-- 结果为 "success"时,跳转至 helloWorld.jsp-->
               <result name="success">/helloWorld.jsp</result>
            </action>
        </package> 
    </struts>

    如果没有头文件可以去到jar中去找, 如下

    打开之后,头文件如下

    测试

     配置好后我们就可以测试运行了

     

    执行流程

    1. 当浏览器发出helloWorld.action请求
    2. 服务器接收后,根据web.xml配置,将请求发送给指定的过滤器
    3. 过滤器根据struts.xml中的配置将请求发送给HelloWorldAction类的对象并调用默认的execute方法;
    4. 根据方法的返回结果在struts,xml文件中匹配处理结果,完成页面的跳转

    可以发现输入提交后文本框中的值就没了,更改的代码如下

      <div>
            <form action="helloWorld.action" method="post">
                请输入您的用户名:<s:textfield name="name" theme="simple"/>
                <input type="submit" value="提交"> 
            </form>
        </div>

    运行

    此外可以发现并没有非空验证

    那么我想用如果是空值则给予提醒,因为为接口没有提供对非空的验证所以换成继承.

    重写如下方法

    @Override
    public void validate() {
        if (name.length()==0) {
            addFieldError("name_is_null", "名称不能为空");
        }
    }

     

    添加效验信息后Struts2框架会根据action的配置跳转到结果名为input的视图页面,因此在需要在struts.xml中添加一个名为input的result

     

    <action name="helloWorld" class="cn.ssh.ch08.HelloWorldAction">
      <!-- 结果为 "success"时,跳转至 helloWorld.jsp-->
      <result name="success">/helloWorld.jsp</result>
      <!-- 当有 效验信息时 跳转到helloWorld.jsp -->
      <result name="input">/helloWorld.jsp</result>
    </action>

     

    在jsp中添加如下代码,进行显示

     

    <div>
      <!-- 显示效验信息 -->
      <s:fielderror fieldName="name_is_null"/>
    </div>

    测试

     Struts2访问servlet api的方式

      为了能够实现对servlet api对象的访问,Struts2提供了多种方式,归结起来可分为两大类:与servlet api解耦的方式访问servlet api耦合的访问方式

    区别:解耦并不直接依赖原生servlet api,耦合则直接依赖于原生api

    servlet解耦方式访问

      为了避免servlet api耦合在一起,方便action类,Struts2框架使用普通的map对象替代了servlet API中的HttpServletRequest,HttpSession和

    ServletContext对应的Map对象.Struts2提供了  com.opensymphony.xwork2.ActionContext类来获取Servlet API对象对应的Map对象,可以通过如下方法获取

    • Map getSession()      : 可获取Session
    • Map getApplication()   : 可获取Application
    • object get(String key)    : 可用来获取request,application,session,一般只是用来获取request因为没有单独获取它的方法

        假设我们需要保存用户名

    public String execute() throws Exception {
        this.setMessage("Hello !" +this.getName());
        ActionContext ac=ActionContext.getContext();
        //获取session和application
        /*Map<String, Object> session = ac.getSession();
        Map<String, Object> aMap =ac.getApplication();*/
        //获取request
        Map<String, Object> rMap = (Map<String, Object>) ac.get("request");
        //保存用户名
        rMap.put("NAME", getName());
        //返回 success
        return Action.SUCCESS;
    }

    jsp页面

    <div>
        <!-- 获取action中的message属性 -->
        <h1><s:property value="message"/></h1>
        <!-- 显示用户名 -->
        <p>获取保存的名称:${NAME}</p>
    </div>

    结果

     

    servlet api耦合的访问方式

      直接访问Servlet API将使Action类与Servlet API耦合在一起,因为Servlet API对象均由Servlet容器来构造,与这些对象绑定在一起,

    测试过程中就必须有Servlet容器,这样不便于Action的测试,但是有时候,确实需要直接访问这些对象,直接访问方式如下

     

    //耦合获取
    HttpServletRequest request= ServletActionContext.getRequest();
    ServletContext sContext= ServletActionContext.getServletContext();
    HttpServletResponse response= ServletActionContext.getResponse();
    HttpSession session =request.getSession();
    session.setAttribute("NMAE", getName());

     

    如何选择访问Servlet API的方式

    1. 能使用解耦方式访问尽量不要用耦合方式
    2. 除非需要使用耦合方式独有的方法 如:request.getServletPath(),getPathInfo(),getContextPaht(),getRequsetURI()等等

     

  • 相关阅读:
    Linux进程管理工具Supervisor
    RSA加密传输代码示例
    静态网站创建工具Docusaurus
    Proactor和Reactor模型
    机器学习中的七宗罪
    Tokio internals: Understanding Rust's asynchronous I/O framework from the bottom up
    开源软件创建SOC的一份清单
    How to setup SOC using open-source tools
    彼得定律
    深入浅出通信原理连载
  • 原文地址:https://www.cnblogs.com/hfx123/p/10048777.html
Copyright © 2020-2023  润新知