Статьи

Добавьте возможности JSON в ваше приложение GWT

Введение в JSON
При работе с веб-приложениями всегда возникает проблема обмена данными между клиентом и сервером. Существуют различные подходы к этому вопросу, и многие из них используют XML для обмена. Не очень известный формат для выполнения этой задачи — JSON. JSON (JavaScript Object Notation) — это легкий формат обмена данными. Людям легко читать и писать, а машинам — анализировать и генерировать. JSON считается менее многословным и раздутым, чем XML, и более читабельным, хотя они могут различаться в передаваемых данных. Есть несколько ресурсов онлайн, чтобы начать вас с JSON .

Библиотеки JSON
JSON — это текстовый формат, полностью независимый от языка, и есть библиотеки, доступные для огромного количества языков программирования. Для JSON в Java доступен исходный код реализации. Обратите внимание, что сайт не предоставляет двоичные файлы в архивном файле, но мы скомпилировали классы и объединили их в файл JAR, который вы можете непосредственно скачать здесь .

Интеграция GWT и JSON
В этом уроке я покажу вам, как управлять JSON в GWT, чтобы вы могли взаимодействовать с веб-приложением с поддержкой JSON. Обратите внимание, что в приложениях GWT наиболее распространенным способом установления связи между клиентом и сервером является вызов RPC . Таким образом, использование JSON применимо в основном в том случае, когда внешний сервер доступен через простые старые HTTP-вызовы.

Создание приложения
Давайте начнем с создания нового проекта Eclipse («Файл? Новый? Проект веб-приложения») и назовем его «JsonGwtProject». Выберите поддержку только для веб-инструментария Google, но не для App Engine. Роль сервера будет выполнять встроенный контейнер Jetty, предоставляемый GWT SDK.

После создания каркаса проекта отредактируйте файл объявления модулей (в нашем случае он называется «JsonGwtProject.gwt.xml»). Добавьте следующую строку после строки, которая гласит «Другие модули наследуются», чтобы включить поддержку JSON вашего приложения GWT.

1
<inherits name="com.google.gwt.json.JSON" />

Объектная модель предметной области
Теперь давайте создадим объект модели, который будет использоваться для хранения данных. Наша модель — это класс «Продукт» с различными полями:

  • название
  • Компания
  • Серийный номер
  • Цены

Несколько цен будут использоваться, чтобы показать вам, как использовать вложенные выражения JSON.

Соответствующий класс Java (обычный старый объект Java) выглядит следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.javacodegeeks.json.gwt.server.model;
 
import java.util.LinkedList;
import java.util.List;
 
public class Product {
  
 private String name;
 private String company;
 private String serialNumber;
 private List<Double> prices = new LinkedList<Double>();
  
 public Product(String name, String company, String serialNumber, List<Double> prices) {
  super();
  this.name = name;
  this.company = company;
  this.serialNumber = serialNumber;
  this.prices = prices;
 }
  
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getCompany() {
  return company;
 }
 public void setCompany(String company) {
  this.company = company;
 }
 public String getSerialNumber() {
  return serialNumber;
 }
 public void setSerialNumber(String serialNumber) {
  this.serialNumber = serialNumber;
 }
 public List<Double> getPrices() {
  return prices;
 }
 public void setPrices(List<Double> prices) {
  this.prices = prices;
 }
 
}

Серверная часть приложения
Теперь давайте создадим код приложения на стороне сервера. Мы создадим сервлет, который будет использоваться для имитации внешнего сервера, с которого будут извлекаться данные. Сервлет создает JSON-ответ клиенту, используя статический список продуктов (в реальном приложении продукты будут выбираться из DAO или, что еще лучше, из другой службы). Убедитесь, что вы включили json.jar, который вы скачали, в classpath вашего проекта и что он также скопирован в папку «war \ WEB-INF \ lib». Код сервлета следующий:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package com.javacodegeeks.json.gwt.server;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import org.json.JSONObject;
 
import com.javacodegeeks.json.gwt.server.model.Product;
 
public class ProductsServlet extends HttpServlet {
  
 private static final long serialVersionUID = 8032611514671727168L;
  
 private static List<Product> products = new LinkedList<Product>();
  
