I use Java Spring in my project.
I need to parse JSON into java class.
Example of the JSON:
[
{
"Id":"aaa1"
"Data1":"test11"
"Data2":"test12"
"url1": "https://...someimg11.png",
"url2": "https://...someimg12.png",
},
{
"Id":"aaa2"
"Data1":"test21"
"Data2":"test22"
"url1": "https://...someimg21.png",
"url2": "https://...someimg22.png",
},
{
"Id":"aaa3"
"data1":"test31"
"data2":"test32"
"url1": "https://...someimg31.png",
"url2": "https://...someimg32.png",
}
]
And here the Java class that json above should be parsed to:
class Info{
#JsonProperty("Id")
public String id;
#JsonProperty("Data1")
public String data1;
#JsonProperty("Data2")
public String data2;
//parse to here url1 and url2 properties from json doc
public List<String> urls;
}
As you can see I have no issues to parse properties, except the last properties in JSON url1 and url2,
the properties of JSON file url1 and url2 should be parsed into URLs property of type List.
My question is, how can I parse the two properties of JSON inside the single property in the class of type list of strings?
UPDATE
I can use #JsonAnySetter annotation as suggested on one of the answers, but in this case, I will need to initialize the urls property, otherwise, I get this error on parsing:
Cannot invoke "java.util.List.add(Object)" because "this.urls" is null
In case if I use #JsonAnySetter annotation how can I init urls property?
You can do it using #JsonAnySetter annotation and I don't if there is any easier way of using patterns or wildcards
class Info{
#JsonProperty("Id")
public String id;
#JsonProperty("Data1")
public String data1;
#JsonProperty("Data2")
public String data2;
//parse to here url1 and url2 properties from json doc
public List<String> urls = new ArrayList<>();
#JsonAnySetter
public void add(String key, String value) {
if(key.equals("url1") || key.equals("url2")) {
urls.add(value);
}
}
}
Related
I have a Document request that I need to send to a REST service endpoint:
#Data // lombok
public class Document {
private String name;
private String location;
private String content; // a base64 encoded byte array
}
I have a utility class that I can use to log the entire JSON object in the log file. So in case an exception is thrown at runtime, the code will log at the ERROR level the request that causes the exception, something like this:
{
"name": "file1.pdf",
"location" : "/root/folder/",
"content" : "JVBERi0xLjQKJdP0zOEKJxxxxxxxxxxxxxxxxxxxx"
}
The problem is in the "content" field. If the file is very large, the "content" field will fill up the log file very quickly when an exception happens at runtime. So how do I make the "content" field not to be printed in the log file? I thought about using #JsonIgnore, but will it make the "content" field to be ignored when the request is passed to the endpoint? I am not using Gson.
You can use JacksonMixin:
#Data
public class Document {
private String name;
private String location;
private String content;
}
public static abstract class ContentIgnoreMixin {
#JsonIgnore
private String content;
}
// same as ContentIgnoreMixin, but interface using getter
public interface class ContentIgnoreMixin2 {
#JsonIgnore
String getContent();
}
and later:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(Document.class, ContentIgnoreMixin.class); // or ContentIgnoreMixin2 - no difference
String jsonWithoutContent = mapper.writeValueAsString(objectWithContent);
I have multiple Java bean classes that are associated to each other (JSON Array + JSON Object) since they have a nested structure.
There are about 10 classes. Is there a way to collectively convert these classes or at-least one by one?
I had created these classes out of a JSON data which I don't have access to right now.
So, now, what I'm looking forward is to create a dummy JSON out of those classes.
Using GSON, I tried converting one of these Bean classes however, I got an empty result. Here is one of the beans called Attachment.java.
Attachment.java
package mypackagename;
import java.io.Serializable;
public class Attachment implements Serializable{
private Payload payload;
private String type;
public Payload getPayload() {
return payload;
}
public void setPayload(Payload payload) {
this.payload = payload;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
Implementation
Gson gson = new Gson();
Attachment attachment = new Attachment();
String json = gson.toJson(attachment);
Sure you got an empty result. Because your JSON object is empty. You should add data to your object and test it again as below:
Attachment attachment = new Attachment(new Payload("Test Payload"), "Test attachment");
String json = new Gson().toJson(attachment);
Log.e("Test", "Json: " + json); // result: Json: {"payload":{"test":"Test Payload"},"type":"Test attachment"}
To avoid empty object, you have to set a default value to your payload and type becaus Gson will ignore any null value.
This section of the Gson User Guide: https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
The fourth bullet point explains how null fields are handled.
Link.java
#JsonInclude(JsonInclude.Include.NON_NULL)
#JsonPropertyOrder({ "rel", "href","method" })
public class Link {
#JsonProperty("rel")
private String rel;
#JsonProperty("href")
private String href;
#JsonProperty("method")
private Method method;
#Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
}
}
I have this third party class with fasterxml jackson annotations. I can convert a given object into a string using the specified toString() method. Is there any way of using that String to get an object of type Link?
Note: The object itself has an embedded object (which has several more embedded objects) and these too needs to be converted into a Method object from the string itself.
Just putting the comment by #pvpkiran in an answer.
Use ObjectMapper class from com.fasterxml.jackson.databind
ObjectMapper objectMapper = new ObjectMapper();
Converting from Object to String:
String jsonString = objectMapper.writeValueAsString(link);
Converting from String to Object:
Link link = objectMapper.readValue(jsonString, type)
My json looks like this :
{
"bid": "181.57",
"ask": "181.58",
"volume": {
"item1": "543.21",
"item2": "123.45",
"timestamp": 1487903100000
},
"last": "181.58"
}
I'm trying to use spring restTemplate to read it into a pojo. My current pojo is this :-
import com.fasterxml.jackson.annotation.JsonProperty;
public class DataModel {
private String last;
private Volume volume;
private String ask;
private String bid;
// Getter and setters
}
class Volume
{
private String timestamp;
#JsonProperty
private String item1;
#JsonProperty
private String item2;
// Gettersand setters
}
The problem is that "item1" and "item2" int the json can change to "item5" and "item6" depending on which entity I am querying for. I get null values if my variables are named item1 and item2. How can I keep generic names for the variables item1 and item2 and still be able to read the values correctly in the generic variables? Is there any annotation that will help here?
I believe this is what you are looking for from a Baeldung tutorial:
3.3. #JsonAnySetter
#JsonAnySetter allows you the flexibility of using a Map as standard properties. On de-serialization, the properties from JSON will simply be added to the map.
Let’s see how this works – we’ll use #JsonAnySetter to deserialize the entity ExtendableBean:
public class ExtendableBean {
public String name;
private Map<String, String> properties;
#JsonAnySetter
public void add(String key, String value) {
properties.put(key, value);
}
}
This is the JSON we need to deserialize:
{
"name":"My bean",
"attr2":"val2",
"attr1":"val1"
}
And here’s how this all ties in together:
#Test
public void whenDeserializingUsingJsonAnySetter_thenCorrect()
throws IOException {
String json
= "{\"name\":\"My bean\",\"attr2\":\"val2\",\"attr1\":\"val1\"}";
ExtendableBean bean = new ObjectMapper()
.readerFor(ExtendableBean.class)
.readValue(json);
assertEquals("My bean", bean.name);
assertEquals("val2", bean.getProperties().get("attr2"));
}
In your case, you would simply query the map for the String values you expect for whichever query you are making.
This is my JSON from URL
https://api.myjson.com/bins/142jr
[
{
"serviceNo":"SR0000000001",
"serDate":"17",
"serMonth":"DEC",
"serYear":"2015",
"serTime":"02.30 AM",
"serApartmentName":"Galaxy Apartments"
},
{
"serviceNo":"SR0000000002",
"serDate":"19",
"serMonth":"JUN",
"serYear":"2016",
"serTime":"03.30 AM",
"serApartmentName":"The Great Apartments"
}
]
I have one ListView I want populate details from online JSON,above i given a link and sample json anybody given sample jackson code in java
Thanks for advance,
Rajesh Rajendiran
To use jackson you need to create a model class:
[
{
"serviceNo":"SR0000000001",
"serDate":"17",
"serMonth":"DEC",
"serYear":"2015",
"serTime":"02.30 AM",
"serApartmentName":"Galaxy Apartments"
},
{
"serviceNo":"SR0000000002",
"serDate":"19",
"serMonth":"JUN",
"serYear":"2016",
"serTime":"03.30 AM",
"serApartmentName":"The Great Apartments"
}
]
For the above the json the model class would be:
public class SomeClass {
private String serviceNo;
private String serDate;
private String serMonth;
private String serYear;
private String serTime;
private String serApartmentName;
#JsonProperty("serviceNo") //to bind it to serviceNo attribute of the json string
public String getServiceNo() {
return serviceNo;
}
public void setServiceNo(String sNo) { //#JsonProperty need not be specified again
serviceNo = sNo;
}
//create getter setters like above for all the properties.
//if you want to avoid a key-value from getting parsed use #JsonIgnore annotation
}
Now whenever you have the above json as string stored in a variable say jsonString use the following code to parse it:
ObjectMapper mapper = new ObjectMapper(); // create once, reuse
ArrayList<SomeClass> results = mapper.readValue(jsonString,
new TypeReference<ArrayList<ResultValue>>() { } );
results should now contain two SomeClass objects having the above json parsed as respective objects.
PS: Its been a long time since I have used Jackson for parsing so this code might need some improvements.
If you are getting this as http response then I would suggest to use spring rest template for android.
It has support for Message Converters. That way the onus of marshaling and unmarshalling.
[Update]
Here is a blog for the same :http://www.journaldev.com/2552/spring-restful-web-service-example-with-json-jackson-and-client-program
Refer Docs for more details:
http://docs.spring.io/spring-android/docs/current/reference/html/rest-template.html