Custom formatting for pretty-printing JSON data Java - java

I'm looking for a way I can create a custom formatting "rule/s" of some sort for pretty-printing JSON data. Currently, I'm using GSON to prettyprint, however, I'd like to output in a different format. To be more specific, I am trying to match the formatting of Minecraft JSON files.
Here's an example of GSON pretty-print:
[
{
"when": {
"OR": [
{
"conditional": false,
"facing": "north"
},
{
"conditional": false,
"facing": "north"
}
]
},
"apply": [
{
"model": "chain_command_block",
"weight": 1,
"uvlock": false,
"x": 0,
"y": 0
}
]
}
]
And here's an example of what I am trying to achieve:
[
{ "when": { "OR": [
{"conditional": false, "facing": "north"},
{"conditional": false, "facing": "north"}
]},
"apply": [
{ "model": "chain_command_block", "weight": 1, "uvlock": false, "x": 0, "y": 0 }
]
}
]
I think I'm going to have to manually format and output the data myself using a StringBuilder or a BufferedWriter but if anyone else has any other ideas, please let me know.
Any help is appreciated, thanks.

With GSON, you can register a typeAdapter and customise how a class should be serialised and deserialised.
https://futurestud.io/tutorials/gson-advanced-custom-serialization-part-1
EDIT: With this method, although you can define what data is used and how it's presented (in an array or a csv string etc...), I don't think you can actually change the structure of the pretty-printing.
For example, if I wanted to pretty-print an object, I also want to be able to define when to indent and when to move down to the next line for a certain class type. Still testing though so maybe I'm wrong,,,

Related

After REST API call ,i have key/value pair in the below format ,I Need to extract just the specific value corresponding to the key

Option 1 :if i use the TALEND job i get the JSON results stored with backslashes in the JSON file for some reason(which is unparseable)
{"read":[{"Body":"{\"items\":[{\"executionId\":\"a0613a31-d16d-4c4d-9279-4564a86cdd44\",\"startTimestamp\":\"2021-09-15T22:30:26.854Z\",\"triggerTimestamp\":\"2021-09-15T22:30:27.209Z\",\"userId\":\"user1\",\"status\":\"dispatching\",\"runtime{\"type\":\"REMOTE_ENGINE_CLUSTER\"},\"executionStatus\":\"DISPATCHING_FLOW\"},{\"executionId\":\"49a56eb1-f3c7-4f26-9554-8fa88acde38b\",\"startTimestamp\":\"2021-09-15T22:29:15.999Z\",\"triggerTimestamp\":\"2021-09-15T22:29:16.447Z\",\"userId\":\"user1\",\"executionType\":\"MANUAL\",\"status\":\"dispatching\",\"runtime\":{\"type\":\"REMOTE_ENGINE_CLUSTER\"},\"executionStatus\":\"DISPATCHING_FLOW\"}],\"limit\":100,\"offset\":0,\"total\":2}","ERROR_CODE":null}]}
Option 2:Using the WEB URL:
After REST API call,i have the JSON results like:
BODY:context.statusbody
{
"items": [{
"executionId": "4f679c12-d8d7-4dd7-89d5-507a94503988",
"startTimestamp": "2021-09-14T19:05:01.854Z",
"triggerTimestamp": "2021-09-14T19:05:02.385Z",
"userId": "user1",
"taskId": "60b7f6d31c6e394de0163d35",
"status": "dispatching",
"runtime": {
"type": "REMOTE_ENGINE_CLUSTER"
},
"executionStatus": "DISPATCHING_FLOW"
},
{
"executionId": "4f40b04c-1ac1-42ea-9a36-7c25b1b17fe8",
"startTimestamp": "2021-09-14T19:00:24.769Z",
"triggerTimestamp": "2021-09-14T19:00:25.122Z",
"userId": "user1",
"taskId": "60b7f6d31c6e394de0163d35",
"executionType": "SCHEDULED",
"status": "dispatching",
"runtime": {
"type": "REMOTE_ENGINE_CLUSTER"
},
"executionStatus": "DISPATCHING_FLOW"
}
],
"limit": 100,
"offset": 0,
"total": 2
}
From this i just need to extract the executionID and triggerTimestamp for each iteration and store in a global variable
In my grayed out tjava3 i am using global variable as:
context.testexecutionID=((String)globalMap.get("executionID"));
context.triggerTimestamp=((String)globalMap.get("triggerTimestamp"));
context.executionID=context.testexecutionID.substring(5, context.testexecutionID.lastIndexOf("\"")-3);
context.triggerTime=context.triggerTimestamp.substring(5, context.triggerTimestamp.lastIndexOf("\"")-3);
#sarah Based on your valid JSON you added in your edit .
i suggest you to add after tRest to add tExtractJSONFields component paremetred as such :
Job Design should be in first test :
tRest -> tExtractJSONFields -> tLogRow .
If extraction is good . Second test you have to see my previous my first answer to get global Variables .
Okey , Json i Used for your case to do your requirement :
Note That your Json is not Valid
{
"items": [{
"executionId": "6e5fa777-9ede-42b9-b862-03b4b1b12375",
"startTimestamp": "2021-09-15T05:59:40.599Z",
"triggerTimestamp": "2021-09-15T05:59:41.006Z",
"userId": "user"
}],
"limit ": 100,
"offset ": 0,
"total ": 2
}
Without knowing your job design i just got the output that is posted right here .
My job design is as such :
Important !: your tFileInputJson should be like this to get the 2 fields
Same configuration if your want to used tExtractJSONFields .
to Stock your Global Variables :
to get the globalVariables easy way is to use tfixedFlowInput :
Output :