 static {
  Product product1 = new Product("Prod1", "Company1", "12345", Arrays.asList(123.2, 123.6));
  Product product2 = new Product("Prod2", "Company2", "67890", Arrays.asList(234.2, 234.6));
  products.add(product1);
  products.add(product2);
 }
 
 @Override
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
  try {
    
   JSONObject responseObj = new JSONObject();
    
   List<JSONObject> productObjects = new LinkedList<JSONObject>();
    
   for (Product product : products) {
     
    JSONObject productObj = new JSONObject();
     
    productObj.put("name", product.getName());
    productObj.put("company", product.getCompany());
    productObj.put("serialNumber", product.getSerialNumber());
     
    List<JSONObject> pricesObjects = new LinkedList<JSONObject>();
    for (Double price : product.getPrices()) {
     JSONObject priceObj = new JSONObject();
     priceObj.put("price", price);
     pricesObjects.add(priceObj);
    }
     
    productObj.put("prices", pricesObjects);
     
    productObjects.add(productObj);
   }
    
   responseObj.put("products", productObjects);
    
   PrintWriter writer = resp.getWriter();
   writer.write(responseObj.toString());
   writer.flush();
    
  }
  catch (Exception e) {  
   e.printStackTrace();
   throw new ServletException(e);
  }
   
 }
  
}

Генерация ответов Java JSON
Позвольте мне объяснить, как создается ответ JSON. Убедитесь, что вы импортируете классы JSON из пакета org.json, а не из com.google.gwt.json. Первым шагом является создание JSONObject, который будет содержать ответ. Поскольку у нас, скорее всего, есть несколько продуктов, мы также создаем список JSONObjects. Мы перебираем существующие продукты и создаем отдельный объект для каждого из них. В этот объект мы добавляем пары ключ-значение, как мы это делаем с картой. Для цен мы также создаем список JSONObjects, а затем добавляем весь список в JSONObject продукта. Наконец, мы добавляем список объектов продукта в JSONObject ответа. Метод toString () JSONObject используется для создания строкового представления. Для этого примера результат:

{«продукты»:
[
{ «Компания»:»Company1″,»имя»:»Prod1″,»цены»: [{ „цена“: 123,2}, { „цена“: 123,6}],»SERIALNUMBER»:»12345″}
{ «Компания»:»Общества2″,»имя»:»Prod2″,»цены»: [{ „цена“: 234,2}, { „цена“: 234,6}],»SERIALNUMBER»:»67890″}
]}

Конфигурация сервлета в web.xml
Теперь давайте настроим приложение так, чтобы сервлет отвечал на определенный URL. Отредактируйте файл web.xml (находится в «war / WEB-INF») и вставьте следующее содержимое (все исходное содержимое с объявлением приветствия приветствия удалено):

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 
<web-app>
   
  <!-- Servlets -->
  <servlet>
    <servlet-name>ProductsServlet</servlet-name>
     <servlet-class>
     com.javacodegeeks.json.gwt.server.ProductsServlet
    </servlet-class>
  </servlet>
   
  <servlet-mapping>
    <servlet-name>ProductsServlet</servlet-name>
    <url-pattern>/jsongwtproject/products.json</url-pattern>
  </servlet-mapping>
   
  <!-- Default page to serve -->
  <welcome-file-list>
    <welcome-file>JsonGwtProject.html</welcome-file>
  </welcome-file-list>
 
</web-app>

Клиентская сторона с GWT
Наконец, давайте создадим точку входа приложения GWT с именем «JsonGwtProject» (исходное содержимое полностью удалено). Клиент вызовет HTTP-вызов GET на сервер, получит ответ в формате JSON и затем проанализирует ответ. Код является:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
036
037
038
039
040
041
042
043
044
045
046
047
048
049
050
051
052
053
054
055
056
057
058
059
060
061
062
063
064
065
066
067
068
069
070
071
072
073
074
075
076
077
078
079
080
081
082
083
084
085
086
087
088
089
090
091
092
093
094
095
096
097
098
099
100
101
102
103
package com.javacodegeeks.json.gwt.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.RootPanel;
 
public class JsonGwtProject implements EntryPoint {
     
