vlambda博客
学习文章列表

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

Chapter 10. Processing JSON with Java EE 7

JavaScript Object Notation (JSON) 是一个 轻量级数据交换格式,常用于 Web 服务中发送和接收数据。目前,Java Web 应用程序使用不同的实现库来消费/生成 JSON。 JSR-353 引入了用于 JSON 处理的 Java API,用于生成、解析、转换和查询 JSON。通过标准化的 JSON API 实现,不需要库,这使得应用程序更具可移植性。 JSR-353 的目标是提供 JSON API 来生成/使用流式 JSON 并为 JSON 构建 Java 对象模型。 Java EE 7 添加了对 JSON 的 Java API 支持。在本章中,我们将讨论对生成和解析 JSON 的支持。本章包含以下部分:

  • 设置环境

  • 创建一个 Maven 项目

  • 创建 JSON

  • 解析 JSON

  • 在 RESTful Web 服务中处理 JSON

Setting up the environment


我们需要下载并安装以下软件:

设置JAVA_HOMEJBOSS_HOMEMAVEN_HOME环境变量添加%JAVA_HOME%/bin%MAVEN_HOME%/bin%JBOSS_HOME%/binPATH 环境变量。

创建一个 WildFly 8.1.0 运行时,如 第 1 章EJB 3.x 入门

Creating a Maven project


在 Eclipse IDE 中创建一个 Maven 项目以进行 JSON 处理。选择文件 | | Other,然后在 New 库中,选择 Maven | Maven 项目,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

New Maven Project 向导中,选择 创建一个简单的项目并点击下一步,如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

指定 Group Id (jboss- json), 工件 ID (json), 版本 (1.0), 包装 (war) 和 Name (json) 为 New Maven Project 并点击 Finish,如此处显示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

创建一个新的 Maven 项目,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

接下来,将 JSP 添加到 处理 JSON。添加 createJson.jsp 来创建 JSON 并添加 parseJson.jsp 来解析 JSON。选择文件 | | Other,然后在 New 库中,选择 网络 | JSP File并点击下一步,如下图:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

选择 webapp 文件夹,指定文件名 (createJson.jsp),点击Finish,如图这里:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

createJson.jsp 文件被 添加到 Maven 项目中。同样,创建 parseJson.jsp。 Eclipse IDE 中 Maven Web 应用程序的目录结构如下图所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

添加jboss-json-api_1.0_specwebapp-javaee7 javax.ws.rs-api 依赖于 pom.xml

  <dependencies>

    <dependency>
      <groupId>org.jboss.spec.javax.json</groupId>
      <artifactId>jboss-json-api_1.0_spec</artifactId>
      <version>1.0.0.Final</version>
    </dependency>

    <dependency>
      <groupId>org.codehaus.mojo.archetypes</groupId>
      <artifactId>webapp-javaee7</artifactId>
      <version>1.1</version>
    </dependency>
    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>2.0</version>
    </dependency>
    
  </dependencies>

Note

完整的 pom.xml 文件可在本章的代码下载中找到。

Creating JSON


在本节中,我们 将为 JSON 创建 Java 对象模型并将 JSON 输出到文件。我们将使用 Java API 进行 JSON 处理,在 createJson.jsp 中创建以下 JSON 结构:

{
"journal":"Oracle Magazine",
"edition":
{"date":"March April 2013","cover":"Public Cloud. Private Cloud"},
"catalog":
[
{"title":"PaaS Fits the Enterprise","author":"David Baum"},
{"title":"On Becoming Others, Limits, and Restoration","author":"Tom Kyte"}
]
}

JSON Java 对象模型由 JsonObject 类表示。 JsonObjectBuilder 接口可用于初始化 JSON 对象模型并创建 JSON 对象。首先,使用 createObjectBuilder() 创建一个 JsonObjectBuilder 对象,即 Json 类静态方法,如下:

JsonObjectBuilder builder = Json.createObjectBuilder();

JsonObjectBuilder 提供了重载的 add() 方法,将不同数据类型的名称/值对添加到 JSON 对象模型中。为 "journal" 添加名称/值对,如下:

