将JSON功能添加到您的GWT应用程序中
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); } @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响应。 确保您是从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-app PUBLIC "-//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() { @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(已将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