I'm trying to pretty print json with the javax.json API
The code I'm currently using is as follows:
private String prettyPrint(String json) {
StringWriter sw = new StringWriter();
try {
JsonReader jr = Json.createReader(new StringReader(json));
JsonObject jobj = jr.readObject();
Map<String, Object> properties = new HashMap<>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
JsonGeneratorFactory jf = Json.createGeneratorFactory(properties);
JsonGenerator jg = jf.createGenerator(sw);
jg.write(jobj).close();
} catch (Exception e) {
}
String prettyPrinted = sw.toString();
return prettyPrinted;
}
I'm getting the following exception:
11:47:08,830 ERROR [stderr] (EJB default - 1) javax.json.stream.JsonGenerationException: write(JsonValue) can only be called in array context
11:47:08,835 ERROR [stderr] (EJB default - 1) at org.glassfish.json.JsonGeneratorImpl.write(JsonGeneratorImpl.java:301)
11:47:08,838 ERROR [stderr] (EJB default - 1) at org.glassfish.json.JsonPrettyGeneratorImpl.write(JsonPrettyGeneratorImpl.java:55)
11:47:08,841 ERROR [stderr] (EJB default - 1) at org.proactive.rest.VideoFeedService.prettyPrint(VideoFeedService.java:247)
11:47:08,843 ERROR [stderr] (EJB default - 1) at org.proactive.rest.VideoFeedService.requestVideoFeedData(VideoFeedService.java:124)
11:47:08,845 ERROR [stderr] (EJB default - 1) at org.proactive.rest.VideoFeedService.run(VideoFeedService.java:86)
11:47:08,848 ERROR [stderr] (EJB default - 1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
11:47:08,850 ERROR [stderr] (EJB default - 1) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
11:47:08,852 ERROR [stderr] (EJB default - 1) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
11:47:08,854 ERROR [stderr] (EJB default - 1) at java.lang.reflect.Method.invoke(Method.java:483)
You should be using JsonWriter instead of JsonGenerator.
Replace these lines:
JsonGeneratorFactory jf = Json.createGeneratorFactory(properties);
JsonGenerator jg = jf.createGenerator(sw);
jg.write(jobj).close();
with these:
JsonWriterFactory writerFactory = Json.createWriterFactory(properties);
JsonWriter jsonWriter = writerFactory.createWriter(sw);
jsonWriter.writeObject(jobj);
jsonWriter.close();
You can achieve pretty printing by utilizing the JsonWriterFactory
. This takes a configuration map of properties.
Use the JsonWriter
to write to the StringWriter
.
I added a convenience method which already passes the PRETTY_PRINTING
flag for you.
public static String prettyPrint(JsonStructure json) {
return jsonFormat(json, JsonGenerator.PRETTY_PRINTING);
}
public static String jsonFormat(JsonStructure json, String... options) {
StringWriter stringWriter = new StringWriter();
Map<String, Boolean> config = buildConfig(options);
JsonWriterFactory writerFactory = Json.createWriterFactory(config);
JsonWriter jsonWriter = writerFactory.createWriter(stringWriter);
jsonWriter.write(json);
jsonWriter.close();
return stringWriter.toString();
}
private static Map<String, Boolean> buildConfig(String... options) {
Map<String, Boolean> config = new HashMap<String, Boolean>();
if (options != null) {
for (String option : options) {
config.put(option, true);
}
}
return config;
}
Here's a solution for pretty printing (indenting) JSON with javax.json
and javax.ws.rs
using Jersey:
@GET
@Path("stuff")
public Response getStuff(@QueryParam("pretty") boolean pretty) {
JsonArrayBuilder stuff = Json.createArrayBuilder().add("foo").add("bar");
JsonObject jsonObject = Json.createObjectBuilder()
.add("status", "OK")
.add("data", stuff).build();
if (pretty) {
Map<String, Boolean> config = new HashMap<>();
config.put(JsonGenerator.PRETTY_PRINTING, true);
JsonWriterFactory jwf = Json.createWriterFactory(config);
StringWriter sw = new StringWriter();
try (JsonWriter jsonWriter = jwf.createWriter(sw)) {
jsonWriter.writeObject(jsonObject);
}
// return "Content-Type: application/json", not "text/plain"
MediaType mediaType = MediaType.APPLICATION_JSON_TYPE;
return Response.ok(sw.toString(), mediaType).build();
} else {
return Response.ok(jsonObject).build();
}
}
Sample curl
output:
$ curl -i http://localhost:8080/api/stuff?pretty=true
HTTP/1.1 200 OK
Content-Type: application/json
Date: Fri, 08 Aug 2014 14:32:40 GMT
Content-Length: 71
{
"status":"OK",
"data":[
"foo",
"bar"
]
}
$ curl http://localhost:8080/api/stuff
{"status":"OK","data":["foo","bar"]}
See also:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.