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);;
}
}
Related
{
"userName": "test"
"customer": {
"mode": "BANK",
"modeDetails": {
"accountNo": "12345678901001",
"walletId": "11324354#paypal"
}
}
}
I am using jsonpath to select accountNo if mode="BANK" or else if mode=WALLET then walletId should be selected. I tried expression $.customer.modeDetails[$.customer.mode=='BANK'].accountNo but it doesn't work. Please help me on this.
public static void main(String[] args) {
String jsonString = "{\r\n" +
" \"userName\": \"test\",\r\n" +
" \"customer\": {\r\n" +
" \"mode\": \"BANK\",\r\n" +
" \"modeDetails\": {\r\n" +
" \"accountNo\": \"12345678901001\",\r\n" +
" \"walletId\": \"11324354#paypal\"\r\n" +
" }\r\n" +
" }\r\n" +
"}";
DocumentContext docCtx = JsonPath.parse(jsonString);
JsonPath jsonPath = JsonPath.compile("$..[?(#.customer.mode==\"BANK\")].customer.modeDetails.accountNo");
List<String> accounts = docCtx.read(jsonPath);
System.out.println(accounts);
}
result
["12345678901001"]
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":""}
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).
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.
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.