• 3、Struts2的API访问和数据封装


    一、API的访问

    在使用Struts2的框架的过程中,发现Struts2和Servlet的API是解耦合的。在实际开发中,经常使用到Servlet的API,比如进行登录,将用户的信息保存到Session中,

    有的时候需要向页面输出一些内容,用到response对象。涉及到Servlet的API的访问。

    1、完全解耦合的方式,通过ActionContext类访问[推荐]

    Struts2框架提供了ActionContext类来访问Servlet API,ActionContext是Action执行的上下文对象。在ActionContext中保存了Action执行所需要的所有对象,

    包括parameters,request,session,application等。

    // 将key-value键值对放入ActionContext中,模拟Servlet API中的HTTPServletRequest
    的setAttribute()方法
    void put(String key,Object value) 
    
    // 通过参数Key来查找当前ActionContext中的值
    Object get(String key)
    
    // 返回一个Application级的对象
    Map<String,Object> getApplication()
    
    // 获取当前线程的ActionContext对象
    static ActionContext getContext() 
    
    // 返回一个包含所有HttpServletRequest参数信息
    Map<String,Object> getParameters()
    
    // 返回一个Map类型的HttpSession对象
    Map<String,Object> getSession()
    
    // 设置Application上下文
    void SetApplication(Map<String,Object> application)
    
    // 设置一个Map类型的Session值
    void setSession(Map<String,Object> session) 

    注意:这种方式只能获得代表request、session、application的数据的Map集合,不能操作这些对象的本身的方法。

    案例:

    Action类

    package com.turtle.demo4.action;
    
    import com.opensymphony.xwork2.ActionContext;
    import com.opensymphony.xwork2.ActionSupport;
    
    import java.util.Map;
    
    public class Demo4Action extends ActionSupport {
    
        public String save(){
    
            // 从前端返回来的参数中取值
            // 通过ActionContext来取得ActionContext对象
            ActionContext actionContext = ActionContext.getContext();
            // actionContext.getParameters()可以取到map值的对象
            Map<String, Object> contextParameters = actionContext.getParameters();
            // 遍历输出值
            for (Map.Entry<String,Object> entry : contextParameters.entrySet()){
                String key = entry.getKey();
                String value = entry.getValue().toString();
            }
    
            // 向返回前端的参数中设置值
            // 把值设置到session中
            actionContext.getSession().put("name1","session");
            // request.setAttribute("","")
            actionContext.put("name2","request");
            // application.setAttribute("","")
            actionContext.getApplication().put("name3", "application");
            
            return SUCCESS;
        }
    }

    Jsp页面

    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
        <h1>使用ServletContext</h1>
        <form action="${pageContext.request.contextPath}/demo4Action.action" method="post">
            用户名:<input type="text" name="name" value=""/><br/>
            密  码:<input type="password" name="password" value=""/><br/>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>
    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
        <h1>使用ServletContext</h1>
        <form action="${pageContext.request.contextPath}/demo4Action.action" method="post">
            Session    :<input type="text" name="name1" value="${name1}"/><br/>
            Request    :<input type="text" name="name2" value="${name2}"/><br/>
            Application:<input type="text" name="name3" value="${name3}"/><br/>
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
                    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
                    "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
            <package name="demo4" extends="struts-default" namespace="/">
                    <action name="demo4Action" class="com.turtle.demo4.action.Demo4Action" method="save">
                            <result name="success">/demo4/success.jsp</result>
                    </action>
            </package>
    </struts>

    结果:

                                                                   

                          

    2、使用Servlet的API的原生方式

    该方法可以直接访问Servle API,提供了ServletActionContext类,该类包含了我么所需要的几个方法

    // 获取web应用中的HttpServletRequest对象
    static HttpServletRequest()
    
    // 获取web应用中的HttpServletResponse对象
    static HttpServletResponse getResponse()
    
    // 获取web应用中的ServletContext对象
    static ServletContext getServletContext()
    
    // 获取WEb应用中的PageContext对象
    static PageContext getPageContext()

    Action类:

    package com.turtle.demo4.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    import org.apache.struts2.ServletActionContext;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Map;
    
    public class Demo4Action extends ActionSupport {
    
        public String save(){
    
            // 取从前端页面带过来的数据
            HttpServletRequest request = ServletActionContext.getRequest();
            Map<String, String[]> parameterMap = request.getParameterMap();
            for(Map.Entry<String,String[]> entry : parameterMap.entrySet()){
                String key = entry.getKey();
                String[] value = entry.getValue();
            }
    
            // 往前端传的数据
            request.setAttribute("name1","request");
            request.getSession().setAttribute ("name2","session");
            ServletActionContext.getServletContext().setAttribute("name3","servletContext");
            return SUCCESS;
        }
    }

    JSP页面和配置文件不做改变,显示的结果也是一样的。

    3、接口注入的方式

    // 实现该接口可以直接访问WEb应用中的HttpServletRequest实例
    ServletRequestAware
    
    // 实现该接口可以直接访问WEb应用中的HttpServletResponse实例
    ServletResponseAware
    
    // 实现该接口可以直接访问WEb应用中的HttpSession实例
    SessionAware
    
    // 实现该接口可以直接访问WEb应用中的ServletContexte实例
    ServletContextAware

    Action:

    package com.turtle.demo4.action;
    
    import com.opensymphony.xwork2.ActionSupport;
    import org.apache.struts2.ServletActionContext;
    import org.apache.struts2.interceptor.ServletRequestAware;
    
    import javax.servlet.http.HttpServletRequest;
    import java.util.Map;
    
    public class Demo4Action extends ActionSupport implements ServletRequestAware {
    
        private HttpServletRequest request;
    
        @Override
        public void setServletRequest(HttpServletRequest httpServletRequest) {
            this.request = httpServletRequest;
        }
        public String save(){
            // 取从前端页面带过来的数据
            Map<String, String[]> parameterMap = request.getParameterMap();
            for(Map.Entry<String,String[]> entry : parameterMap.entrySet()){
                String key = entry.getKey();
                String[] value = entry.getValue();
            }
    
            // 往前端传的数据
            request.setAttribute("name1","request");
            request.getSession().setAttribute ("name2","session");
            ServletActionContext.getServletContext().setAttribute("name3","servletContext");
            return SUCCESS;
        }
    }

    配置文件和结果显示页面与上面的一致。

    Servlet是单例的,多个程序访问同一个Servlet只会创建一个Servlet的实例。Action是多例的,一次请求,创建一个Action的实例(不会出现线程安全的问题)。

    二、结果页面的配置

    1、局部结果页面的配置:

    局部结果页面指的是,只能在当前的action中的配置有效。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
                    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
                    "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
            <package name="demo4" extends="struts-default" namespace="/">
                    <action name="demo4Action" class="com.turtle.demo4.action.Demo4Action" method="save">
                            <result name="success">/demo4/success.jsp</result>
                    </action>
            </package>
    </struts>

    2、全局结果页面的配置:

    全局结果页面:全局结果页面指的是,在包中配置一次,其他的在这个包中的所有的action只要返回了这个值,都可以跳转到这个页面。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE struts PUBLIC
                    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
                    "http://struts.apache.org/dtds/struts-2.0.dtd">
    
    <struts>
            <package name="demo4" extends="struts-default" namespace="/">
                    <global-results>
                            <result name="success">/demo4/success.jsp</result>
                    </global-results>
                    <action name="demo4Action" class="com.turtle.demo4.action.Demo4Action" method="save">
                            <!--<result name="success">/demo4/success.jsp</result>-->
                    </action>
            </package>
    </struts>

    3、result标签的配置

    result标签用于配置页面的跳转。在result标签上有两个属性:

    name属性      :逻辑视图的名称。默认值:success

    type属性        :页面跳转的类型。

      dispatcher       :默认值,请求转发。(Action转发JSP

      redirect            :重定向。(Action重定向JSP

      chain                 :转发。(Action转发Action)

      redirectAction :重定向。(Action重定向Action)

      stream              :Struts2中提供文件下载的功能。

    三、数据封装:

    1、属性驱动:提供属性set方法的方式(不常用)

    Action类:

    package com.turtle.demo5;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class Demo5Action extends ActionSupport {
    
        // 用户名
        private String name;
        // 密码
        private String password;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String save() {
            System.out.println("用户名"+name);
            System.out.println("密码"+password);
            return null;
        }
    }

    前端页面:

    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
    <h1>属性驱动第一种方法</h1>
    <form action="${pageContext.request.contextPath}/demo5Action.action" method="post">
        用户名:<input type="text" name="name" /><br/>
        密  码:<input type="password" name="password"/><br/>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

    2、属性驱动:页面中提供表达式方式

    封装的对象

    package com.turtle.demo5;
    
    public class User {
        // 名字
        private String name;
        // 密码
        private String password;
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }

    Action类

    package com.turtle.demo5;
    
    import com.opensymphony.xwork2.ActionSupport;
    
    public class Demo5Action extends ActionSupport {
    
        // 用户对象
        private User user;
    
        public String save() {
            System.out.println("用户名"+user.getName());
            System.out.println("密码"+user.getPassword());
            return null;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }

    Jsp页面:

    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
    <h1>属性驱动第一种方法</h1>
    <form action="${pageContext.request.contextPath}/demo5Action.action" method="post">
        用户名:<input type="text" name="user.name" /><br/>
        密  码:<input type="password" name="user.password"/><br/>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

    3、模型驱动,采用模型驱动方式(最常用)

    通过实现ModelDriven接口来接收参数,Action类必须实现ModelDerven接口,并且要重写getModel方法,这个方法返回的是Action类所要使用的数据模型对象。

    Action类

    package com.turtle.demo5;
    
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    public class Demo5Action extends ActionSupport implements ModelDriven<User> {
    
        // 用户对象,需要手动进行实例化
        private User user = new User();
    
        /**
         * 主要就是这个方法
         * @return
         */
        @Override
        public User getModel() {
            return user;
        }
    
        public String save() {
            System.out.println("用户名"+user.getName());
            System.out.println("密码"+user.getPassword());
            return null;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    }

    jsp页面

    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
    <h1>属性驱动第一种方法</h1>
    <form action="${pageContext.request.contextPath}/demo5Action.action" method="post">
        用户名:<input type="text" name="name" /><br/>
        密  码:<input type="password" name="password"/><br/>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

    汇总:大部分我们会优先使用模型驱动的方式,因为Struts2内部有很多结果都是围绕模型驱动设计的。但如果页面中向

    多个对象中封装,那么就要使用属性驱动的方式二了。

    4、封装到List集合中

    Action类

    package com.turtle.demo5;
    
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    import java.util.List;
    
    public class Demo5Action extends ActionSupport {
    
        // 用户对象,需要手动进行实例化
        // 该变量和jsp中使用的list名字要一致,而且get/set方法也要一致
        private List<User> userList;
    
        public String save() {
            for(User user : userList){
                System.out.println("用户名"+user.getName());
                System.out.println("密码"+user.getPassword());
            }
            return null;
        }
        public List<User> getUserList() {
            return userList;
        }
    
        public void setUserList(List<User> userList) {
            this.userList = userList;
        }
    
    }

    JSp页面:

    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
    <h1>属性驱动第一种方法</h1>
    <form action="${pageContext.request.contextPath}/demo5Action.action" method="post">
        用户名:<input type="text" name="userList[0].name" /><br/>
        密  码:<input type="password" name="userList[0].password"/><br/>
        <hr/>
        用户名:<input type="text" name="userList[1].name" /><br/>
        密  码:<input type="password" name="userList[1].password"/><br/>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

    5、封装到Map集合中

    Action类

    package com.turtle.demo5;
    
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    import java.util.List;
    import java.util.Map;
    
    public class Demo5Action extends ActionSupport {
    
        private Map<String,User> userMap;
    
        public String save() {
            for(Map.Entry<String,User> user : userMap.entrySet()){
                System.out.println("用户名"+user.getValue().getName());
                System.out.println("密码"+user.getValue().getPassword());
            }
            return null;
        }
    
        public Map<String, User> getUserMap() {
            return userMap;
        }
    
        public void setUserMap(Map<String, User> userMap) {
            this.userMap = userMap;
        }
    }

    Jsp页面

    <%--
      Created by IntelliJ IDEA.
      User: 22274
      Date: 2019/10/27
      Time: 23:52
      To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head>
        <title>Servlet</title>
    </head>
    <body>
    <h1>属性驱动第一种方法</h1>
    <form action="${pageContext.request.contextPath}/demo5Action.action" method="post">
        用户名:<input type="text" name="userMap['0'].name" /><br/>
        密  码:<input type="password" name="userMap['0'].password"/><br/>
        <hr/>
        用户名:<input type="text" name="userMap['1'].name" /><br/>
        密  码:<input type="password" name="userMap['1'].password"/><br/>
        <input type="submit" value="提交">
    </form>
    </body>
    </html>

     四、总结

  • 相关阅读:
    高效编写微信小程序
    故事怎么讲才有逼格?
    基于RESTful API 怎么设计用户权限控制?
    【开源访谈】腾讯贺嘉:从小程序谈起,开发者该如何跟进新技术?
    图标字体设计
    微信小程序即将上线,创业者机会在哪里?
    微信小程序开发学习资料
    PC 微信扫码登陆
    一张二维码同时集成微信、支付宝支付
    支付宝Wap支付你了解多少?
  • 原文地址:https://www.cnblogs.com/zhh19981104/p/11749897.html
Copyright © 2020-2023  润新知