builder=builder.add("journal", "Oracle Magazine");

要创建 JSON Java 对象模型结构的层次结构,请为每个子结构调用 Json.createObjectBuilder()。添加"edition" JSON对象模型,如下:

builder=builder.add("edition", Json.createObjectBuilder().add("date","March April 2013").add("cover", "Public Cloud. Private Cloud"));

可以使用静态方法 createArrayBuilder() 添加 JSON 数组,该方法返回 JSON 数组构建器 JsonArrayBuilder 对象,从 < code class="literal">Json 类。要构建 JSON 数组,请为每个 JSON 对象模型子结构调用 Json.createObjectBuilder(),如下所示:

builder=builder.add("catalog", Json.createArrayBuilder().add(Json.createObjectBuilder(). add("title", "PaaS Fits the Enterprise").add("author","David Baum")).add(Json.createObjectBuilder().add("title","On Becoming Others, Limits, and Restoration").add("author","Tom Kyte")));

使用 JsonObjectBuilder 对象创建 一个 JsonObject 对象build() 方法:

JsonObject value = builder.build();

JsonWriter 类用于输出 JSON 对象或数组。创建一个JsonWriter对象输出到jsonOutput.txt文件,如下:

JsonWriter jsonWriter= Json.createWriter(new FileOutputStream(new File("C:/json/jsonOutput.txt")));

使用writeObject方法输出JsonObject对象,如下:

jsonWriter.writeObject(value);

创建 JsonObjectBuilder 的另一种方法是使用 JsonBuilderFactory 接口,这适用于 JsonObjectBuilder 对象是必需的。 JsonBuilderFactory 对象是使用 createBuilderFactory() 创建的,Json 类是静态的方法。随后,调用JsonBuilderFactory对象的createObjectBuilder()方法创建一个JsonObjectBuilder 对象:

JsonBuilderFactory factory = Json.createBuilderFactory(null);
JsonObjectBuilder builder = factory.createObjectBuilder();

创建 JsonWriter 对象的替代方法是 JsonWriterFactory 接口,如果有多个 JsonWriter 对象是必需的。使用静态方法 createWriterFactory() 创建一个 JsonWriterFactory 对象,然后创建一个 JsonWriter 对象使用工厂方法createWriter()

JsonWriterFactory jsonWriterFactory = Json.createWriterFactory(null);
JsonWriter jsonWriter= jsonWriterFactory.createWriter(new FileOutputStream(new File("C:/json/jsonOutput.txt")));

JsonGenerator 接口用于以流的方式生成 JSON。 JsonGenerator 对象可以使用 Json 类静态方法 createGenerator() 或者来自 JsonGeneratorFactory 工厂,可以使用 Json 类静态方法 createGeneratorFactory 创建() 。创建 JsonGenerator 对象的两种模式是:

JsonGenerator generator = Json.createGenerator(new FileOutputStream(new File("C:/json/jsonOutput.txt")));

JsonGeneratorFactory factory = Json.createGeneratorFactory(null);
JsonGenerator generator = factory.createGenerator(new FileOutputStream(new File("C:/json/jsonOutput.txt")));

JsonGenerator 提供 几种方法来生成 JsonObjectJsonArray 名称/值对。 writeStartObject() 方法启动一个 JsonObject 对象模型。 writeStartArray() 方法启动一个 JsonArray 对象模型。结束 JsonObjectJsonArray 对象模型的对应方法是 writeEnd()generator 方法可以按顺序调用以生成完整的 JSON 对象模型:

generator
.writeStartObject()
.write("journal", "Oracle Magazine")
.writeStartObject("edition")
.write("date", "March April 2013")
.write("cover", "Public Cloud. Private Cloud")
         .writeEnd()
         .writeStartArray("catalog")
             .writeStartObject()
                 .write("title", "PaaS Fits the Enterprise")
                 .write("author", "David Baum")
             .writeEnd()
             .writeStartObject()
                 .write("title", "On Becoming Others, Limits, and Restoration")
                 .write("author", "Tom Kyte")
             .writeEnd()
         .writeEnd()
     .writeEnd();