java json string to url query string

Two days i spend to search efficent method to convert json string to url query string, for example
SRC:
"searchCriteria": {
"filterGroups": [
{
"filters": [
{
"field": "myfiled",
"value": "myvalue",
"conditionType": "eq"
}
]
}
],
"sortOrders": [
{
"field": "string",
"direction": "string"
}
],
"pageSize": 0,
"currentPage": 0
}
to:
http://host/api/?searchCriteria[filterGroups][][filters][][field]=myfield&searchCriteria[filterGroups][][filters][][value]=myvalue&searchCriteria[filterGroups][][filters][][conditionType]=eq&..
Some suggestions ?
A.
Thank U for answer, but ...
I've tryed to pass directly with payload json string and api give me an error, when I put instead query string like in my example, api respond in right way.
In PHP is very simple: json can be converted in array and so with function "http_build_query" it's done ! I'm suprised that not exist similar method .
Alb

How to escape HTML in JSON

I'm wondering how can I escape HTML code in JSON ? I'm using Jackson as my JSON mapper.
In my content I have various characters: tags, single quotes, double quotes, new lines character (\n), tabs etc. I tried to use CharacterEscapes class, but with no results.
My JSON response blows up after using CharacterEscapes. I tried to escape it manually, but also without any results.
So the question is, lets say that we have:
<p>Some text</p>\n<p>"SomeText"</p>
How can I send it back to browser as value of the JSON object?
UPDATE:
Input is:
{
"code": {
"num": 12
},
"obj": {
"label": "somelabel",
"order": 1
},
"det": {
"part": "1",
"cont": true
},
"html": "<p>Mine text</p>"
}
Output:
{
"code": {
"num": 12
},
"obj": {
"label": "somelabel",
"order": 1
},
"det": {
"part":"1",
"cont": true
},
"html":{"code": {
"num": 12
},
"obj": {
"label": "somelabel",
"order": 1
},
"det": {
"part":"
}
For now I have found following solution:
I have added CharacterEscapes to the JsonFactory of the ObjectMapper class.
Also I have changed way of writting JSON into response.
Instead of
objectMapper.writeValue(response.getWriter(), myObject)
I'm doing this:
PrintWriter writer = response.getWriter();
writer.print(String.valueOf(objectMapper.writeValueAsBytes(myObject));
writer.flush();
And it works as I wanted.
I would suggest to use either of below.
1.You can use GSON library for this purpose.
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
2.Use Apache commons StringEscapeUtils.escapeHtml("JSON string").

Most memory efficient way to re format a JSON array in Java

Say I have a JSON array similar to the following:
[
{
"title": "This is a title",
"year": 2013,
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
"thumbsdown": 256
}
},
{
"title": "This is a title",
"year": 2013,
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
"thumbsdown": 256
}
}
]
And the required output is a JSON array like this:
[
{
"title": "This is a title",
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
}
},
{
"title": "This is a title",
"images": {
"image": "http://........jpg",
},
"ratings": {
"thumbsup": 1053,
}
}
]
Iv'e been researching and it's suggested that the most efficient way would be to parse it using the Jackson streaming API. This is for use on a PaaS with limited memory, so I wish to keep the memory usage to the bare minimum.
Is the best way to parse the JSON with Jackson Streaming API, and construct a new JSON array at the same time or simply remove the elements somehow?
I did something similiar with XML once. You can have the requestor tell you what fields you want to get back, and have it only emit those. In my case I had no control over the 3rd party axis xml view, but once I had the view, when I asked for things from it if it was already there I could give back just the pieces I was interested in. As a bonus, if you are marshalling or unmarshalling real java objects from the JSON after getting the json or XML you don't need to build the part of the object graph you don't care about.