    public void onModuleLoad() {
         
        final Button fetchDataButton = new Button("Fetch data");
        fetchDataButton.addStyleName("sendButton");
         
        RootPanel.get("fetchDataButtonContainer").add(fetchDataButton);
         
        fetchDataButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                fetchDataFromServer();
            }
        });
         
    }
 
    private void fetchDataFromServer() {
         
        try {
             
            RequestBuilder rb = new RequestBuilder(
                 RequestBuilder.GET, "/jsongwtproject/products.json");
             
            rb.setCallback(new RequestCallback() {
                @Override
                public void onResponseReceived(Request request, Response response) {
                    parseJsonData(response.getText());
                }
                @Override
                public void onError(Request request, Throwable exception) {
                    Window.alert("Error occurred" + exception.getMessage());
                }
            });
            rb.send();
             
        }
        catch (RequestException e) {
            Window.alert("Error occurred" + e.getMessage());
        }
    }
 
    private void parseJsonData(String json) {
 
        JSONValue value = JSONParser.parse(json);
 
        JSONObject productsObj = value.isObject();
         
        JSONArray productsArray = productsObj.get("products").isArray();
         
        if (productsArray != null) {
             
            for (int i=0; i<=productsArray.size()-1; i++) {
                 
                JSONObject productObj = productsArray.get(i).isObject();
                 
                String name = productObj.get("name").isString().stringValue();
                String company = productObj.get("company").isString().stringValue();
                String serialNumber = productObj.get("serialNumber").isString().stringValue();
                 
                StringBuffer priceSb = new StringBuffer();
                 
                JSONArray pricesArray = productObj.get("prices").isArray();
                if (pricesArray != null) {
                    for (int j=0; j<=pricesArray.size()-1; j++) {
                        JSONObject priceObj = pricesArray.get(j).isObject();
                        double price = priceObj.get("price").isNumber().doubleValue();
                        if (j!=pricesArray.size()-1) {
                            priceSb.append("-");
                        }
                    }
                }
                String message = "Product -- " +
                    "\nName: " + name +
                    "\nCompany: " + company +
                    "\nSerial: " + serialNumber +
                    "\nPrices: " +  priceSb.toString();
                Window.alert(message);
                 
            }
             
        }
    }
 
}

Для вызова HTTP используется класс RequestBuilder . Метод HTTP (GET) определяется вместе с URL-адресом конечной точки (где сервлет настроен для ответа). Затем асинхронный метод обратного вызова предоставляется с использованием класса RequestCallback . Наконец, запрос отправлен. Когда ответ приходит с сервера (если ошибок не было), вызывается наш метод parseJsonData. Разбор данных JSON с помощью GWT Теперь посмотрим, как анализировать полученные данные с помощью встроенных методов GWT. Убедитесь, что вы импортируете классы JSON из пакета com.google.gwt.json, а не из org.json. Сначала мы используем JSONParser для создания объекта JSONValue из строкового ответа. Из этого мы извлекаем экземпляр JSONObject, используя метод isObject () . Поскольку мы знаем, что ответ на самом деле представляет собой список продуктов, мы создаем класс JSONArray , вызывая метод isArray () класса JSONValue. Затем используется цикл, и мы извлекаем поля модели с помощью метода stringValue () объекта JSONString . Обратите внимание, что для извлечения нескольких значений цены мы используем одну и ту же процедуру, проходящую по объекту JSONArray. Подготовка файла HTML «JsonGwtProject.html» также необходимо изменить, чтобы обеспечить заполнитель для кнопки интерфейса. Отредактируйте его и добавьте следующие строки после объявления «noscript»:

01
02
03
04
05
06
07
08
09
10
11
12
...
    <h1>Web Application Starter Project</h1>
 
    <table align="center">
      <tr>
        <td id="fetchDataButtonContainer"></td>
      </tr>
      <tr>
        <td colspan="2" style="color:red;" id="errorLabelContainer"></td>
      </tr>
    </table>
...

Запуск примера Если мы запустим проект, появится интерфейс, на самом деле есть только кнопка. Нажав на кнопку. данные JSON извлекаются, выполняется анализ и результаты выводятся на экран: Это было бы все. Как всегда, вы можете скачать проект Eclipse отсюда .

Наслаждайтесь!

Статьи по Теме :