I have JSON which has colon (:) in property. Now I am wondering how to map this property name with java class property.
I tried #JsonProperty("viacom:VideoDuration") but it is not working.
Here is the sample json
{
"shortTitle": "Teen Wolf",
"viacom:VideoDuration": "20h:30m",
"viacom:metadataLanguage": "en",
"viacom:contentType": "franchise",
"viacom:urlKey": "http://urlkey.com",
"viacom:vmid":"cee71f4a-ec7d-4ccd-a10d-9bf6b7506d352",
"viacom:originLanguage":"en"
}
Note : I do not have option to rename the json property name to something else.
Probably it's a problem of a library you are using or its version.
I've just created a simple test and it has ran properly.
Test class:
public class TestClass {
private String valueStr;
#JsonProperty("test:prop")
private String testProp;
public String getValueStr() {
return valueStr;
}
public void setValueStr(String valueStr) {
this.valueStr = valueStr;
}
public String getTestProp() {
return testProp;
}
public void setTestProp(String testProp) {
this.testProp = testProp;
}
}
And test:
#Test
public void test()
throws JsonParseException, JsonMappingException, IOException {
String test = "{\r\n" +
" \"test:prop\": \"Teen Wolf\",\r\n" +
" \"valueS\": \"franchise\"\r\n" +
"}";
ObjectMapper mapper = new ObjectMapper();
TestClass data = mapper.readValue(test, TestClass.class);
Assert.assertTrue("expected Teen Wolf, actual=" + data.getTestProp(),
Objects.equals("Teen Wolf", data.getTestProp()));
}
I've used com.fasterxml.jackson.databind.ObjectMapper from com\fasterxml\jackson\core\jackson-databind\2.8.8\jackson-databind-2.8.8.jar
By the way which type the "viacom:VideoDuration" property is in the java class? I mean what if the problem not in the property name but in the value? It also has a colon and you are trying to deserialize it in the wrong way?
Related
Diferent results occur when mapping an object containing a field starting with "x" to org.json.JSONObject and com.fasterxml.jackson.core.ObjectMapper:
JSONObject
{"one":"One"}
ObjectMapper
{"one":"One","xOne":"xOne"}
Why does the JSONObject not include the "xOne" field?
public class Test {
private String one;
private String xOne;
public String getOne() {
return one;
}
public void setOne(String one) {
this.one = one;
}
public String getxOne() {
return xOne;
}
public void setxOne(String xOne) {
this.xOne = xOne;
}
#Override
public String toString() {
return "Test [one=" + one + ", xOne=" + xOne + "]";
}
}
public class PojoToJson {
public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
Test test = new Test();
test.setOne("One");
test.setxOne("xOne");
JSONObject json = new JSONObject(test);
System.out.println("JSONObject o/p: " + json);
ObjectMapper mapper = new ObjectMapper();
String mapperString = mapper.writeValueAsString(test);
System.out.println("ObjectMapper o/p: " + mapperString);
}
}
Here is my output difference using JSONObject and ObjectMapper:
According to the Jackson reference documentation:
In absence of a registered custom strategy, the default Java property
naming strategy is used, which leaves field names as is, and removes
set/get/is prefix from methods (as well as lower-cases initial
sequence of capitalized characters).
As I understand it, this means that Jackson will understand that getxOne() actually correspond to xOne property.
org.json.JSONObject may have a different naming strategy (which I was not able to find anywhere) and hence the reason for getxOne() to work with Jackson's ObjectMapper but not with org.json.JSONObject.
I have a json payload with:
"host_names": [
"www.host1.com",
"www.host2.com"
]
How can I deserialize this as a csv using Jackson - e.g.:
"www.host1.com,www.host2.com"
Previously I was deserializing this as a String[] but I can't persist that with hibernate, so now I'm trying to deserialize it as a csv.
EDIT:
I want to use annotations to turn the json array into a string, where each element of the array is separated by a comma. Perhaps something like #JsonRawValue. The goal is to then persist the value to a data via hibernate.
public static void main(String[] args) {
String jsonStr = "{\"host_names\": [\r\n" +
" \"www.host1.com\",\r\n" +
" \"www.host2.com\"\r\n" +
"]}";
JSONObject jsonObject = new JSONObject(jsonStr);
JSONArray hostNames = jsonObject.getJSONArray("host_names");
String result = "";
for(int i=0;i<hostNames.length(); i++) {
if(!result.isEmpty())
result = result+",\""+hostNames.getString(i)+"\"";
else
result = "\""+hostNames.getString(i)+"\"";
}
System.out.println(result);
}
result
"www.host1.com","www.host2.com"
Other approach based on annotation
Create a class
class Server{
#JsonProperty(value = "host_names")
private List<String> hostNames;
public List<String> getHostNames() {
return hostNames;
}
public void setHostNames(List<String> hostNames) {
this.hostNames = hostNames;
}
}
Now use com.fasterxml.jackson.databind.ObjectMapper to parse the JSON into this class
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
String jsonStr = "{\"host_names\": [\r\n" +
" \"www.host1.com\",\r\n" +
" \"www.host2.com\"\r\n" +
"]}";
ObjectMapper mapper = new ObjectMapper();
Server server = mapper.readValue(jsonStr, Server.class);
System.out.println(server.getHostNames());
}
output
[www.host1.com, www.host2.com]
You can slightly modify your setter / getter for host_names property as
Bean Class
public class Server {
#JsonProperty("host_names")
private List<String> hostNames;
#JsonGetter("host_names")
public String getHostNames() {
return String.join(",", hostNames);
}
#JsonSetter("host_names")
public void setHostNames(List<String> hostNames) {
this.hostNames = hostNames;
}
}
Main Method
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Server server = mapper.readValue("{\"host_names\":[\"www.host1.com\",\"www.host2.com\"]}", Server.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(server);
System.out.println(json);
}
Output
{
"host_names" : "www.host1.com,www.host2.com"
}
This way you can serialize as comma separated string, and array of string while deserializing.
Another Solution using #JsonValue Annotation.
Define your bean class as:
public class Server {
#JsonProperty("host_names")
private List<String> hostNames;
#JsonValue
public String hostNames() {
return String.join(",", hostNames);
}
public List<String> getHostNames() {
return hostNames;
}
public void setHostNames(List<String> hostNames) {
this.hostNames = hostNames;
}
}
Main Method
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Server server = mapper.readValue("{\"host_names\":[\"www.host1.com\",\"www.host2.com\"]}", Server.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(server);
System.out.println(json);
}
Output
"www.host1.com,www.host2.com"
This method will only be useful if your bean class has no other fields to serialize.
Having a JSON with a property like this which i try to deserialze with jackson:
{ "$fooid" : "yfdfjjhkjhkljhd768622323jjj" }
Problem here is, i'm not able to read the key "$fooid".
I tried to annotate the property with
#JsonAlias("$fooid")
private String fooid;
also as
#JsonProperty("$fooid")
private String fooid;
Both variants won't work, the property fooid is always null.
How to deserialize it in Java? Any hints?
I am not sure how are you doing It, but It is working for me on version 2.0.0 doing this.
public class JSonAliasWithSpecialCharacters {
public static void main(String[] args) throws IOException {
String json="{ \"$fooid\" : \"yfdfjjhkjhkljhd768622323jjj\" }";
ObjectMapper mapper = new ObjectMapper();
JsonFooid fooid = mapper.readValue(json, JsonFooid.class);
System.out.println("read the foodid:"+fooid.getFooid());
}
}
public class JsonFooid {
#JsonProperty("$fooid")
private String fooid;
public String getFooid() {
return fooid;
}
public void setFooid(String fooid) {
this.fooid = fooid;
}
}
I have JSON object and I don't want to parse some of nested objects. Instead I want them as String (I have my reasons). Is there an easy way to do it?
I've tried to implement custom Deserializer but I found it complicated in different ways (I don't want to concatenate tokens I just need whole object. It also doesn't consider ':' as token so it need special handling) or maybe I'm missing smth.
Also putting quotes in json is not an option. I need that json the way it is.
JSON example:
{
"lastName":"Bitman",
"jsonObjectIDontWantToParse":{
"somefield":1234
}
}
Java object I want to parse json to.
public class Jack {
public String lastName;
public String jsonObjectIDontWantToParse;
#Override
public String toString() {
return "lastName=" + lastName + ", jsonObjectIDontWantToParse=" + jsonObjectIDontWantToParse;
}
}
Here's my main class
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
final String jackString = "{\"lastName\":\"Bitman\",\"jsonObjectIDontWantToParse\":{\"somefield\":1234}}";
Jack user = mapper.readValue(jackString, Jack.class);
System.out.println(user);
}
I expect output to be like this
lastName=Bitman, jsonObjectIDontWantToParse={"somefield":1234}
Updated: So basically this is example what I'm looking for (except There are no such method). I want to skip any parsing for that node...
public class LeaveAsStringDeserializer extends JsonDeserializer<String> {
#Override
public String deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
return jp.getWholeObject().toString();
}
}
I think, that you should use JsonNode class as a type of jsonObjectIDontWantToParseproperty:
class Jack {
private String lastName;
private JsonNode jsonObjectIDontWantToParse;
// getters, setters, toString, other
public String getJsonObjectIDontWantToParseAsString() {
return jsonObjectIDontWantToParse.toString();
}
}
You can add one additional method getJsonObjectIDontWantToParseAsStringif you want to get Stringrepresentation.
Example usage:
ObjectMapper mapper = new ObjectMapper();
Jack jack = mapper.readValue(json, Jack.class);
System.out.println(jack);
System.out.println(jack.getJsonObjectIDontWantToParseAsString());
Above program prints:
lastName=Bitman, jsonObjectIDontWantToParse={"somefield":1234}
{"somefield":1234}
To get to this:
lastName=Bitman, jsonObjectIDontWantToParse={"somefield":1234}
You just need to escape the String representation of jsonObjectIDontWantToParse. That means change it read:
jsonObjectIDontWantToParse: "{ \"somefield\": 1234 }"
I have a JSON:
{"evaluationPart": {
"generatedId": "48D5181DB8704F8AB5FC998964AD9075",
"evaluationQuestionPartOption": {
"generatedId": "48D5181DB8704F8AB5FC998964AD9075"
}
}}
I've created java classes for it to represent it:
The root class:
#JsonIgnoreProperties(value = {"evaluationPart"})
public class JsonEvaluationPart {
#JsonProperty("generatedId")
private String generatedId;
#JsonProperty("evaluationQuestionPartOption")
private JsonQuestionOption questionOption;
public String getGeneratedId() {
return generatedId;
}
public void setGeneratedId(String generatedId) {
this.generatedId = generatedId;
}
public JsonQuestionOption getQuestionOption() {
return questionOption;
}
public void setQuestionOption(JsonQuestionOption questionOption) {
this.questionOption = questionOption;
}
}
And the JsonQuestionOption class:
public class JsonQuestionOption {
#JsonProperty("generatedId")
private String generatedId;
public String getGeneratedId() {
return generatedId;
}
public void setGeneratedId(String generatedId) {
this.generatedId = generatedId;
}
}
I have written a small JUnit test to check how it goes:
public class JsonReaderTest {
/**
* Logger for this class.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(JsonReaderTest.class);
private ObjectMapper objectMapper;
private static final String JSON = "{\"evaluationPart\": {\n" +
" \"generatedId\": \"48D5181DB8704F8AB5FC998964AD9075\",\n" +
" \"evaluationQuestionPartOption\": {\n" +
" \"generatedId\": \"48D5181DB8704F8AB5FC998964AD9075\"\n" +
" }\n" +
"}}";
#Before
public void setUp()
throws Exception {
LOGGER.debug("Creating the object mapper.");
objectMapper = new ObjectMapper();
LOGGER.debug("Object mapper successfully created. {}", objectMapper);
}
#Test
public void testJsonReader()
throws Exception {
JsonEvaluationPart partType = objectMapper.readValue(JSON, JsonEvaluationPart.class);
assertNotNull(partType);
LOGGER.debug("Part: {}.", partType);
assertEquals(partType.getGeneratedId(), "48D5181DB8704F8AB5FC998964AD9075");
assertEquals(partType.getQuestionOption().getGeneratedId(), "48D5181DB8704F8AB5FC998964AD9075");
}
}
The problem is that when I am reading my JSON like this:
JsonEvaluationPart partType = objectMapper.readValue(JSON, JsonEvaluationPart.class);
All the properties in partType are null. What I am doing wrong here and how to solve this?
According to the documentation JsonIgnoreProperties means:
Annotation that can be used to either suppress serialization of properties
(during serialization), or ignore processing of JSON properties read (during
deserialization).
Just try replacing:
#JsonIgnoreProperties(value = {"evaluationPart"})
with:
#JsonTypeName("evaluationPart")
Your Json Headers is wrong.
use
#JsonTypeName("evaluationPart")
instead of
#JsonIgnoreProperties(value = {"evaluationPart"})