Mapfish Print Vector layer GeoJSON example?

I'm using MapFish Print to generate PDFs of maps, creating the map images in the pdf when I only use a WMS layer for base tiles is completely fine. Works as expected.
However, when I add a vector layer and a geoJSON object within it, mapfish print throws the following error:
Exception in thread "tilesReader3" java.lang.NullPointerException
at org.mapfish.print.map.renderers.vector.PointRenderer.renderImpl(PointRenderer.java:113)
at org.mapfish.print.map.renderers.vector.PointRenderer.renderImpl(PointRenderer.java:49)
at org.mapfish.print.map.renderers.vector.GeometriesRenderer.render(GeometriesRenderer.java:69)
at org.mapfish.print.map.renderers.vector.FeaturesRenderer$FeatureRenderer.renderImpl(FeaturesRenderer.java:62)
at org.mapfish.print.map.renderers.vector.FeaturesRenderer$FeatureRenderer.renderImpl(FeaturesRenderer.java:58)
at org.mapfish.print.map.renderers.vector.FeaturesRenderer.render(FeaturesRenderer.java:53)
at org.mapfish.print.map.renderers.vector.FeaturesRenderer$FeatureCollectionRenderer.renderImpl(FeaturesRenderer.java:70)
at org.mapfish.print.map.renderers.vector.FeaturesRenderer$FeatureCollectionRenderer.renderImpl(FeaturesRenderer.java:67)
at org.mapfish.print.map.renderers.vector.FeaturesRenderer.render(FeaturesRenderer.java:53)
at org.mapfish.print.map.readers.VectorMapReader$1.renderOnPdf(VectorMapReader.java:85)
at org.mapfish.print.map.ParallelMapTileLoader.handle(ParallelMapTileLoader.java:97)
at org.mapfish.print.map.ParallelMapTileLoader.handle(ParallelMapTileLoader.java:41)
at org.pvalsecc.concurrent.OrderedResultsExecutor.addOutput(OrderedResultsExecutor.java:148)
at org.pvalsecc.concurrent.OrderedResultsExecutor.access$600(OrderedResultsExecutor.java:23)
at org.pvalsecc.concurrent.OrderedResultsExecutor$Runner.run(OrderedResultsExecutor.java:181)
at java.lang.Thread.run(Unknown Source)
My query that I am sending to Mapfish print is a slightly modified version of the default sample (to use a different WMS as the default for the example is down), with the Vector layer added in, as follows:
{
layout: 'A4 portrait',
title: 'A simple example',
srs: 'EPSG:4326',
units: 'dd',
outputFilename: 'mapfish-print',
outputFormat: 'pdf',
layers: [
{
type: 'WMS',
format: 'image/png',
layers: ['OSM-GB:__all__'],
baseURL: 'http://www.osmgb.org.uk/ogc/wms'
},
{
type: 'Vector',
geoJson: {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-0.0996621,
51.5059247
]
},
"properties": {
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-0.099332,
51.5072000
]
},
"properties": {
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
-0.0945508,
51.50240484
]
},
"properties": {
}
}
]
}
}
],
pages: [
{
center: [0.09, 51.50],
scale: 4000000,
dpi: 190,
mapTitle: "First map",
comment: "The \"routes\" layer is not shown (the scale is too small)",
data: [
{id:1, name: 'blah', icon: 'icon_pan'},
{id:2, name: 'blip', icon: 'icon_zoomin'}
]
},
{
center: [0.09, 51.50],
scale: 500000,
dpi: 190,
mapTitle: "Second map",
comment: "This is a zoomed in version of the first map. Since the scale is more appropriate, we show the \"routes\" layer.",
data: [
{id:1, name: 'blah', icon: 'icon_pan'},
{id:2, name: 'blip', icon: 'icon_zoomin'}
]
}
]
}
The GeoJSON validates and displays on geojsonlint.com, just fine. Having looked through the source for mapfish print I cannot figure out why exactly this is occurring. Though it seems to be something to do with styles, I have had no luck adding one into the request to fix this issue.
-- Update:
If anybody else ever comes across this issue, the problem was that (undocumented), you have to define within the vector layer, a set of styles, and make sure each feature in the geoJSON uses a style.
The problem was that (undocumented), you have to define within the vector layer, a set of styles and a styleproperty, and make sure each feature in the geoJSON uses a style.
The styles themselves are SVG styles, although many of the tags are renamed, so rather than being fill-color, they will be fillColor.
See here for a bit more detail: http://www.mapfish.org/doc/print/protocol.html#layers-params
The SVG styles which need to be defined are in the form of OpenLayers.Feature.Vector.style

Categories

Resources