I have JSON string that needs to be converted in Java object using Google Gson library.
I am stuck in converting due to forward slash in the following JSON string.
{
"status":"200",
"results":{
"resultitems":[
{
"uri":"/document/id/e20a8dad50d91a839c50ab5f323f3df3",
"path":"Data/xyz/abcdata",
"metadata":{
"data/category/item":"yahoo/post",
"ast_id":"67677"
}
}
]
}
Indeed, for Data/category/item, I am getting a null value. How can I correctly parse it?
Just a starting note: the JSON you put in request is not a valid JSON, but can be easily fixed adding a brace (I used fixed JSON in my answer).
I suggest you to parse your JSON this way. Declare the following classes.
public class Container {
public int status;
public Results results;
#Override
public String toString() {
return "Container [status=" + status + ", results=" + results + "]";
}
}
public class Results {
public List<ResultItem> resultitems;
#Override
public String toString() {
return "Results [resultitems=" + resultitems + "]";
}
}
public class ResultItem {
String uri;
String path;
HashMap metadata;
#Override
public String toString() {
return "ResultItem [uri=" + uri + ", path=" + path + ", metadata="
+ metadata + "]";
}
}
and then call this code:
public class Q19684865 {
public static void main(String[] args) {
String json = " { "
+ " \"status\":\"200\", "
+ " \"results\":{ "
+ " \"resultitems\":[ "
+ " { "
+ " \"uri\":\"/document/id/e20a8dad50d91a839c50ab5f323f3df3\", "
+ " \"path\":\"Data/xyz/abcdata\", "
+ " \"metadata\":{ "
+ " \"data/category/item\":\"yahoo/post\", "
+ " \"ast_id\":\"67677\" "
+ " } "
+ " } "
+ " ] "
+ " } "
+ " } ";
Container c = new Gson().fromJson(json, Container.class);
System.out.println("this is the parsed json: " +c);
System.out.println("this is the property 'data/category/item': "+c.results.resultitems.get(0).metadata.get("data/category/item"));
}
and this is the result:
this is the parsed json: Container [status=200, results=Results [resultitems=[ResultItem [uri=/document/id/e20a8dad50d91a839c50ab5f323f3df3, path=Data/xyz/abcdata, metadata={data/category/item=yahoo/post, ast_id=67677}]]]]
this is the property 'data/category/item': yahoo/post
Explanation: normally you need just POJOs if you do not have particular needs, where POJO field name corresponds to the label of the JSON value. But 'data/category/item' cannot be a valid Java identifier. So I chose to parse to a Map.
A second way could be to replace in JSON string your "data/category/item" with a valid Java identifier, "data_category_item" for example or, if you can change JSON origin, do the same at the source.
Related
I've a JSON:
{
"payment_intent": {
"amount": "Amount",
"currency_code": "840",
"invoice_number": "pay-automation-invoice-no-01",
"payment_intent_id": "pay-automation-return-intent-id-01",
"intent_reference_id": "pay-automation-intent-reference-id-01"
},
"payment_refundable_intents": {
"transactions": {
"sales": "pay-automation-sales"
}
}
}
Now, when I tried to replace string "pay-automation-sales" with JSONArray using
payloadJson = payloadJson.replaceAll("pay-automation-sales", salesString);
salesString is
[{"amount":"200.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893275","status":"Approved"},{"amount":"800.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893282","status":"Approved"}]
Here, payloadJson is of type String. The replaceAll works fine but actually I want to pass "sales" as an array of object in JSON. But it is getting passed like this and it's not a valid JSON format. Double quotes in value of sales key in JSON causes an issue I think.
"sales": "[{"amount":"200.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893275","status":"Approved"},{"amount":"800.0","payment_intent_id":"29518150","tender_type":"cash","reference_id":"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466","intent_reference_id":"db79893a-9fe0-4391-91f8-fbc7945ce446","id":"000000893282","status":"Approved"}]"
How do I replace string in JSON with valid JSON array of objects?
Since you're working with String objects here and not some form of JSON object model, when you did
payloadJson = payloadJson.replaceAll("pay-automation-sales", salesString);
it found the string
pay-automation-sales
within payloadJson and replaced it verbatin with the contents of salesString. Notice that you did NOT tell it to include the quotes in the original string in the part being replaced.
It should be
payloadJson = payloadJson.replaceAll("\"pay-automation-sales\"", salesString);
You would probably be better off using a real JSON library that understands JSON syntax and can manipulate the JSON as an in-memory document model.
Using Java String
public class StringDemo {
static final String originalJson = " {\n"
+ " \"payment_intent\": {\n"
+ " \"amount\": \"Amount\",\n"
+ " \"currency_code\": \"840\",\n"
+ " \"invoice_number\": \"pay-automation-invoice-no-01\",\n"
+ " \"payment_intent_id\": \"pay-automation-return-intent-id-01\",\n"
+ " \"intent_reference_id\": \"pay-automation-intent-reference-id-01\"\n"
+ " },\n"
+ " \"payment_refundable_intents\": {\n"
+ " \"transactions\": {\n"
+ " \"sales\": \"pay-automation-sales\"\n"
+ " }\n"
+ " }\n"
+ "}";
static final String originalArray = "[{\"amount\":\"200.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893275\",\"status\":\"Approved\"},{\"amount\":\"800.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893282\",\"status\":\"Approved\"}]";
public static void main(String[] args) {
String editedJson = originalJson.replaceAll("\"pay-automation-sales\"", originalArray);
System.out.println(editedJson);;
}
}
Using Jackson
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.*;
public class JacksonDemo {
static final String originalJson = " {\n"
+ " \"payment_intent\": {\n"
+ " \"amount\": \"Amount\",\n"
+ " \"currency_code\": \"840\",\n"
+ " \"invoice_number\": \"pay-automation-invoice-no-01\",\n"
+ " \"payment_intent_id\": \"pay-automation-return-intent-id-01\",\n"
+ " \"intent_reference_id\": \"pay-automation-intent-reference-id-01\"\n"
+ " },\n"
+ " \"payment_refundable_intents\": {\n"
+ " \"transactions\": {\n"
+ " \"sales\": \"pay-automation-sales\"\n"
+ " }\n"
+ " }\n"
+ "}";
static final String originalArray = "[{\"amount\":\"200.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-6c88-66db\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893275\",\"status\":\"Approved\"},{\"amount\":\"800.0\",\"payment_intent_id\":\"29518150\",\"tender_type\":\"cash\",\"reference_id\":\"db79893a-9fe0-4391-91f8-fbc-cash-1d12-8466\",\"intent_reference_id\":\"db79893a-9fe0-4391-91f8-fbc7945ce446\",\"id\":\"000000893282\",\"status\":\"Approved\"}]";
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(originalJson);
JsonNode array = mapper.readTree(originalArray);
ObjectNode transactions = (ObjectNode) root.findValue("transactions");
transactions.set("sales", array);
String editedJson = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(root);
System.out.println(editedJson);;
}
}
I have a list of json records, for instance:
[{“age”:27,”lastname”:”Robert “,”firstName”:”Rob”,”company”:”abc”},
{“age”:27,”lastname”:”Ashok “,”firstName”:”Bob”,”company”:”def”},
{“age”:27,”lastname”:”murali“,”firstName”:”Got”,”company”,”Ghori”}]
Write a method which takes lastName as parameter and based on that input I need to get only that particular record out and get it displayed
Your probleme is not well explained, you can try this solution (after correcting your string to be a real json content)
Using ObjectMapper you can read your string to transform it to an ArrayNode
public static void main(String[] args) throws IOException {
String json= "[\n" +
" {\n" +
" \"age\":27,\n" +
" \"lastname\":\"Robert \",\n" +
" \"firstName\":\"Rob\",\n" +
" \"company\":\"abc\"\n" +
" },\n" +
" {\n" +
" \"age\":27,\n" +
" \"lastname\":\"Ashok \",\n" +
" \"firstName\":\"Bob\",\n" +
" \"company\":\"def\"\n" +
" },\n" +
" {\n" +
" \"age\":27,\n" +
" \"lastname\":\"murali\",\n" +
" \"firstName\":\"Got\",\n" +
" \"company\":\"\"\n" +
" }\n" +
"]";
// example with murali
getLine(json, "murali");
}
private static String getLine(String json, String lastName) throws IOException {
ArrayNode rootNode = (ArrayNode) new ObjectMapper().readTree(json);
for(JsonNode jsonNode : rootNode) {
ObjectNode node = (ObjectNode)jsonNode;
String lastNameValue = node.get("lastname").textValue();
if(lastName.equals(lastNameValue)){
return jsonNode.toString();
}
}
return null;
}
the result for this example is :
{"age":27,"lastname":"murali","firstName":"Got","company":""}
i know how to parse Json in android. but i can't seem to wrap my head around parsing JSONC from Youtube using GSON. i just need to parse the title of the video. Thanks here is the url
http://gdata.youtube.com/feeds/api/videos/iS1g8G_njx8?v=2&alt=jsonc
The following code works to parse the given response with Gson
public class ExampleParser {
public static final String JSONC =
"{\"apiVersion\":\"2.1\","
+ " \"data\":{"
+ " \"id\":\"iS1g8G_njx8\","
+ " \"uploaded\":\"2014-05-30T20:00:01.000Z\","
+ " \"updated\":\"2014-11-26T14:14:11.000Z\","
+ " \"uploader\":\"arianagrandevevo\","
+ " \"category\":\"Music\","
+ " \"title\":\"Ariana Grande - Problem ft. Iggy Azalea\","
+ " \"description\":\"Ariana Grande ft. Iggy Azalea - Problem\nBuy now! http://smarturl.it/ArianaMyEvrythnDlxiT?IQid=vevo.cta.problem\nGoogle Play: http://goo.gl/n7rey5\n\nPre-order My Everything and get access to the iHeartRadio Concert video stream where Ariana performs songs from her new album FOR THE FIRST TIME!\nhttp://myplay.me/19ys\","
+ " \"thumbnail\":{"
+ " \"sqDefault\":\"http://i.ytimg.com/vi/iS1g8G_njx8/default.jpg\","
+ " \"hqDefault\":\"http://i.ytimg.com/vi/iS1g8G_njx8/hqdefault.jpg\"},"
+ " \"player\":{"
+ " \"default\":\"http://www.youtube.com/watch?v=iS1g8G_njx8&feature=youtube_gdata_player\"},"
+ " \"content\":{"
+ " \"5\":\"http://www.youtube.com/v/iS1g8G_njx8?version=3&f=videos&app=youtube_gdata\"},"
+ " \"duration\":208,"
+ " \"aspectRatio\":\"widescreen\","
+ " \"rating\":4.731269,"
+ " \"likeCount\":\"1527921\","
+ " \"ratingCount\":1637964,"
+ " \"viewCount\":307368910,"
+ " \"favoriteCount\":0,"
+ " \"commentCount\":156682,"
+ " \"status\":{"
+ " \"value\":\"restricted\","
+ " \"reason\":\"limitedSyndication\"},"
+ " \"restrictions\":["
+ " {\"type\":\"country\","
+ " \"relationship\":\"deny\","
+ " \"countries\":\"DE\"}],"
+ " \"accessControl\":{"
+ " \"comment\":\"allowed\","
+ " \"commentVote\":\"allowed\","
+ " \"videoRespond\":\"moderated\","
+ " \"rate\":\"allowed\","
+ " \"embed\":\"allowed\","
+ " \"list\":\"allowed\","
+ " \"autoPlay\":\"allowed\","
+ " \"syndicate\":\"allowed\"}}}";
public static void main(String[] args) {
Gson gson = new GsonBuilder()
// Add your date deserializer
.create();
YoutubeResponse response = gson.fromJson(JSONC, YoutubeResponse.class);
System.out.println(response);
}
public static class YoutubeResponse {
Double apiVersion;
Data data;
}
public static class Data {
String id;
String uploaded; // TODO should be a date
String updated; // TODO should be a date
String uploader;
String category;
String title;
String description;
Thumbnail thumbnail;
Player player;
Integer duration;
String aspectRatio;
Double rating;
Integer likeCount;
Integer ratingCount;
Integer viewCount;
Integer favoriteCount;
Integer commentCount;
Status status;
List<Restriction> restrictions;
}
public static class Thumbnail {
String sqDefault;
String hqDefault;
}
public static class Player {
#SerializedName("default")
String defaultt; // default is a reserved java keyword
}
public static class Status {
String value;
String reason;
}
public static class Restriction {
String type;
String relationship;
String countries;
}
public static class AccessControl {
String comment;
String commentVote;
String videoRespond;
String rate;
String embed;
String list;
String autoPlay;
String syndicate;
}
}
Hey I was wondering if it is possible to edit an existing json I know the location off.
So lets say that the location is C:\Something.json
then how do I edit it ??.
Thanks
If you want to edit complex JSON structure I would recommend using GSON library. You can then perform the following steps :
Gson gson = new Gson();
String yourfilecontents; //read contents from File
1) read JSON File and convert it into an object structure.
YourObject obj = gson.fromJson(yourfilecontents, YourObject.class);
2) Modify the object as per your requirement.
obj.field1(newValue);
3) Convert the object into JSON
String newJson = gson.toJson(obj);
4) Write the JSON (newJson) back to the file
Your question is very unprecise, but here are some tips, you can:
Open the JSON file with your favourite notepad
Use java.io.File API to open the file
Use some JSON Java API
To transform/filter JSON, especially in case of large files, it isn't a good idea to load the whole file to memory and use object mapping at all. Prefer stream oriented parsing and generating. For example, both Gson and Jackson support such technique. To illustrate the idea I use small, fast and GC-free library https://github.com/anatolygudkov/green-jelly. I've taken a question Loop and edit json file in java The code renames all property names "div" to "b-div"
import org.green.jelly.*;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
public class Transformation {
public static void main(final String[] args) throws IOException {
final String inputContent = "{ \n" +
" \"html\":{ \n" +
" \"child\":[ \n" +
" { \n" +
" \"head\":{ \n" +
"\n" +
" }\n" +
" },\n" +
" { \n" +
" \"body\":{ \n" +
" \"child\":[ \n" +
" { \n" +
" \"div\":{ \n" +
" \"id\":\"intk\",\n" +
" \"class\":\"akagen-row b-table\",\n" +
" \"child\":[ \n" +
" { \n" +
" \"div\":{ \n" +
" \"id\":\"aaaaa\",\n" +
" \"title\":\"bbbbbbb\",\n" +
" \"class\":\"akagen-cell\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" { \n" +
" \"div\":{ \n" +
" \"class\":\"akagen-row b-table\",\n" +
" \"child\":[ \n" +
" { \n" +
" \"div\":{ \n" +
" \"class\":\"akagen-cell\"\n" +
" }\n" +
" },\n" +
" { \n" +
" \"div\":{ \n" +
" \"class\":\"akagen-cell\"\n" +
" }\n" +
" },\n" +
" { \n" +
" \"div\":{ \n" +
" \"class\":\"akagen-cell\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
"}";
final Reader input = new StringReader(inputContent); // replace by FileReader
final Writer output = new StringWriter(); // replace by FileWriter
final JsonGenerator generator = new JsonGenerator();
generator.setOutput(new AppendableWriter<>(output));
final JsonParser parser = new JsonParser().setListener(new JsonParserListener() {
#Override
public void onJsonStarted() {
generator.reset();
}
#Override
public void onError(final String error, final int position) {
}
#Override
public void onJsonEnded() {
generator.eoj();
}
#Override
public boolean onObjectStarted() {
generator.startObject();
return true;
}
#Override
public boolean onObjectMember(final CharSequence name) {
if ("div".contentEquals(name)) {
generator.objectMember("b-div");
} else {
generator.objectMember(name);
}
return true;
}
#Override
public boolean onObjectEnded() {
generator.endObject();
return true;
}
#Override
public boolean onArrayStarted() {
generator.startArray();
return true;
}
#Override
public boolean onArrayEnded() {
generator.startArray();
return true;
}
#Override
public boolean onStringValue(final CharSequence data) {
generator.stringValue(data);
return true;
}
#Override
public boolean onNumberValue(final JsonNumber number) {
generator.numberValue(number);
return false;
}
#Override
public boolean onTrueValue() {
generator.trueValue();
return true;
}
#Override
public boolean onFalseValue() {
generator.falseValue();
return true;
}
#Override
public boolean onNullValue() {
generator.nullValue();
return true;
}
});
final CharArrayCharSequence buffer = new CharArrayCharSequence(1024 * 8);
int length;
while ((length = input.read(buffer.getChars())) != -1) {
buffer.setLength(length);
parser.parse(buffer);
}
parser.eoj();
System.out.println(output.toString());
}
}
Performance of such lightweight technique of transformation is almost the highest in terms of both CPU utilization and memory footprint you can reach in Java (with no tricks like SIMD over JNI).
The json looks like this :
"hour_totals": {
"382423": {
"imp": 126,
"clk": 1,
"spend": "$0.03",
"conv": 0,
"cpm": "$0.22",
"cpc": "$0.03",
"ctr": "0.79%",
"cpa": "$Inf"
},
"382424": {
"imp": 209,
"clk": 1,
"spend": "$0.05",
"conv": 0,
"cpm": "$0.23",
"cpc": "$0.05",
"ctr": "0.48%",
"cpa": "$Inf"
}}
I read more than 20 answers, but unable to find how to deserialize such a structure, please help on what would the class look like since the hour is not a fixed string.
To parse this JSON with Gson you need two steps.
Define this classes:
public class Total {
Map<String, HourData> hour_totals;
#Override
public String toString() {
return "Total [hour_totals=" + hour_totals + "]";
}
}
where HourData is
public class HourData {
Integer imp;
Integer clk;
String spend;
Integer conv;
String cpm;
String cpc;
String cpa;
#Override
public String toString() {
return "HourData [imp=" + imp + ", clk=" + clk + ", spend=" + spend
+ ", conv=" + conv + ", cpm=" + cpm + ", cpc=" + cpc + ", cpa="
+ cpa + "]";
}
}
Hack a bit your "Json string" since it's not a valid Json (see more details below). You just need to add braces like this code:
public class Q19201300 {
public static void main(String[] args) {
String json = "\"hour_totals\": { "
+ " \"382423\": { "
+ " \"imp\": 126, "
+ " \"clk\": 1, "
+ " \"spend\": \"$0.03\", "
+ " \"conv\": 0, "
+ " \"cpm\": \"$0.22\", "
+ " \"cpc\": \"$0.03\", "
+ " \"ctr\": \"0.79%\", "
+ " \"cpa\": \"$Inf\" "
+ "}, "
+ "\"382424\": { "
+ " \"imp\": 209, "
+ " \"clk\": 1, "
+ " \"spend\": \"$0.05\", "
+ " \"conv\": 0, "
+ " \"cpm\": \"$0.23\", "
+ " \"cpc\": \"$0.05\", "
+ " \"ctr\": \"0.48%\", "
+ " \"cpa\": \"$Inf\" "
+ "}} ";
Total t = new Gson().fromJson("{" + json + "}", Total.class);
System.out.println(t);
}
}
This will give you:
Total [hour_totals={382423=HourData [imp=126, clk=1, spend=$0.03,
conv=0, cpm=$0.22, cpc=$0.03, cpa=$Inf], 382424=HourData [imp=209,
clk=1, spend=$0.05, conv=0, cpm=$0.23, cpc=$0.05, cpa=$Inf]}]
About your string. From JSON official grammar (http://www.ietf.org/rfc/rfc4627.txt):
JSON Grammar
A JSON text is a sequence of tokens. The set of tokens includes
six structural characters, strings, numbers, and three literal
names.
A JSON text is a serialized object or array.