解析包含Java Servlets中数组的JSON对象的正确方法(例如使用Gson)

我知道这是一个备受关注的话题,但我仍然无法找到对我具体问题的正确而明确的答案。

我有一个看起来像这样的JSON:

var myData = { "gameID" : gameID, "nrOfPlayers" : 2, "playerUIDs" : [123, 124] }; 

我所拥有的问题正是在Java servlet中解析它的正确方法(或最好的方式,样式方式)(例如使用GSON)? 首先,我使用jQuery ajax方法将此JSON发送到服务器,如下所示:

 jQuery.ajax({ url : path, data : myData, success : successFunction, error : function(data) { console.log("Error: ", data); } , type : "post", timeout : 30000 }); 

现在在servlet中我了解到我应该能够像这样解析JSON:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Gson gson = new Gson(); String gameID = gson.fromJson(request.getParameter("gameID"), String.class); String nrOfPlayers = gson.fromJson(request.getParameter("nrOfPlayers"), String.class); String[] playerUIDs = gson.fromJson(request.getParameter("playerUIDs"), String[].class); log.info(gameID); log.info(nrOfPlayers); log.info(playerUIDs[0] +" "+ playerUIDs[1]); } 

但是playerUIDs变量是IS NULL,当然playerUIDs [0]会引发exception!

深入挖掘我发现当循环遍历请求参数名称时,它包含一个名为“playerUIDs []”参数 ,其值仅为123 (数组中的第一个int)。 这很奇怪,因为我似乎根本无法访问下一个值。

然后我读到在POST之前应该对JSON对象进行字符串化,所以我添加了JSON.stringify(myData),但现在请求参数名称只包含一个名称 ,它是字符串化状态下的JSON对象本身:

 INFO: Parameter name = {"gameID":"b6a51aabb8364b04bce676eafde1bc87","nrOfPlayers":2,"playerUIDs":[123,124]} 

我似乎让这个工作的唯一方法是创建一个内部类:

 class GameStart { protected String gameID; protected int nrOfPlayers; protected int[] playerUIDs; } 

并从请求参数名称解​​析JSON,如下所示:

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Gson gson = new Gson(); Enumeration en = request.getParameterNames(); GameStart start = null; while (en.hasMoreElements()) { start = gson.fromJson((String) en.nextElement(), GameStart.class); } log.info(start.gameID); log.info(String.valueOf(start.nrOfPlayers)); log.info(start.playerUIDs[0] +" "+ start.playerUIDs[1]); } 

现在所有的值都存在,但这看起来更像是一个hack(从请求参数名称读取JSON)而不是优雅的解决方案,所以我想我会问你们这样做的“正确”方法究竟是什么? 我错过了一些明显的东西吗

提前致谢!

您不是使用JSON将数据发送到服务器:

 data : myData, 

这将参数指定为JavaScript对象 ,但不一定是JSON。 这意味着如果您执行GET请求:

 data: {name1: "value1", name2: "value2"} 

请求将是:

 http://some/page?name1=value1&name2=value2 

这基本上是您在第一次调用时看到的内容,其中所有内容都转换为字符串,然后作为表单参数发送。

你在第二个版本中所做的几乎就是你应该做的。 唯一的区别是您需要使用JavaScript对象作为data的参数,而不仅仅是字符串:

 data: {arbitraryNameHere: JSON.stringify(myData)} 

这将在名为“arbitraryNameHere”的参数中将您的“myData”对象发布为JSON。

在现实世界中,您通常不会将实际的json对象发送到servlet,并且在大多数情况下,您不会经常处理来自请求的填充值。 JSON是JavaScript对象表示法 – 当用于客户端编码时,它很棒。

使用params的查询字符串更容易,而不是使用json的post(看起来你实际上在做)。 主机/ URL?游戏ID = 5&nrPlayers = 2

至于如何填充值,配置约定是获得最干净代码的方法。 您可以使用struts之类的框架将所有值的传输卸载到框架上。 不确定你的整个应用程序看起来是什么,你的写作意图(即从头开始编写servlet是一种很好的学习方法,但在实际的应用程序开发环境中并不常见),所以这可能是也可能不是一个有用的答案。

使用jQuery ajax方法向服务器提供JSON

 function send() { var myData = {"gameID": 30, "nrOfPlayers": 2, "playerUIDs": [123, 124] }; jQuery.ajax({ url: "servletName", data: JSON.stringify(myData), success: function(){ //console.log(JSON.stringify(myData)); }, error: function(data) { console.log("Error: ", data); }, type: "post", timeout: 30000 }); } 

发件人按钮

  

Java servlet处理

 public class servletName extends HttpServlet { class GameStart { protected String gameID; protected int nrOfPlayers; protected int[] playerUIDs; } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Gson gson = new Gson(); Enumeration en = request.getParameterNames(); GameStart start = null; while (en.hasMoreElements()) { start = gson.fromJson((String) en.nextElement(), GameStart.class); } System.out.println(start.gameID); System.out.println(start.playerUIDs[0] +" "+ start.playerUIDs[1]); } }