1. 程式人生 > >Struts2與Ajax數據交互

Struts2與Ajax數據交互

json插件 通過 bsp pre 繼承 結果 而是 返回 input

寫在前面:

  ajax請求在項目中常常使用,今天就平時掌握的總結一下,關於使用ajax請求到Struts2中的action時,前臺頁面與後臺action之間的數據傳遞交互問題。

  這裏我主要記錄下自己所掌握的幾種方式。可以根據自己平時項目的需求來進行選擇。

  

  1.使用stream類型的result

  此種類型可以直接讓Struts2中的action向客戶端瀏覽器生成文本響應。

示例:

  jsp頁面:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8
" language="java" %> <html> <head> <title>ajax提交登錄信息</title> <%--導入js插件--%> <script src="${PageContext.request.contextPath}/demo/js/jquery-1.4.4.min.js" type="text/javascript"></script> </head> <body> <h3>異步登錄</h3> <s:form id
="loginForm" method="POST"> <s:textfield name="username"/> <s:textfield name="psw"/> <input id="loginBtn" type="button" value="提交"> </s:form> <div id="show" style="display:none;"></div> </body> <script type="text/javascript"> $("#loginBtn
").click(function(){ $("#show").hide(); //發送請求login 以各表單裏歌空間作為請求參數 $.get("login",$("#loginForm").serializeArray(), function(data,statusText){ $("#show").height(80) .width(240) .css("border","1px solid black") .css("border-radius","15px") .css("backgroud-color","#efef99") .css("color","#ff0000") .css("padding","20px") .empty(); $("#show").append("登錄結果:"+data+"<br/>"); $("#show").show(600); },"html");//指定服務器響應為html }); </script> </html>

  處理邏輯的action:

/**
 * Description:eleven.action
 * Author: Eleven
 * Date: 2018/1/26 18:09
 */
public class LoginAction extends ActionSupport{

    private String username;
    private String psw;
    //輸出結果的二進制流
    private InputStream inputStream;

    public String login() throws Exception{
        if(username.equals("tom")&& psw.equals("123")){
            inputStream = new ByteArrayInputStream("恭喜您,登錄成功".getBytes("UTF-8"));
        }else{
            inputStream = new ByteArrayInputStream("對不起,登錄失敗".getBytes("UTF-8"));
        }
        return SUCCESS;
    }

    //提供get方法
    public InputStream getInputStream() {

        return inputStream;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPsw() {
        return psw;
    }

    public void setPsw(String psw) {
        this.psw = psw;
    }
}

  action中除了接收頁面傳遞的用戶名、密碼外,還有一個InputStream類型的成員變量,並為它提供了對應的get方法。get方法中返回的二進制流將會直接輸出給客戶端瀏覽器。

  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>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default">

        <action name="login" class="eleven.action.LoginAction" method="login">
            <result type="stream">
                <!--指定stream流生成響應的數據類型-->
                <param name="contentType">text/html</param>
                <!--指定action中由哪個方法去輸出InputStream類型的變量-->
                <param name="inputName">inputStream</param>
            </result>
        </action>
    </package>

</struts>

  在瀏覽器中瀏覽該頁面,並輸入相關信息,然後提交,可以看到後臺action直接將消息數據返回給頁面,而同時頁面也不需要進行刷新,而是直接在局部進行顯示,這是利用了ajax的異步發送請求。註意,此種方式需要在struts.xml文件中要配置類型為stream的流,並設置inputName屬性,並在action中提供InputStream對應的get方法。

  運行截圖:

技術分享圖片

  2.使用json類型的result

  有個jar包struts2-json-plugin-2.3.16.3.jar,可以為Struts2增加JSON插件,即當action中的result的類型設為json時,也可以在客戶端js中異步調用action,並且action中返回的數據,可以直接被JSON插件序列化成json格式的字符串,並將該字符串返回給客戶端瀏覽器。

  示例:

  jsp頁面:

<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax提交登錄信息</title>
    <%--導入js插件--%>
    <script src="${PageContext.request.contextPath}/demo/js/jquery-1.4.4.min.js" type="text/javascript"></script>
</head>
<body>
<h3>異步登錄</h3>
<s:form id="loginForm" method="POST">
    <s:textfield name="username"/>
    <s:textfield name="psw"/>
    <input id="loginBtn" type="button" value="提交">
</s:form>

<div id="show" style="display:none;"></div>
</body>

<script type="text/javascript">

    $("#loginBtn").click(function(){

        $("#show").hide();
        //發送請求login 以各表單裏歌空間作為請求參數
        $.get("login",$("#loginForm").serializeArray(),
            function(data,statusText){
                //此時的data中包含username,psw,age
                $("#show").height(80)
                    .width(300)
                    .css("border","1px solid black")
                    .css("border-radius","15px")
                    .css("backgroud-color","#efef99")
                    .css("color","#ff0000")
                    .css("padding","20px")
                    .empty();
               
                alert(data);
                $("#show").append(data+"<br/>");
                $("#show").show(600);

        },"html");
    });
</script>
</html>

  action代碼:

public class LoginAction extends ActionSupport{

    private String username;
    private String psw;
    private int age;

    public String login() throws Exception{
        age = 18;
        return SUCCESS;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPsw() {
        return psw;
    }

    public void setPsw(String psw) {
        this.psw = psw;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

  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>
    <constant name="struts.enable.DynamicMethodInvocation" value="false" />
    <constant name="struts.devMode" value="true" />

    <package name="default" namespace="/" extends="struts-default,json-default">
        <action name="login" class="eleven.action.LoginAction" method="login">
            <result type="json">
                <param name="noCache">true</param>
                <param name="contentType">text/html</param>
            </result>
        </action>
    </package>

</struts>

  在瀏覽器中瀏覽該頁面,並輸入相關信息,然後提交,可以看到後臺action直接將消息數據返回給頁面,而同時頁面也不需要進行刷新,而是直接在局部進行顯示,這是利用了ajax的異步發送請求。註意,此種方式需要在struts.xml文件中要配置package繼承json-default,且配置result類型為json,並在action中提供需要傳遞數據的對應的get方法。當然了前提是添加了struts2-json-plugin-2.3.16.3.jar,不然struts2是不會自動將數據轉為json格式的數據的。

  效果截圖:

技術分享圖片

  故我們可以總結一下result類型為json的步驟:

    1.導入jar包:struts2-json-plugin-2.3.7.jar
    2.配置struts返回的結果集視圖 設置type=json
    3.設置對應action所在的package繼承自json-default
    4.將要返回的數據提供get方法
    5.在struts.xml中設置返回數據的格式

  對於第5步設置返回數據的格式,可以根據自己項目的需要,去具體設置,這裏只是簡單舉例,並沒有拿復雜的數據,如果是返回一個List集合,那麽對於數據的格式可以進行如下設置:

<result name="test" type="json">
       <!-- 設置數據的來源從某個數據得到 -->
        <!-- 過濾數據從gtmList集合中得到,且只獲取集合中對象的name,跟uuid屬性 --> 
     <param name="root">gtmList</param> <param name="includeProperties"> \[\d+\]\.name, \[\d+\]\.uuid </param>
</result>

  上面這種方式外,還有下面這種方式

<result name="ajaxGetBySm" type="json">
            
          <!-- 一般使用這種方式 先用來源過濾action默認從整個action中獲取所有的(前提是此action中沒有getAction()方法)
                但是為了方便  一般不寫root:action這個
                然後再用包含設置進行過濾設置
          -->                
          <param name="root">action</param>
          <param name="includeProperties">
                 gtmList\[\d+\]\.name,
                 gtmList\[\d+\]\.uuid
          </param>
  </result>

  上面兩種方式都是設置數據從gtmList集合中獲取且,只獲取對象的屬性為name與uuid的。這裏只做簡單的舉例,具體可自己下去深入研究。

  附上json類型的Result允許指定的常用參數:

技術分享圖片

  另外,除了以上兩種是struts2支持的ajax外,其實如果單純的只是可以讓服務器端可以跟客戶端瀏覽器進行數據交互,可以使用response.getWrite()這種方式。

PrintWriter printWriter =response.getWriter();
printWriter.print("success");

  

  選擇哪種方式?

  對於我,如果只是對增刪改功能是否成功的一個flag判斷的數據,則可優先選擇response.getWriter().print("xxx")與設置result類型為stream的方式,但是如果是需要返回大量對象數據,在頁面接收然後進行數據展示,例如頁面通過ajax請求,需要後臺action返回一個list集合,則就要選擇配置result類型為json的方式了。

  

Struts2與Ajax數據交互