createJson.jsp 文件列出如下:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<%@ page import="javax.json.*, java.io.*,javax.json.stream.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>JSON Array</title>
    </head>
    <body>
        <%
                JsonObjectBuilder builder = Json.createObjectBuilder();
                builder=builder.add("journal", "Oracle Magazine");

                builder=builder.add("edition", Json.createObjectBuilder().add("date","March April 2013").add("cover", "Public Cloud. Private Cloud"));
                builder=builder.add("catalog", Json.createArrayBuilder() .add(Json.createObjectBuilder() .add("title","PaaS Fits the Enterprise") .add("author","David Baum")) .add(Json.createObjectBuilder() .add("title","On Becoming Others, Limits, and Restoration").add("author","Tom Kyte")));
                
                JsonObject value = builder.build();
                JsonWriter jsonWriter= Json.createWriter(new FileOutputStream(new File("C:/json/jsonOutput.txt")));
                jsonWriter.writeObject(value); 
                jsonWriter.close();
                out.println("JSON Array output to jsonOutput.txt");
        
     /**    JsonBuilderFactory factory = Json.createBuilderFactory(null);
         JsonObjectBuilder builder = factory.createObjectBuilder();
                builder=builder.add("journal", "Oracle Magazine");

                builder=builder.add("edition", factory.createObjectBuilder().add("date","March April 2013").add("cover", "Public Cloud. Private Cloud"));
                builder=builder.add("catalog", factory.createArrayBuilder() .add(factory.createObjectBuilder() .add("title","PaaS Fits the Enterprise").add("author","David Baum")) .add(factory.createObjectBuilder() .add("title","On Becoming Others, Limits, and Restoration").add("author","Tom Kyte")));
                
                JsonObject value = builder.build();
                JsonWriterFactory jsonWriterFactory = Json.createWriterFactory(null);
                JsonWriter jsonWriter= jsonWriterFactory.createWriter(new FileOutputStream(new File("C:/json/jsonOutput.txt")));
                jsonWriter.writeObject(value); 
                jsonWriter.close();
                out.println("JSON Array output to jsonOutput.txt");
*/
        
    /**    JsonGeneratorFactory factory = Json.createGeneratorFactory(null);
        JsonGenerator generator = factory.createGenerator(new FileOutputStream(new File("C:/json/jsonOutput.txt")));
  
       //  JsonGenerator generator = Json.createGenerator(new FileOutputStream(new File("C:/json/jsonOutput.txt")));
         generator
     .writeStartObject()
         .write("journal", "Oracle Magazine")
         .writeStartObject("edition")
             .write("date", "March April 2013")
             .write("cover", "Public Cloud. Private Cloud")
         .writeEnd()
         .writeStartArray("catalog")
             .writeStartObject()
                 .write("title", "PaaS Fits the Enterprise")
                 .write("author", "David Baum")
             .writeEnd()
             .writeStartObject()
                 .write("title", "On Becoming Others, Limits, and Restoration")
                 .write("author", "Tom Kyte")
             .writeEnd()
         .writeEnd()
     .writeEnd();
 generator.close();
  out.println("JSON Array output to jsonOutput.txt");*/
        %>
    </body>
</html>

要运行 createJson.jsp,首先 构建并安装 Maven 项目。在Package Explorer中右击项目节点,选择Run As | Maven 安装,如下图所示。本章中的所有 JSP 都可以一起构建;为了重新测试,需要重建 Maven 项目。

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

JSON Web 应用程序被部署到 WildFly 8.1。 Maven 构建输出消息 BUILD SUCCESS,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

使用 URL http://localhost:8080 启动 WildFly Administration Console。现在,点击 管理控制台。指定登录Name密码登录管理控制台。点击管理部署json.war 文件已列出并部署,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

使用 URL http 在 WildFly 服务器上运行 createJson.jsp: //localhost:8080/json-1.0/createJson.jsp ,如下图所示。 createJson.jsp 是在服务器上运行,将 JSON Java 对象模型输出到 C:/json/jsonOutput.txt 文件 .

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

JSON 输出如下所示:

{"journal":"Oracle Magazine","edition":{"date":"March April 2013","cover":"Public Cloud. Private Cloud"},"catalog":[{"title":"PaaS Fits the Enterprise","author":"David Baum"},{"title":"On Becoming Others, Limits, and Restoration","author":"Tom Kyte"}]} 

Parsing JSON


在这个部分,我们将解析上一节生成的jsonOutput.txt文件。 JsonParser 接口用于以流的方式解析 JSON。使用 Json 类中的静态方法 createParser() 创建 JsonParser,如下:

JsonParser parser=Json.createParser(new FileInputStream(new File("C:/json/jsonOutput.txt")));

创建 JsonParser 对象的另一种方法是使用 JsonParserFactory 工厂,可以使用静态方法 createParserFactory(),如下代码行所示:

JsonParserFactory factory = Json.createParserFactory(null);
JsonParser parser = factory.createParser(new FileInputStream(new File("C:/json/jsonOutput.txt")));

JsonParser 对象可用于使用 StringReader 解析 JSON 字符串。首先,为 JSON 创建 StringReader。随后,使用Json类静态方法createParser(Reader)创建一个JsonParser对象代码>,如下:

StringReader reader = new StringReader("{\"journal\":\"Oracle Magazine\",\"edition\":{\"date\":\"March April 2013\",\"cover\":\"Public Cloud. Private Cloud\"},\"catalog\":[{\"title\":\"PaaS Fits the Enterprise\",\"author\":\"David Baum\"},{\"title\":\"On Becoming Others, Limits, and Restoration\",\"author\":\"Tom Kyte\"}]}");
JsonParser parser = Json.createParser(reader);

JsonParser 使用拉解析模型解析 JSON,其中客户端使用 next() 拉取(调用)下一个解析事件方法。生成以下解析事件:

解析事件

描述

START_OBJECT

JSON 对象的开始

END_OBJECT

JSON 对象的结尾

START_ARRAY

JSON数组的开始

END_ARRAY

JON 数组的结尾

KEY_NAME

JSON 对象的键/值对中的名称

VALUE_STRING

JSON 对象或数组中的字符串值

VALUE_NUMBER

JSON 对象或数组中的数值

VALUE_TRUE

JSON 对象或数组中的布尔值 true

VALUE_FALSE

布尔值 false

VALUE_NULL

JSON 对象或数组中的空值

使用 hasNext() 方法 查找下一个解析事件是否可用,并使用 next() 方法获取下一个事件。使用 switch 语句输出事件名称和名称/值对:

while(parser.hasNext()){
        JsonParser.Event parsingState= parser.next();
        switch(parsingState){
}
}

Note

parseJson.jsp 可在本章的代码下载中找到。

代码清单中的某些部分已被注释掉,以测试不同的解析方法。要部署和运行 parseJson.jsp,我们需要重新构建 Maven 项目。首先,清理 Maven 项目。在Eclipse中右键单击json项目节点,选择Run As | Maven clean,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

BUILD SUCCESS 消息表明从先前构建生成的文件已被删除。在 浏览器中使用 URL http:// 调用 parseJson.jsp /localhost:8080/json-1.0/parseJson.jsp 以JSON结构输出事件名称和键/值对,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

解析 JSON 结构的另一种接口是 JsonReader 接口,它读取 JSON 对象 或数组从输入源。 JsonReader 可以从 InputStreamReader 创建。 JsonReader 接口可以使用 Json 类静态方法 createReader() 或者使用 JsonReaderFactory 工厂,它是通过 Json 类静态方法 createReaderFactory( ) 。以下是我们如何做到这一点:

JsonReaderFactory factory = Json.createReaderFactory(null);
JsonReader jsonReader = factory.createReader(new StringReader("[{\"title\":\"PaaS Fits the Enterprise\",\"author\":\"David Baum\"},{\"title\":\"On Becoming Others, Limits, and Restoration\",\"author\":\"Tom Kyte\"}]"));

或者,可以使用 Json 类静态方法 createReader()< 创建 JsonReader 接口/代码>。使用 readArray() 从 JsonReader 接口获取 JSON 数组(JsonArray 对象) 方法,通过 readObject() 方法得到一个 JSON 对象(JsonObject 对象)。随后可以使用JsonObjectJsonArrayget()方法获取键/值对。例如,从 StringReader 读取一个 JSON 数组,数组输出中的名称/值对如下:

JsonReader jsonReader = Json.createReader(new StringReader("[{\"title\":\"PaaS Fits the Enterprise\",\"author\":\"David Baum\"},{\"title\":\"On Becoming Others, Limits, and Restoration\",\"author\":\"Tom Kyte\"}]"));
 JsonArray array = jsonReader.readArray();
jsonReader.close();
JsonObject catalog = array.getJsonObject(0);
 out.println("Title: "+catalog.getString("title"));
   out.println("Author: "+catalog.getString("author"));
   JsonObject catalog2 = array.getJsonObject(1);
 out.println("Title: "+catalog2.getString("title"));
 out.println("Author: "+catalog2.getString("author"));

现在,重新运行 parseJson.jsp 以输出 JSON 数组中的名称/值对,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

Processing JSON in a RESTful web service


JSON 格式 常用于 RESTful Web 服务来交换消息。在本节中,我们将讨论如何在 RESTful Web 服务中使用 Java API 或 JSON 处理。首先,将 RESTful Web 服务依赖添加到 pom.xml

    <dependency>
      <groupId>javax.ws.rs</groupId>
      <artifactId>javax.ws.rs-api</artifactId>
      <version>2.0</version>
    </dependency>

创建示例 REST Web 服务以测试 JSON API。创建一个资源类 JsonResource 并用 @PATH 进行注释,以标识 URI 路径。以下是我们如何做到这一点:

package org.json;

import java.io.StringReader;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

import javax.json.*;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

@Path("jaxrs")
public class JsonResource {
}

要打包资源类,请创建一个扩展 javax.ws.rs.core.Application 类的类。使用 @ApplicationPath 注释来注释 Application 子类>定义资源的基本 URI 模式。覆盖 getClasses() 方法以返回 RESTful Web 服务资源列表。将 org.json.JsonResource 类添加到 HashSet 以从 getClasses()< /代码>方法。 JsonResourceApplication 类扩展了 Application 子类,如下所示:

package org.json;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;

@ApplicationPath("resources")
public class JsonResourceApplication extends Application {

    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> set = new HashSet<Class<?>>();
        set.add(org.json.JsonResource.class);
         
        return set;
    }
    
}

JsonArray as a return type in the resource method for a GET request

