JSON簡介
在Web應用程序上工作時,總是會出現客戶端-服務器數據交換的問題。 在此問題上有多種方法,其中許多使用XML進行交換。 執行此任務的一種不太知名的格式是JSON。 JSON(JavaScript對象表示法)是一種輕量級的數據交換格式。 這對人類來說很容易讀寫,對機器來說也很容易解析和生成。 盡管JSON在傳輸的數據上可能有所不同,但與XML相比,JSON被認為不那么冗長,過時。 在線上有多種資源可幫助您開始使用JSON 。
JSON庫
JSON是一種完全獨立于語言的文本格式,并且提供了可用于大量編程語言的庫。 對于Java中的JSON ,實現的源代碼可用。 請注意,該站點未在存檔文件中提供二進制文件,但是我們已經編譯了這些類并將它們捆綁在一個JAR文件中,您可以在此處直接下載。
GWT和JSON集成
在本教程中,我將向您展示如何在GWT中操作JSON,以便您可以與啟用JSON的Web應用程序進行通信。 請注意,在GWT應用程序中,實現客戶端與服務器通信的最常見方法是通過RPC調用 。 因此,使用JSON通常適用于通過普通的舊HTTP調用訪問外部服務器的情況。
創建應用程序
讓我們開始創建一個新的Eclipse項目(“ File?New?Web Application Project”)并將其命名為“ JsonGwtProject”。 選擇僅支持Google的Web工具包,而不支持App Engine。 服務器的角色將由GWT SDK提供的嵌入式Jetty容器扮演。
創建項目框架后,編輯模塊聲明文件(在本例中為“ JsonGwtProject.gwt.xml”)。 在讀取“其他模塊繼承”的行之后添加以下行,以使您的GWT應用程序啟用JSON。
<inherits name="com.google.gwt.json.JSON" />
領域模型對象
現在,讓我們創建將用于保存數據的模型對象。 我們的模型是具有各個領域的“產品”類:
- 名稱
- 公司
- 序列號
- 價格
為了說明如何使用嵌套的JSON表達式,將使用多種價格。
相應的Java類(普通的Java舊對象)如下:
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;}}
應用程序的服務器端
現在,讓我們創建應用程序的服務器端代碼。 我們將創建一個servlet,該servlet將用于模擬從中檢索數據的外部服務器。 Servlet使用產品的靜態列表創建對客戶端的JSON響應(在實際應用程序中,將從DAO或更好地從其他服務中獲取產品)。 確保將下載的json.jar包含在項目的類路徑中,并且還將其復制到“ war \ WEB-INF \ lib”文件夾中。 servlet代碼如下:
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);}@Overrideprotected 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響應。 確保您是從org.json包而不是com.google.gwt.json導入JSON類。 第一步是創建一個JSONObject,它將保存響應。 由于我們很可能擁有許多產品,因此我們還創建了一個JSONObjects列表。 我們遍歷現有產品,并為每個產品創建一個單獨的對象。 在該對象中,我們添加鍵值對,就像使用Map一樣。 對于價格,我們還創建了一個JSONObjects列表,然后將整個列表添加到產品的JSONObject中。 最后,我們將產品對象列表添加到響應的JSONObject中。 JSONObject的toString()方法用于創建字符串表示形式。 對于該示例,結果為:
{“產品”:
[
{“公司”:“公司1”,“名稱”:“產品1”,“價格”:[{“價格”:123.2},{“價格”:123.6}],“序列號”:“ 12345”} {“公司”:“公司2”,“名稱”:“產品2”,“價格”:[{“價格”:234.2},{“價格”:234.6}],“序列號”:“ 67890”} ]}
web.xml中的Servlet配置
現在讓我們配置應用程序,以便Servlet響應特定的URL。 編輯web.xml文件(位于“ war / WEB-INF”中)并粘貼以下內容(所有帶有greetingService聲明的原始內容都將被刪除):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-appPUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN""http://java.sun.com/dtd/web-app_2_3.dtd"><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格式的響應,然后解析響應。 代碼是:
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() {@Overridepublic void onResponseReceived(Request request, Response response) {parseJsonData(response.getText());}@Overridepublic 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(已將servlet配置為響應)。 然后,使用RequestCallback類提供異步回調方法。 最后,請求被發送。 當響應從服務器到達時(如果未發生錯誤),將調用我們的parseJsonData方法。 使用GWT解析JSON數據現在,讓我們看看如何使用GWT內置方法解析接收到的數據。 確保您是從com.google.gwt.json包而不是org.json導入JSON類。 首先,我們使用JSONParser從字符串響應中創建一個JSONValue對象。 然后,我們使用isObject()方法檢索一個JSONObject實例。 因為我們知道響應實際上是產品列表,所以我們通過調用JSONValue的isArray()方法來創建JSONArray類。 然后使用一個循環,并使用發生的JSONString對象的stringValue()方法提取模型的字段。 請注意,為了提取多個價格值,我們使用相同的過程遍歷JSONArray對象。 準備HTML文件還必須更改“ JsonGwtProject.html”,以便為界面的按鈕提供占位符。 編輯它,并在“ noscript”聲明之后添加以下幾行:
...<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項目。
請享用!
- GWT EJB3 Maven JBoss 5.1集成教程
- 使用Spring Security保護GWT應用程序
- GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示
- 建立自己的GWT Spring Maven原型
- 將CAPTCHA添加到您的GWT應用程序
翻譯自: https://www.javacodegeeks.com/2010/07/add-json-gwt-application.html