Правильный способ анализа объектов JSON, содержащих массивы, в сервлетах Java (например, с Gson) - PullRequest
6 голосов
/ 23 марта 2012

Я знаю, что это тема, о которой много говорят, но я все еще не смог найти правильный и четкий ответ на мою конкретную проблему.

У меня есть JSON, который выглядит так:

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

Вопрос, который у меня возникает, заключается в том, какой именно способ (или лучший способ по стилю) проанализировать это в сервлете Java (например, с использованием GSON)?Сначала я отправляю этот JSON на сервер, используя метод jQuery ajax, например:

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

Теперь в сервлете я узнал, что должен был проанализировать этот 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] выдает исключение!

Копая глубже Я обнаружил, что при циклическом изменении имен параметров запроса он содержал1016 * параметр с именем "playerUIDs []" со значением только 123 (первое целое число в массиве).Это было странно, потому что я, казалось, вообще не мог получить доступ к следующим значениям.

Затем я прочитал, что объекты JSON должны быть преобразованы в строку перед POST, поэтому я добавил JSON.stringify (myData), нотеперь только имена параметров запроса содержали ОДНО имя , которое представляло собой сам объект JSON в строковом состоянии:

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

Мне показалось, что единственный способ заставить это работать - создать внутреннееclass:

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]);
}

Теперь все значения есть, но это больше похоже на взлом (чтение JSON изимя параметра запроса), чем элегантное решение, поэтому я подумал, что я спрошу вас, ребята, какой именно «правильный» способ сделать это?Я что-то упускаю из виду?

Заранее спасибо!

Ответы [ 3 ]

8 голосов
/ 23 марта 2012

Вы не используете 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)}

Это будет публиковать ваш объект "myData" как JSON, в параметре с именем "произвольное_имя".

1 голос
/ 30 июня 2014

JSON на сервер с использованием метода jQuery ajax

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
    });
}

Кнопка отправки

<button onclick="send();" id="send">Send</button>

Обработка Java-сервлета

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]);
}
}
1 голос
/ 23 марта 2012

В реальном мире вы, как правило, не будете отправлять фактический объект json сервлету, и в большинстве случаев вы не будете часто обрабатывать заполнение значений из запроса.JSON - это нотация объектов JavaScript - и она прекрасно подходит для использования при кодировании на стороне клиента.

Проще использовать строку запроса для параметров, а не сообщение с json (что, по-видимому, вы на самом деле делаете).host / url? gameId = 5 & nrPlayers = 2

Что касается того, как заполнять значения, соглашение о переконфигурации - это путь к чистому коду.Вы можете использовать фреймворки, такие как Struts, чтобы переложить всю передачу значений в фреймворк.Не уверен, как выглядит все ваше приложение, ваше намерение писать (то есть писать сервлеты с нуля - это отличный способ научиться, но не является обычной практикой в ​​реальных средах разработки приложений), так что это может быть или не быть полезным ответом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...