Java EE 7 提供对 JsonObject/JsonArray/JsonStructure RESTful Web 服务中的 API。 JsonObject/JsonArray/JsonStructure可以作为返回类型和参数类型在资源方法中。在本节中,我们使用 JsonArray 作为资源方法的返回类型。在生成 application/json 的 JsonResource 类中添加资源方法(getJsonMessage() 并接受 GET 请求。在资源方法中,从StringReader创建JsonReader,从JsonArray创建JsonReader,上一节也讨论过。从此处列出的资源方法返回 JsonArray

    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public JsonArray getJsonMessage() {
        JsonReader jsonReader = Json.createReader(new StringReader("[{\"title\":\"PaaS Fits the Enterprise\",\"author\":\"David Baum\"},{\"title\":\"On Becoming Others, Limits, and Restoration\",\"author\":\"Tom Kyte\"}]"));

        JsonArray array = jsonReader.readArray();
        jsonReader.close();
        return array;

    }

创建 jaxrsGetJsonReturnType.jsp JSP。在此 JSP 中,使用 JAX-RS 2.0 中引入的新 Client API 创建 Client 并调用 RESTful Web 服务。从 ClientBuilder 静态方法 newClient() 创建一个 Client 对象。 Client 对象用于从 RESTful Web 服务发送请求和接收响应。在流畅的 Client API 方法中,可以链接调用。调用 target(String) 方法来构建一个新的 Web 资源目标。

使用 path() 方法构建资源路径。将 "resources" 添加到 Application 子类的路径中。将"jaxrs"添加到访问资源类JsonResource的路径中。由于 getJsonMessage() 方法没有使用 @PATH 注释,因此我们不会为资源方法添加路径组件。使用 request() 方法构建请求,并将可接受的响应类型指定为 application/json (或 MediaType.APPLICATION_JSON)。调用请求的get()方法,指定响应实体的Java类型为JsonArray.class

Client client = ClientBuilder.newClient();
JsonArray array = client.target("http://localhost:8080/json-1.0").path("resources").path("jaxrs").request(MediaType.APPLICATION_JSON).get(JsonArray.class);

获取JsonArray中的JsonObject,使用getJsonObject(int index) 方法。例如,JsonArray中第一个JsonObject中的名称/值对输出如下:

JsonObject catalog = array.getJsonObject(0);
out.println("Title: "+catalog.getString("title"));
out.println("Author: "+catalog.getString("author"));

jaxrsGetJsonReturnType.jsp 文件在此处列出:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<%@ page import="javax.ws.rs.client.ClientBuilder,javax.ws.rs.client.Client ,javax.json.*,javax.json.stream.*,javax.ws.rs.core.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>JSON Array</title>
    </head>
    <body>
        <% 
   
 Client client = ClientBuilder.newClient();
JsonArray array = client.target("http://localhost:8080/json"). path("resources").path ("jaxrs").request(MediaType.APPLICATION_JSON). get(JsonArray.class);

 JsonObject catalog = array.getJsonObject(0);
  
  out.println("Title: "+catalog.getString("title"));
   out.println("<br/>");
   out.println("Author: "+catalog.getString("author"));
   out.println("<br/>");
   
   JsonObject catalog2 = array.getJsonObject(1);
  
  out.println("Title: "+catalog2.getString("title"));
   out.println("<br/>");
   out.println("Author: "+catalog2.getString("author"));
   out.println("<br/>");
 
        %>
    </body>
</html>

json 应用程序的 目录结构如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

部署应用程序之前,运行Maven clean从以前的 Maven 构建。从 WildFly 服务器的 deployments 目录中删除 json.war 文件。如前所述运行 Maven install 以将 JSON 应用程序部署到 WildFly。如果 WildFly 尚未启动,请启动它。在浏览器中使用 http://localhost:8080/json/jaxrsGetJsonReturnType.jsp URL 运行 jaxrsGetJsonReturnType.jsp 以调用RESTful Web 服务,并输出 JsonArray 中的名称/值对,这是从 Web 服务返回的,如下所示:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

Encoding a JsonObject object for a GET request

JsonObject/JsonArray 可以作为资源使用方法参数类型,但有限制; JsonObject/JsonArray 类型不能包含在 GET 请求中,因为GET 请求 URI 不能包含特殊字符(例如 { ,}[]) 在 JSON 中使用。 JSON 对象或数组必须为请求 URI 的 String UTF-8 编码,因此资源方法的参数类型不能为 JsonObject/JsonArray 不使用提供者从字符串转换为 JsonObject/ JsonArray(我们将在后面讨论的一种方法)。在本节中,我们将 JsonObject 编码为 String 并使用 @QueryParam String 类型的注释参数。

在资源类 JsonResource 中,添加一个资源方法,该方法具有 @QueryParam 类型的注释参数“文字”>字符串。在资源方法中,首先使用创建 JsonReaderString 创建 JsonObject StringReader 并随后通过 readObject() 方法获取 JsonObject。使用 getJsonArray()JsonObject 获取 "catalog" JSON数组方法并返回 JsonArray 对象。将以下资源方法添加到 JsonResource 类:

    @Path("jsonp")
    @GET
    @Produces({MediaType.APPLICATION_JSON})
    public JsonArray getJsonArray(@QueryParam("jsonObject") String jsonObjectStr) {
        JsonReader jsonReader = Json.createReader(new StringReader(jsonObjectStr));
        JsonObject jsonObject = jsonReader.readObject();
        jsonReader.close();
        JsonArray jsonArray = jsonObject.getJsonArray("catalog");
        return jsonArray;


    }

添加 jaxrsGetJsonStringMethodParam.jsp JSP。在这个 JSP 中,构建一个 JsonObject 对象,如前一节 创建 JSON 中所述。使用 URLEncoder.encode(String,String) 将 JsonObject 编码为 UTF-8 String 静态方法,如下:

String jsonObjectStr =  URLEncoder.encode(jsonObject.toString(), "UTF-8");

使用流畅的 Client API 构建 客户端请求。使用静态方法 newClient()ClientBuilder 创建一个 Client 对象。使用 http://localhost:8080/json 作为基本 URI 构建 Web 资源目标。为 Application 子类 (path ("resources"))、资源类 (path ("jaxrs")) 和资源方法 (path ("jsonp"))。使用 queryParam()jsonObject 查询参数值设置为编码的 jsonObjectStr 字符串代码>方法。使用 request 方法构建请求并调用请求以使用 get 方法获取 JsonArray.class Java 类型的响应:

Client client = ClientBuilder.newClient();
JsonArray array = client.target("http://localhost:8080/json").path("resources").path ("jaxrs").path("jsonp").queryParam("jsonObject",jsonObjectStr).req uest(MediaType.APPLICATION_JSON).get(JsonArray.class);

输出 JSON 数组中的名称/值对,如上一节所述。 jaxrsGetJsonStringMethodParam.jsp 在这里列出:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<%@ page
  import="java.net.URLEncoder,java.io.StringReader, javax.ws.rs.client.ClientBuilder, javax.ws.rs.client.Client,javax.json.*, javax.json.stream.*,javax.ws.rs.core.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>JSON Array</title>
  </head>
  <body>
    <%
      JsonObjectBuilder builder = Json.createObjectBuilder();
      builder = builder.add("journal", "Oracle Magazine");
      builder = builder.add("edition",
      Json.createObjectBuilder().add("date", "March April 2013")
      .add("cover", "Public Cloud. Private Cloud"));
      builder = builder
      .add("catalog",
      Json.createArrayBuilder()
      .add(Json
      .createObjectBuilder()
      .add("title",
      "PaaS Fits the Enterprise")
      .add("author", "David Baum"))
      .add(Json
      .createObjectBuilder()
      .add("title",
      "On Becoming Others, Limits, and Restoration")
      .add("author", "Tom Kyte")));
      
      JsonObject jsonObject = builder.build();
      String jsonObjectStr = URLEncoder.encode(jsonObject.toString(),
      "UTF-8");
      Client client = ClientBuilder.newClient();
      JsonArray array = client.target("http://localhost:8080/json")
      .path("resources").path("jaxrs").path("jsonp")
      .queryParam("jsonObject", jsonObjectStr)
      .request(MediaType.APPLICATION_JSON).get(JsonArray.class);
      JsonObject catalog = array.getJsonObject(0);
      
      out.println("Title: " + catalog.getString("title"));
      out.println("<br/>");
      out.println("Author: " + catalog.getString("author"));
      out.println("<br/>");
      
      JsonObject catalog2 = array.getJsonObject(1);
      
      out.println("Title: " + catalog2.getString("title"));
      out.println("<br/>");
      out.println("Author: " + catalog2.getString("author"));
      out.println("<br/>");
      %>
  </body>
</html>

在浏览器中使用 URL http://localhost:8080/json/jaxrsGetJsonStringMethodParam.jsp 运行 jaxrsGetJsonStringMethodParam.jsp 以输出 JSON 数组名称/值对,如下图所示。由于 JsonObjectString 的 UTF-8 编码,空格被替换为 String 值输出中的 +

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

JsonObject as a parameter type in the resource method for a POST request

我们无法在 GET 请求中发送 JSON 对象而不将其编码为 String,因为 GET 请求在请求 URI 中包含键/值对。请求 URI 中的 JSON 对象会生成 org.apache.jasper.JasperException: javax.ws.rs.core.UriBuilderException: java.net.URISyntaxException 异常。

JSON 对象可以在 POST 请求中发送,因为键/值对是在请求本身而不是请求 URI 中发送的。在本节中,我们将向具有 JsonObject 类型参数的资源方法发送 POST 请求。在资源方法中,从JsonObject中获取"catalog" JsonArray并返回JsonArray< /代码>对象。添加一个使用 @POSTJsonObject 参数注释的资源方法,如下所示:

@Path("post")
@POST
@Consumes(MediaType.APPLICATION_JSON)  
@Produces(MediaType.APPLICATION_JSON) 
public JsonArray post(final JsonObject jsonObject) {
     JsonArray jsonArray = jsonObject.getJsonArray("catalog");

        return jsonArray;
}

创建 jaxrsPostJsonMethodParam.jsp JSP,该 JSP 创建一个 JsonObject 对象,如前面关于 的小节在 RESTful Web 服务中处理 JSON。使用流畅的 Client API 创建一个 Client 对象 .通过包含 post 资源方法的路径 URI 来构建 Web 资源路径。使用 buildPost(Entity 方法构建 POST 请求调用。使用 javax 中的静态方法 json(T entity) 创建一个 Entity<JsonObject> 对象.ws.rs.client.Entity 。使用响应类型为 JsonArray.classinvoke(Class<T> responseType) 方法调用请求:

JsonObject jsonObject = builder.build();
Client client = ClientBuilder.newClient();
JsonArray array = client.target("http://localhost:8080/json"). path("resources").path("jaxrs").path("post"). request(MediaType.APPLICATION_JSON). buildPost(Entity.json(jsonObject)).invoke(JsonArray.class);

输出 JSON 数组中的名称/值对。 jaxrsPostJsonMethodParam.jsp 文件在此处列出:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<%@ page import="javax.ws.rs.client.*,java.io.StringReader, javax.json.*,javax.json.stream.*, javax.ws.rs.core.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
        <title>JSON Array</title>
    </head>
    <body>
        <% 
          JsonObjectBuilder builder = Json.createObjectBuilder();
                builder=builder.add("journal", "Oracle Magazine");
                builder=builder.add("edition", Json.createObjectBuilder().add("date","March April 2013").add("cover", "Public Cloud. Private Cloud"));
                builder=builder.add("catalog", Json.createArrayBuilder(). add(Json.createObjectBuilder(). add("title","PaaS Fits the Enterprise").add("author","David Baum")).add(Json.createObjectBuilder(). add("title","On Becoming Others, Limits, and Restoration").add("author","Tom Kyte")));
                
                JsonObject jsonObject = builder.build();
                Client client = ClientBuilder.newClient();
JsonArray array = client.target("http://localhost:8080/json").path("resources").path ("jaxrs").path("post").request(MediaType.APPLICATION_JSON).buildPo st(Entity.json(jsonObject)).invoke(JsonArray.class);
  JsonObject catalog=array.getJsonObject(0);
  out.println("Title: "+catalog.getString("title"));
  out.println("<br/>");
  out.println("Author: "+catalog.getString("author"));
  out.println("<br/>");
  JsonObject catalog2 = array.getJsonObject(1);
  out.println("Title: "+catalog2.getString("title"));
  out.println("<br/>");
  out.println("Author: "+catalog2.getString("author"));
  out.println("<br/>");
 
        %>
    </body>
</html>

json 应用程序的目录结构显示在 Package Explorer 如下截图:

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

运行Maven clean删除之前生成的部署文件,运行Maven install 以重新部署 json 应用程序。然后,在 http://localhost:8080/json/jaxrsPostJsonMethodParam.jsp URL 中运行 jaxrsPostJsonMethodParam.jsp 以输出名称/ JSON 数组中的值对,如下一个屏幕截图所示。由于我们没有对随请求发送的 JSON 对象进行编码,因此 JSON 数组 字符串值有空格而不是 +

读书笔记《advanced-java-ee-development-with-wildfly》用Java EE 7处理JSON

Summary


在本章中,我们讨论了 Java EE 7 中用于 JSON 处理的 Java API,以创建 JSON 对象、创建 JSON 数组和解析 JSON 对象/数组。本章还讨论了在 RESTful Web 服务中处理 JSON。本章是本书的总结 我们探讨了在 Eclipse 中与 WildFly 和 Maven 一起使用的常用 Java EE 技术。我们还讨论了 Java EE 7 中的显着新技术、对 JAX-RS 2.0 的支持以及对处理 JSON 的支持。