从Servlet返回JSON响应给Javascript/JSP页面

7

我觉得(其实我知道!)我在这里做错了什么,我正在尝试将一些值填充到HashMap中,并将每个HashMap添加到列表中,该列表将被添加到JSON对象中:

JSONObject json = new JSONObject();
try
{
    Map address;
    List addresses = new ArrayList();

    int count = 15;

    for (int i=0 ; i<count ; i++)
    {
        address = new HashMap();
        address.put("CustomerName"     , "Decepticons" + i);
        address.put("AccountId"        , "1999" + i);
        address.put("SiteId"           , "1888" + i);
        address.put("Number"            , "7" + i);
        address.put("Building"          , "StarScream Skyscraper" + i);
        address.put("Street"            , "Devestator Avenue" + i);
        address.put("City"              , "Megatron City" + i);
        address.put("ZipCode"          , "ZZ00 XX1" + i);
        address.put("Country"           , "CyberTron" + i);
        addresses.add(address);
    }
    json.put("Addresses", addresses);
}
catch (JSONException jse)
{

}
response.setContentType("application/json");
response.getWriter().write(json.toString());

我的问题是,我知道这个返回的是一个字符串,但是我似乎无法解析它(这就是问题所在)。我的问题是,如何返回实际的JSON编码字符串(甚至我是否应该这样做?)或者对于这种类型的问题,最好的攻击方法是什么。我正在使用以下JavaScript:

function getReadyStateHandler(req)
{
    // Return an anonymous function that listens to the
    // XMLHttpRequest instance
    return function ()
    {
        // If the request's status is "complete"
        if (req.readyState == 4)
        {
            // Check that a successful server response was received
            if (req.status == 200)
            {
                msgBox("JSON Response recieved...");
                populateDatagrid(req.responseText.toJSON());
            }
            else
            {
                // An HTTP problem has occurred
                alert("HTTP error: " + req.status);
            }
        }
    }
}

请注意,JSON响应可以正常返回,但它是一个字符串。非常感谢您的建议。我也愿意使用Google的Gson,但对此并不了解太多。

你不应该尝试自己创建一个JSON编码的字符串;如果你的服务器端代码没有提供一个库函数来正确地将对象编码为JSON编码的字符串,那我会非常惊讶。 - Marcel Korpel
可能是重复的问题:在Java中创建JSON对象并将其转换为字符串 - Marcel Korpel
3个回答

29

搞定了!我应该构建一个由JSONObject构成的JSONArray,然后将该数组添加到最终的 "Addresses" JSONObject 中。请注意以下内容:

JSONObject json      = new JSONObject();
JSONArray  addresses = new JSONArray();
JSONObject address;
try
{
   int count = 15;

   for (int i=0 ; i<count ; i++)
   {
       address = new JSONObject();
       address.put("CustomerName"     , "Decepticons" + i);
       address.put("AccountId"        , "1999" + i);
       address.put("SiteId"           , "1888" + i);
       address.put("Number"            , "7" + i);
       address.put("Building"          , "StarScream Skyscraper" + i);
       address.put("Street"            , "Devestator Avenue" + i);
       address.put("City"              , "Megatron City" + i);
       address.put("ZipCode"          , "ZZ00 XX1" + i);
       address.put("Country"           , "CyberTron" + i);
       addresses.add(address);
   }
   json.put("Addresses", addresses);
}
catch (JSONException jse)
{ 

}
response.setContentType("application/json");
response.getWriter().write(json.toString());

这个方法有效并返回了可解析的JSON。希望这能帮助到未来的其他人。感谢 Marcel 的帮助。


如何在ajax中读取这个,我尝试了 alert(responsedata.Addresses.CustomerName); - Dan
太棒了!我在GAE上使用它,与内置的import com.google.appengine.labs.repackaged.org.json.JSONObject包完美地配合工作!非常感谢。 - Abhishek Ghosh

2

我在Servlet中使用了如下的JSONObject。

    JSONObject jsonReturn = new JSONObject();

    NhAdminTree = AdminTasks.GetNeighborhoodTreeForNhAdministrator( connection, bwcon, userName);

    map = new HashMap<String, String>();
    map.put("Status", "Success");
    map.put("FailureReason", "None");
    map.put("DataElements", "2");

    jsonReturn = new JSONObject();
    jsonReturn.accumulate("Header", map);

    List<String> list = new ArrayList<String>();
    list.add(NhAdminTree);
    list.add(userName);

    jsonReturn.accumulate("Elements", list);

Servlet会返回如下所示的JSON对象:
    response.setContentType("application/json");
    response.getWriter().write(jsonReturn.toString());

这个Servlet是通过AngularJs从浏览器中调用的,代码如下:
$scope.GetNeighborhoodTreeUsingPost = function(){
    alert("Clicked GetNeighborhoodTreeUsingPost : " + $scope.userName );

    $http({

        method: 'POST',
        url : 'http://localhost:8080/EPortal/xlEPortalService',
        headers: {
           'Content-Type': 'application/json'
         },
        data : {
            'action': 64,
            'userName' : $scope.userName
        }
    }).success(function(data, status, headers, config){
        alert("DATA.header.status : " + data.Header.Status);
        alert("DATA.header.FailureReason : " + data.Header.FailureReason);
        alert("DATA.header.DataElements : " + data.Header.DataElements);
        alert("DATA.elements : " + data.Elements);

    }).error(function(data, status, headers, config) {
        alert(data + " : " + status + " : " + headers + " : " + config);
    });

};

这段代码有效,弹出对话框显示正确数据:

数据头部状态:成功

数据头部失败原因:无

数据头部详细元素:2个

数据元素:逗号分隔的字符串值,即NhAdminTree、userName


1

我认为你想要做的是在XMLHttpRequest返回时将JSON字符串转换回对象,对吗?

如果是这样,你需要eval该字符串以将其转换为JavaScript对象 - 请注意,这可能是不安全的,因为你相信JSON字符串不是恶意的,因此执行它。最好使用jQuery的parseJSON


嗨,我已经尝试使用那个了,但是我只得到了一个对象 - 请参见此线程:http://stackoverflow.com/questions/6153295/cant-access-property-in-returned-object这解释了我认为返回的是有效JSON的内容。然而,事实上它似乎是传回了一个字符串,所以我很难解析它 - 这就是为什么我在这里问与尝试将JSON传回我的JavaScript函数有关的问题。 - majestica
问题是关于发送JSON编码字符串,而不是关于如何在JavaScript中处理它。 - Marcel Korpel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接