【问题标题】:Posting JSON array using Ajax and parse in servlet using Gson使用 Ajax 发布 JSON 数组并使用 Gson 在 servlet 中解析
【发布时间】:2013-12-05 17:08:31
【问题描述】:

我是 Java 新手,遇到了这个问题。我正在用 JavaScript 构建一个数组,看起来像这样

  var jsonObj = [];

  jsonObj.push(
  {
     Effect: "Deny",
     RuleID: "Rule1"
   },
   {
     Effect: "Deny",
     RuleID: "Rule2"
   },
   {
     Effect: "Deny",
     RuleID: "Rule3"
    },....

    )

在此之后,我将使用 Ajax 将其传递给 servlet:

 jQuery.ajax({ 
    url: "http://localhost:8080/PolicyConsumerServlet/PolicyServlet",  
    dataType: "json",
    type: 'POST',
    data: {jsondata : JSON.stringify(jsonObj)},

     contentType: 'application/json',
        mimeType: 'application/json',
        success: function(data) { 

            alert('Hi');
        },
    error: function(jqXHR, textStatus, errorThrown) {
        alert("error occurred");
    } 
});

在 servlet 中,在doPost 方法中我写了下面的代码

  StringBuffer jb = new StringBuffer();
  String line = null;

  BufferedReader reader = request.getReader();
  RequestMaker.requestProcess();
  while ((line = reader.readLine()) != null)
      jb.append(line);

  String jsonstring = jb.toString(); 
  Gson gson = new Gson();

  Wrapper[] data = gson.fromJson(jsonstring, Wrapper[].class);

  System.out.println(jb);

而包装类是

public class Wrapper {
  String Effect;
  String RuleID;
}

但这会在下面一行抛出异常

    Wrapper [] data = gson.fromJson(jsonstring, Wrapper[].class);

解析这个 JSON 有什么问题?

【问题讨论】:

  • 尝试将顶级“密钥”添加到您在 JavaScript 中创建的 JSON。例如{"data" : [..values]}
  • 但是这种方法有什么问题?
  • Servlets 不是我的域。但是 JSON,根据定义需要遵循键值结构。因此,建议。

标签: java ajax parsing servlets gson


【解决方案1】:

简单地说,您传递给 servlet 的字符串不是有效的 JSON。

您正在传递一个 Wrapper 数组,但在 JSON 中,一个数组用方括号括起来。此外,由于通用擦除,您需要使用TypeToken

我为您提供了一个示例,该示例显示了适合您的情况以及如何解析它的正确 JSON。您将相关部分复制并粘贴到您的代码中并不难。您可以在 IDE 中粘贴并直接运行我的示例以查看它是否正常工作。

package stackoverflow.questions;

import com.google.gson.*;
import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import stackoverflow.questions.q18123430.Q18123430.ObjectA;

public class Test {

   public static class Wrapper {

      String Effect;
      String RuleID;

      @Override
      public String toString() {
         return "Wrapper [Effect=" + Effect + ", RuleID=" + RuleID + "]";
      }

   }

   public static void main(String[] args) {

      String json = "[ { \"Effect\": \"Deny\",  \"RuleID\": \"Rule1\" }, { \"Effect\": \"Deny\",  \"RuleID\":  \"Rule2\"  }]";
      Type listType = new TypeToken<List<Wrapper>>() {}.getType();

      Gson g = new Gson();
      List<Wrapper> list = g.fromJson(json, listType);
      for (Wrapper w : list)
         System.out.println(w);

   }
}

这是控制台结果:

Wrapper [Effect=Deny, RuleID=Rule1]
Wrapper [Effect=Deny, RuleID=Rule2]

【讨论】:

    【解决方案2】:

    我相信 jQuery.ajax() API 声明数据必须使用 jQuery.param() 转换为查询字符串,并且内容类型必须是 'application/x-www-form -urlencoded'

    要发送到服务器的数据参数数据。它被转换为查询字符串 在这种情况下,数据是url查询字符串的参数。

    data =[
           {"Effect":"Deny","RuleID":"Rule1"},
           {"Effect":"Deny","RuleID":"Rule2"},{"Effect":"Deny","RuleID":"Rule3"}
          ]
    

    在 servlet 中,您可以从 rquest 参数中获取它,而不是从阅读器中获取。

    String jsonData =  req.getParameter("jsondata");
    

    如果您将从 inputStream 或 BufferedReader 获取数据,那么您将在 servlet 中获取数据,如下所示

    jsondata=%5B%7B%22Effect%22%3A%22Deny%22%2C%22RuleID%22%3A%22Rule1%22%7D%2C%7B%22Effect%22%3A%22Deny%22%2C%22RuleID%22%3A%22Rule2%22%7D%2C%7B%22Effect%22%3A%22Deny%22%2C%22RuleID%22%3A%22Rule3%22%7D%5D
    

    这里是萤火虫屏幕快照短

    如果你想从 servlet 中的 reader 对象获取数据,那么你需要将 ajax 调用可选数据参数更改为

    data : JSON.stringify(jsonObj),
    

    //不是这个

     data: {jsondata : JSON.stringify(jsonObj)},
    

    你的ajax调用是这样的

    jQuery.ajax({
              url: "http://localhost:8080/PolicyConsumerServlet/PolicyServlet",
              type : 'POST',
              dataType: "json",
              data : JSON.stringify(jsonObj),
               contentType : 'application/json',
               mimeType : 'application/json',
               success : function(data) {
                             alert('Hi');
                         },
                    error : function(jqXHR, textStatus, errorThrown) {
                        alert("error occurred");
                    }
                });
    

    datatype 参数指定来自服务器的数据类型为 json 您需要在 servlet 中设置内容类型

    response.setContentType("application/json");
    

    您可以在流上发送 json 响应

    response.getWriter().write(jsonString);
    

    【讨论】:

      猜你喜欢
      • 2013-08-27
      • 1970-01-01
      • 2018-01-18
      • 1970-01-01
      • 2017-05-28
      • 1970-01-01
      • 1970-01-01
      • 2012-01-12
      相关资源
      最近更新 更多