Struts2与Ajax数据交互

Posted 蚊蚊蚊蚊蚊170624

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Struts2与Ajax数据交互相关的知识,希望对你有一定的参考价值。

写在前面:

  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()这种方式。但是要特别注意,如果前台页面发送的是ajax请求,注意修改dataType类型,就不要再设置为json类型了,不然会接收不到

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

  

  选择哪种方式?

  对于我,如果只是对增删改功能是否成功的一个flag判断的数据,则可优先选择response.getWriter().print("xxx")与设置result类型为stream的方式,但是如果是需要返回大量对象数据,在页面接收然后进行数据展示,例如页面通过ajax请求,需要后台action返回一个list集合,则就要选择配置result类型为json的方式了。

  

 

以上是关于Struts2与Ajax数据交互的主要内容,如果未能解决你的问题,请参考以下文章

ajax前台与struts2中action交互详见

使用Struts2和jQuery EasyUI实现简单CRUD系统(转载汇总)

Struts2-Ajax整合之JavaScript版本

Struts2-Ajax整合之Jquery版本

ajax struts2 前后台 交互

Struts2与jQuery.ajax()的结合