zoukankan      html  css  js  c++  java
  • Struts2(二)— Result结果配置、Servlet的API的访问、模型驱动、属性驱动

    一.Result结果配置

    1.全局和局部结果

    ​   平常我们设置跳转页面,是在action标签里面加上 result标签来控制,这种设置的页面跳转,称之为局部结果页面但是我们有时候在很多个action里面,针对不同的结果进行跳转时,也有可能跳转同一个页面,那么这个时候就可以配置全局结果页面。

    1.1局部结果
    • 在action里面写上的result跳转的页面,称之为局部结果页面配置

      <action name="demo01_*" class="com.pri.web.action.ActionDemo01" method="{1}">
           <result name="error">/error.jsp</result>
      </action>
    1.2全局结果
    • 如果有多个action的结果跳转的页面是一样的,那么我们可以提取出来,做成全局结果页面的配置. 全局页面通过package标签中配置global-results标签来定义

      <package name="test" extends="struts-default" namespace="/">
          <global-results>
              <result name="error">/error.jsp</result>
          </global-results>
          ....
      </package>

    优先级: 局部>全局

    1.3不同包里面的全局结果的配置
    <!--把全局的结果抽取到父包里面  -->
    <package name="base" extends="struts-default" abstract="true">
         <global-results>
              <!--全局的结果: 配置在package里面的 特点:可以被当前包里面所有的Action共用; 使用场景:不同的Action需要跳转到相同的结果的时候eg: 错误页面, msg页面等  -->
              <result name="error">/msg.jsp</result>
         </global-results>
    </package><package name="test" extends="base" namespace="/">
          <action name="demo01_fun01" class="com.pri.web.ActionDemo01" method="fun01">
          </action>
          <action name="demo02_fun02" class="com.pri.web.ActionDemo02" method="fun02">
          </action>
    </package> 

    2.结果的类型【常用】

    ​   根据前面学的servlet知识,我们知道服务器响应给浏览器的时候,有三种类型:response响应JSON数据&请求转发 & 重定向。 对于Struts2而言,无非就是Action跳转(转发重定向)到页面,Action跳转到Action....

      文档位置 docs/docs/result-types.html

    2.1Action跳转页面
    • 转发(默认)
    <result name="success" type="dispatcher">/index.jsp</result> 
    • 重定向
    <result name="success" type="redirect">/index.jsp</result>
    2.2Action跳转Action
    • 转发

      <action name="demo01_*" class="com.pri.web.action.ActionDemo01" method="{1}">
              <result name="success" type="chain">demo02_fun02</result>
      </action>
      <action name="demo02_*" class="com.pri.web.action.ActionDemo02" method="{1}">
      </action>
    • 重定向

      <action name="demo01_*" class="com.pri.web.action.ActionDemo01" method="{1}">
              <result name="success" type="redirectAction">demo02_fun02</result>
      </action>
      <action name="demo02_*" class="com.pri.web.action.ActionDemo02" method="{1}">
      </action>
    2.3其它的结果

    ​      一般来说,我们平常的请求到来,我们要不就是跳转到 页面上 ,要不就是跳转到下一个action 去。 但是除了这两种结果之外,我们仍然还有一些其他结果类型可以控制.

    ​   比如: 我们可以返回一个文件数据给客户端 (比如文件下载).再比如: 我们可以返回一个json字符串给来请求的页面,而不是重新打开新的页面 (有点像之前的Ajax请求,返回json数据)

    2.3.1响应JSON数据【了解】
    • 导入struts-json-plugin-xxx.jar

    • Java代码

    •  1 public class ActionDemo01 extends ActionSupport {
       2     private User json;
       3     
       4     public User getJson() {
       5         return json;
       6     }
       7  8     public String fun01(){
       9         json = new User();
      10         json.setName("张三");
      11         json.setAge(18);
      12         json.setPassword("123456");
      13         
      14         return "success";
      15     }
      16 }
      • 配置文件

      • <struts>
            <package name="test" extends="json-default" namespace="/">
                <action name="demo01" class="com.pri.web.action.ActionDemo01" method="fun01">
                    <result name="success" type="json">
                          <param name="root">json</param>
                   <!--这里的name必须是root  至于这个json 是我们在action里面的成员 变量 json(属性)  -->
                     </result>
                </action>
            </package>
        </struts>

      注意:

      • ​ root:配置对象。action类中必须提供一个和root值相同的属性名称,且需要提供getter方法。
      • ​ package需要继承json-default
      • ​ result的type值是json
    2.3.2响应流(文件下载)【了解】
    • Action里面的代码

    •  1 public class ActionDemo01 extends ActionSupport {
       2     private InputStream stream;
       3     
       4     public void setStream(InputStream stream) {
       5         this.stream = stream;
       6     }
       7     public InputStream getStream() {
       8         return stream;
       9     }
      10     public String fun01() throws Exception{
      11         System.out.println("demo01 执行了...");
      12         stream = new FileInputStream("E:/data/Desktop/a.jpg");
      13         
      14         return "success";
      15     }
      16 }
    • 配置文件

      <struts>
          <package name="test" extends="struts-default" namespace="/">
              <action name="demo01" class="com.pri.web.action.ActionDemo01"
                  method="fun01">
                  <result name="success" type="stream">
                      <param name="contentType">image/jpeg</param>
                      <param name="inputName">stream</param>
                      <param name="contentDisposition">attachment;filename="b.jpg"</param>
                      <param name="bufferSize">1024</param>
                  </result>
              </action>
          </package>
      </struts>

    注意:

    • ​ contentType:下载文件类型
    • ​ contentDisposition:下载到客户端时,客户端文件名称
    • ​ bufferSize:读文件的缓存大小
    • ​ inputName:对应要输出到客户端流声明的名称,也就是说需要和Action里面声明的变量名要一致

    二、Struts2中的Servlet的API的访问

    ​      客户端与服务端交互时,通常会带参数过来,服务器也会回写数据给客户端。在此过程中,参与着请求,和响应,以及会话。servlet在此过程中提供了HttpServletRequest作为获取请求数据的方案,HttpServletResponse作为响应的方案,HttpSession负责了会话方案。Struts其实是基于servlet实现的web框架,他需要遵循规则提供请求,响应和会话的API供开发人员使用,因此Struts针对这一问题提供了自己的一套API封装,提供了多种方式的访问。

    1.ActionContext

    1.1概述

    ​    ActionContext是Action的上下文,Struts2自动在其中保存了一些在Action执行过程中所需的对象,比如session, parameters等。Struts2会根据每个执行HTTP请求的线程来创建对应的ActionContext,即一个线程有一个唯一的ActionContext。

    1.2使用
    • 获得(创建)ActionContext

      ActionContext context = ActionContext.getContext();
    • 获得请求参数

      Map<String, Object> parameters = context.getParamters();

      ​相当于Servlet中的request.getParamters()方法,只能获得所有的请求参数

    2.ServletActionContext

    2.1概述

    ​   ServletActionContext继承ActionContext,因此比ActionContext功能要强大。ServletActionContext提供了多个静态方法。

    2.2使用
    • 获得Request对象

      HttpServletRequest request = ServletActionContext.getRequest();
    • 获得Response对象

      HttpServletResponse response = ServletActionContext.getResponse();
    • 获得ServletContext

      ServletContext servletContext = ServletActionContext.getServletContext();

    3.实现接口的方式

    • 编写Action,让Action使用实现特定的接口的方式访问Servlet的API,有如下接口可以实现
      • ​ ServletContextAware
      • ​ ServletRequestAware
      • ​ ServletResponseAware
      • ​ SessionAware
      • ​ ApplicationAware
    • Eg:

    •  1 public class ActionDemo03 extends ActionSupport implements ServletRequestAware {
       2     private HttpServletRequest request;
       3     public String fun03() throws IOException{
       4         HttpServletRequest request = ServletActionContext.getRequest();
       5         String username = request.getParameter("username");
       6         String password = request.getParameter("password");
       7         System.out.println(username+":"+password);
       8         return NONE;
       9     }
      10 11     @Override
      12     public void setServletRequest(HttpServletRequest request) {
      13         this.request = request;
      14     }
      15 }

    三、获得请求参数

    1.获得零散数据

    1.1使用上面介绍的Struts2中的Servlet的API获取
    • ActionContext

      //1.创建ActionContext对象
      ActionContext context = ActionContext.getContext();
      //2.获得所有的请求参数
      Map<String, Object> parameters = context.getParamters();
    • ServletActionContext

      //1.获得request对象
      HttpServletRequest request = ServletActionContext.getRequest();
      requet.getParameter(String key);
      requet.getParameterValues(String key);
      requet.getParameterMap();
    1.2属性驱动【常用】
    • 页面

      <h1>01使用属性驱动</h1>
      <form method="post" action="${pageContext.request.contextPath }/demo01">
          用户名:<input type="text" name="username"/><br/>
          密    码:<input type="password" name="password"/><br/>
          <input type="submit"/>
      </form>
    • Action.java

      public class ActionDemo01 extends ActionSupport {
          private String username;//和表单里面的name属性值要一致,并且提供set方法
          private String password;//和表单里面的name属性值要一致,并且提供set方法
          public void setUsername(String username) {
              this.username = username;
          }
      ​
          public void setPassword(String password) {
              this.password = password;
          }
          public String fun01(){
              System.out.println(username+":"+password);
              return NONE;
          }
      }

    2.获得封装后的数据(对象)

    2.1属性驱动
    • 页面

      <h1>01使用属性驱动方式</h1>
      <form method="post" action="${pageContext.request.contextPath }/demo01">
          用户名:<input type="text" name="user.username"/><br/>
          密    码:<input type="password" name="user.password"/><br/>
          <input type="submit"/>
      </form>
    • Action.java

    •  1 public class ActionDemo01 extends ActionSupport {
       2     //1. User类里面的字段属性需要和表单里面的name属性一致, 且提供无参构造
       3     //2. user需要set和get方法
       4     private User user;
       5     public User getUser() {
       6         return user;
       7     }
       8     public void setUser(User user) {
       9         this.user = user;
      10     }
      11 12     public String fun01(){
      13         System.out.println(user.toString());
      14         return NONE;
      15     }
      16 }
    2.2模型驱动【常用】
    • 页面

      <h1>02使用模型驱动方式</h1>
      <form method="post" action="${pageContext.request.contextPath }/demo02">
          用户名:<input type="text" name="username"/><br/>
          密    码:<input type="password" name="password"/><br/>
          <input type="submit"/>
      </form>

    Action.java

     1 public class ActionDemo02 extends ActionSupport implements ModelDriven<User> {
     2     
     3     private User user;
     4     
     5     public String fun02(){
     6         System.out.println(user.toString());
     7         return NONE;
     8     }
     9     @Override
    10     public User getModel() {
    11         if(user == null){
    12             user = new User();
    13         }
    14         return user;
    15     }
    16 }

    结论:我们在实际开发里面,

    • ​ 如果要获得单个(零散)的数据,我们通常用属性驱动
    • ​ 如果要获得封装后的数据, 我们通常用模型驱动
    2.3封装到集合

    ​   封装到集合,一般我们会在批量添加 、批量更新场景下见到。也就是说页面上同一个请求,这时候提交过来多份数据,如果我们是批量添加用户的话,可能会提交过来多个用户,那么这个时候,我们就需要把他们封装到List集合或者Map集合中去。 刨去批量操作、我们比较少用这种封装到集合的知识点。

    2.3.1封装到list
    • 页面

      <h1>01封装到list</h1>
      <form method="post" action="${pageContext.request.contextPath }/demo01">
          用户名:<input type="text" name="list[0].username"/><br/>
          密    码:<input type="password" name="list[0].password"/><br/>
          用户名:<input type="text" name="list[1].username"/><br/>
          密    码:<input type="password" name="list[1].password"/><br/>
          <input type="submit"/>
      </form>
    • Action.java

      public class ActionDemo01 extends ActionSupport {
          
          private List<User> list;
          
          public List<User> getList() {
              return list;
          }
      ​
          public void setList(List<User> list) {
              this.list = list;
          }
      ​
          public String fun01(){
              System.out.println(list.toString());
              return NONE;
          }
      }
    2.3.2封装到Map
    • 页面

      <h1>02封装到map</h1>
      <form method="post" action="${pageContext.request.contextPath }/demo02">
          用户名:<input type="text" name="map['user1'].username"/><br/>
          密    码:<input type="password" name="map['user1'].password"/><br/>
          用户名:<input type="text" name="map['user2'].username"/><br/>
          密    码:<input type="password" name="map['user2'].password"/><br/>
          <input type="submit"/>
      </form>
    • Action.java

    • public class ActionDemo02 extends ActionSupport {
          
          private Map<String, User> map;
          public Map<String, User> getMap() {
              return map;
          }
      ​
          public void setMap(Map<String, User> map) {
              this.map = map;
          }
      ​
          public String fun02(){
              Set<Entry<String, User>> entrySet = map.entrySet();
              for (Entry<String, User> entry : entrySet) {
                  System.out.println(entry.getKey()+":"+entry.getValue().toString());
              }
              return NONE;
          }
  • 相关阅读:
    《Linux设备驱动开发详解(第2版)》配套视频登录51cto教育频道
    异常Address already in use: JVM_Bind的处理
    你的Jsp页面有黄×么,有黄色问号么?Multiple annotations found at this line:
    dispatch_get_current_queue 废弃
    二叉树代码(较全)
    ArrayList and LinkedList
    android的tabhost+RadioGroup+PopupWindow
    子进程继承父进程的当前工作目录的问题
    oracle AWR深入研究分析,如何使用
    Linux下对后台进程通过kill传递信号不起作用的问题
  • 原文地址:https://www.cnblogs.com/gdwkong/p/8367055.html
Copyright © 2011-2022 走看看