I am working with an exiting API that expects a "Metadata" field as part of its json payload. That "Metadata" field is a json object that is completely free-form. Currently, I need to read this data provided from another source, do some enrichment, then pass it on. I am struggling with how to define this "Metadata" object so that it can be any valid json object. OR, if that field was not provided, an empty json object.
I attempted to use org.json.JSONObject like so.
//meta is the json string read from the db
JSONObject jsonobject = new JSONObject(meta);
message.Metadata = jsonobject;
However, jackson, not unexpectedly, threw a serialization error:
com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.json.JSONObject and no properties discovered...
This is a critical requirement that I'm guessing I am missing some relatively obvious solution to. Any help would be greatly appreciated.
UPDATED FIX
As suggested by #shmosel I just switched the json object to a com.fasterxml.jackson.databind.JsonNode and all works beautifully.
// working code (rough of course)
ObjectMapper mapper = new ObjectMapper();
JsonNode rootNode = null;
try {
rootNode = mapper.readTree(meta);
} catch (IOException e) {
e.printStackTrace();
}
message.Metadata = rootNode;
Related
I have a stable SpringBoot project that runs. I want to add a end point that reads a json file from classpath and passes it through to the response without having to create any Model objects (pass thru).
I have no issues reading the json file into JsonNode or ObjectNode, I'm struggling with where to go next to set the data in my response object.
Added this caveat later, I do need to update the json from a database.
Ok, paired up with a colleague at work and we tried two things, return a string (escapes strings in REST output - returns a big String.) not good. What worked is setting the response object to a and calling mapper.readValue(jsonFeed, Map.class), that returned the JSON in proper object notation.
#Value("${metadata.json.file}") //defined in application.context
private Resource metaJsonFileName;
public String getJsonFromFile(List<UnitUiItem> uiitems){
JsonNode root;
ObjectMapper mapper = new ObjectMapper();
InputStream stream = metaJsonFileName.getInputStream();
root = mapper.readTree(stream);
JsonNode dataNode = root.get("data");
JsonNode optionDataNode = dataNode.get("storelocation");
((ObjectNode)optionDataNode).putArray("units");
for(UnitUiItem item : uiitems){
JsonNode unitNode = ((ObjectNode)optionDataNode).withArray("units").addObject();
((ObjectNode)unitNode).put("code",item.getCode());
((ObjectNode)unitNode).put("displayName",item.getDisplayName());
}
LOGGER.info("buildMetaJson exit");
return root.toString();
}
//calling method
String jsonFeed = getJsonFromFile();
ObjectMapper mapper = new ObjectMapper();
response.setData(mapper.readValue(jsonFeed, Map.class));
I have some code cleanup to do.. any cleaner ways of doing this?
I have the following code to convert an object to Json:
public static Function<Object, Object> WRITE_JSON = (Object val) -> {
try {
return new ObjectMapper().writeValueAsString(val);
} catch (IOException e) {
// log exception
return "";
}
}
This works fine for most cases, but f.e I have an Avro class named AvroData, and a class that saves it:
class SomeData {
private AvroData avroData;
// more fields, getter/setter boilerplate, etc...
}
When I try to serialise the object to Json, this fails when trying to serialize the Avro field.
In reality, I have a bit more data, like Sets and Maps that contain Avro record values, but I think the point stands.
How do you manage to serialise a avro to json, but specifically when it's part of a Non-avro object?
To convert your Object val in JSON with Jackson:
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(val);
I have created an application for converting the HashMap object to String, its working fine, The problem which i am facing is that i want to convert the HashMap string again back to HasMap object, when i tried that by using the following code , I am getting exception as shown below
Unexpected character ('u' (code 117)): was expecting double-quote to start field name
Can anyone please tell me some solution for this
My code is given below
Map<String,Object> map = new HashMap<String,Object>();
map.put("userVisible", true);
map.put("userId", "1256");
ObjectMapper mapper = new ObjectMapper();
try {
map = mapper.readValue(map.toString(), new TypeReference<HashMap<String,Object>>(){});
System.out.println(map.get("userId"));
} catch (Exception e) {
e.printStackTrace();
}
Update 1
As suggested by #chrylis I have used Feature.ALLOW_UNQUOTED_FIELD_NAMES like as shown below, but now i am getting the following exception
Unexpected character ('=' (code 61)): was expecting a colon to separate field name and value
Updated Code
Map<String,Object> map = new HashMap<String,Object>();
map.put("userVisible", true);
map.put("userId", "1256");
ObjectMapper mapper = new ObjectMapper();
mapper.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
try {
map = mapper.readValue(map.toString(), new TypeReference<HashMap<String,Object>>(){});
System.out.println(map.get("userId"));
} catch (Exception e) {
e.printStackTrace();
}
You're getting this error because JSON specifies that you have to put field names in quotation marks, unlike in a regular JavaScript object. You can tell Jackson to permit unquoted field names by configuring the ObjectMapper so:
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
Update
It appears that a more fundamental problem is that you're trying to use Java toString() to convert the map to a String, and a Jackson JSON mapper to convert it back. The two are completely different formats, and if you need to be able to convert the string back into an object, you should probably use the Jackson mapper to turn the map into JSON in the first place.
I am working with Jackson 2 and CXF.
I have done lots of research to find a clean and safe way to get a writer object from the shared object mapper that is given to CXF for un/marshaling JSON. I cannot just use annotation or set the mapper object to ignore null fields when serializing due to some business logic.
The code below seem to be very correct, but the output JSON still include null fields. Please help !!
ObjectWriter writer = this.jacksonMapper.writer().without( SerializationFeature.WRITE_NULL_MAP_VALUES ) ;
if( writer.isEnabled( SerializationFeature.WRITE_NULL_MAP_VALUES ) ) {
System.out.println("Oppa gangname style");
}
String json = null;
try {
json = writer.writeValueAsString( myObject );
System.out.println ( json ) ;
} catch (JsonProcessingException e) {
throw new RuntimeException() ;
}
The if case verify that I have successful disable SerializationFeature.WRITE_NULL_MAP_VALUES.
However, the result is still include null fields.
I'm using an older Jackson version but this works for me:
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
mapper.setSerializationInclusion(Inclusion.NON_NULL);
return mapper.writeValueAsString(input);
The docs say SerializationFeature.WRITE_NULL_MAP_VALUES only applies to generating JSON strings from Map objects.
This question already has answers here:
How to parse JSON in Java
(36 answers)
Closed 7 years ago.
I have searched alot on JSON Parsing in Android, but couldn't quite convinced. Actually got a brief idea but not so clear yet regarding JSON Parsing.
How to implement the JSON Parsing in the Application?
This is a very simple JSON String
{"key1":"value1","key2":"value2"}
In order to get values for it use JSONObject like this :
JSONObject json_obj=new JSONObject(your json string);
String value1=json_obj.getString("key1");
String value2=json_obj.getString("key2");
This is a slightly complex json string
[{"key1":"value1","key2":"value2"},{"key1":"value1","key2":"value2"}]
In order to extract values from this use JSONArray
JSONArray jArray=new JSONArray(your json string);
for(int i=0;i<(jArray.length());i++)
{
JSONObject json_obj=jArray.getJSONObject(i);
String value1=json_obj.getString("key1");
String value2=json_obj.getString("key2");
}
Hope this helps a bit...........
You can also check out Google's GSON library here. The GSON user guide here has some useful examples to help get you started. I've found GSON to be simple and powerful.
See: http://developer.android.com/reference/org/json/package-summary.html
Primarily, you'll be working with JSONArray and JSONObject.
Simple example:
try {
JSONObject json = new JSONObject(jsonString);
int someInt = json.getInt("someInt");
String someString = json.getString("someString");
} catch (JSONException e) {
Log.d(TAG, "Failed to load from JSON: " + e.getMessage());
}
You can use the org.json package, bundled in the SDK.
See here: http://developer.android.com/reference/org/json/JSONTokener.html
One more choice: use Jackson.
Simple usage; if you have a POJO to bind to:
ObjectMapper mapper = new ObjectMapper(); // reusable
MyClass value = mapper.readValue(source, MyClass.class); // source can be String, File, InputStream
// back to JSON:
String jsonString = mapper.writeValue(value);
to a Map:
Map<?,?> map = mapper.readValue(source, Map.class);
or to a Tree: (similar to what default Android org.json package provides)
JsonNode treeRoot = mapper.readTree(source);
and more examples can be found at http://wiki.fasterxml.com/JacksonInFiveMinutes.
Benefits compared to other packages is that it is lightning fast; very flexible and versatile (POJOs, maps/lists, json trees, even streaming parser), and is actively developed.