Jackson Mixin not working in Pojo to json - java

My target is xml to Pojo and Pojo to json. I already did xml to pojo using jaxb. Now I am trying pojo to json using jackson Jaxb. Where I am getting the following json which produce JXBElement class fileds in json like following.
{
"name" : "{http://xxx.xx.xx.xx.xx.xx.xx}CompositeResponse",
"declaredType" : "xxx.xx.xx.xx.xx.xx.xxCompositeResponseType",
"scope" : "javax.xml.bind.JAXBElement$GlobalScope",
"value" : {
"CompositeIndividualResponse" : [ {
"ResponseMetadata" : {
"ResponseCode" : "HS000000",
"ResponseDescriptionText" : "Success"
}
} ]
},
"nil" : false,
"globalScope" : true,
"typeSubstituted" : false
}
How Can I removed name, declaredType,scope,nil, globalScope,typeSubstituted ang get the following json
{
"CompositeResponse":
{
"CompositeIndividualResponse" : [ {
"ResponseMetadata" : {
"ResponseCode" : "HS000000",
"ResponseDescriptionText" : "Success"
}
} ]
}
}
I was looking this post but this does not work for me.
The following code I have tried for jackson mixin.
public class Main {
public static interface JAXBElementMixinT {
#JsonValue
Object getValue();
}
public static void main(String[] args) throws XMLStreamException, IOException {
ObjectMapper mapper = new ObjectMapper();
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector );
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.addMixIn(JAXBElement.class, JAXBElementMixinT.class);
String result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
System.out.println(result);
}
}
I also tried with following code but no luck.
public abstract class JAXBElementMixIn {
#JsonIgnore abstract String getScope();
#JsonIgnore abstract boolean isNil();
#JsonIgnore abstract boolean isGlobalScope();
#JsonIgnore abstract boolean isTypeSubstituted();
#JsonIgnore abstract Class getDeclaredType();
}
Can anyone help me where I am wrong and what to do thanks.

I just faced this issue this week in fact and solved it by removing the
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector );
Piece. I haven't looked back into how to add that back yet, but that let the rest of the code you have work for me correctly and I'm no longer seeing the JAXBElement wrapper.

Finally I am able to solve the problem. According #Ryan answer I donot need the following code:
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(mapper.getTypeFactory());
mapper.setAnnotationIntrospector(introspector );
But I have to add the JaxbAnnotationModule module = new JaxbAnnotationModule(); mapper.registerModule(module) otherwise jackson will produce links and metadata for every element. The complete code is following
public class Main {
public static interface JAXBElementMixinT {
#JsonValue
Object getValue();
}
public static void main(String[] args) throws XMLStreamException, IOException {
ObjectMapper mapper = new ObjectMapper();
JaxbAnnotationModule module = new JaxbAnnotationModule();
mapper.registerModule(module)
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.addMixIn(JAXBElement.class, JAXBElementMixinT.class);
String result = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(employee);
System.out.println(result);
}
}

Related

How would I print an object's name as part of the JSON in Java's Jackson library?

I'm trying to determine how to print out a JSON that looks like this, using Java's Jackson library:
{
"status": {
{
"busStatus" : {
"status" : null,
"transactions" : "0",
"retries" : "0",
"failures" : "0"
}
}
}
}
I'm 95% there, but the outermost object is not currently being printed. This is what I'm currently getting outputted:
{
"busStatus" : {
"status" : null,
"transactions" : "0",
"retries" : "0",
"failures" : "0"
}
}
I have a Java class that looks like this:
public class DataClass {
public StatusData status = new StatusData();
public StatusConfig config = new StatusConfig();
public class StatusData {
public SerialStatus busStatus = new SerialStatus();
}
public class StatusConfig {
}
public class SerialStatus {
public String status = null;
public String transactions = "0";
public String retries = "0";
public String failures = "0";
}
}
I'm printing this class to json using the code below:
private DataClass internalData;
ObjectMapper mapper = new ObjectMapper();
status = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(internalData.status);
Is there a way I can configure Jackson to print out the name of the object its serializing into the JSON?
To achieve what you want, you need to print DataClass instead of StatusData. Something like below:
private DataClass internalData = <initialize>;
ObjectMapper mapper = new ObjectMapper();
String data =
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(internalData);
You can use Jackson Filter to control the serialization process, I think it should work with your use case, at least one way to do it.
Use the filter annotation and then create two different filters for your class, where you can define which field to skip, and use it with the ObjectMapper accordingly to convert the whole internalData object, so when you need to skip the status, use one filter and when you need to skip the config associate the other filter with the mapper, while always serializing the parent object. Which should give you the structure you want.
#JsonFilter("filter_serializer")
class User {
public String v1;
public String v2;
}
String[] fieldsToSkip = new String[] { "v1" };
ObjectMapper mapper = new ObjectMapper();
final SimpleFilterProvider filter = new SimpleFilterProvider();
filter.addFilter("filter_serializer",
SimpleBeanPropertyFilter.serializeAllExcept(fieldsToSkip));
User dtoObject = new User();
dtoObject.v1 = "v1";
dtoObject.v2 = "v2";
String jsonStr = mapper.writer(filter).writeValueAsString(dtoObject);
I was able to find the solution I was looking for, from this website.
I've gotten rid of the DataClass and now only have a StatusData and a StatusConfig class. I've included how the StatusData class would look below:
#JsonRootName(value = "status")
public class StatusData {
String status;
String transactions;
// so on
}
To parse the class, I needed to add the JsonRootName annotation above, and also enable a feature on the mapper, as below:
private DataClass internalData;
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE); // don't forget this!
statusText = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(statusObject);
Separately, if you'd like to deserialize a JSON like the one I had into a class like StatusData, do this:
mapper.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true);
statusObject = mapper.readValue(statusText, StatusData.class);

No serializer found for class java.io.ByteArrayInputStream

I am getting the below error message while getting the user entity from the openfire rest api. ( I am wrapping the my Api Endpoints with openfire Restapi Endpoints.)
"error": "Internal Server Error",
"exception": "org.springframework.http.converter.HttpMessageNotWritableException",
"message": "Could not write JSON: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class java.io.ByteArrayInputStream and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.mashape.unirest.http.HttpResponse[\"rawBody\"])",
"path": "/usersInfo/user2"
The code is the following.
String host ="http://abdul01anpi01:9090" ;
String userEndPoint = "/plugins/restapi/v1/users" ;
String apiURL = host+userEndPoint ;
HttpResponse<JsonNode> response =null;
response = Unirest.get(apiURL +"/{username}").header("accept", "application/json").header("Content-Type", "application/json").routeParam("username",String.valueOf(username)).asJson();
The expected output from the response is the following.
{
"username": "user2",
"name": "user2",
"properties": null
}
Kindly advise, any help is appreciated.
The poster found a solution and posted it in a comment. Since it's been a few years, I figured it might be worth copying as an actual answer:
#Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(mapper);
return converter;
}
Let me add the description for the flag that is being set to false :
/**
* Feature that determines what happens when no accessors are
* found for a type (and there are no annotations to indicate
* it is meant to be serialized). If enabled (default), an
* exception is thrown to indicate these as non-serializable
* types; if disabled, they are serialized as empty Objects,
* i.e. without any properties.
*<p>
* Note that empty types that this feature has only effect on
* those "empty" beans that do not have any recognized annotations
* (like <code>#JsonSerialize</code>): ones that do have annotations
* do not result in an exception being thrown.
*<p>
* Feature is enabled by default.
*/
FAIL_ON_EMPTY_BEANS
it works, add a ResourceHttpMessageConverter!
#Configuration
public class EirExceptionConfig extends WebMvcConfigurerAdapter {
#Autowired
ObjectMapper objectMapper;
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(EirException.class, new EirExceptionJackson2Serializer());
objectMapper.registerModule(simpleModule);
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(objectMapper);
converters.add(new ResourceHttpMessageConverter());
converters.add(converter);
}
}
Another way to solve this issue is to ignore the property which has return type of ByteArrayInputStream, for example you could decorate this class:
class Frodo {
private bytes[] value;
public Frodo(bytes[] value) {
this.value = value;
}
public ByteArrayInputStream getFoo() throws IOException {
return new ByteArrayInputStream(value());
}
public void setFoo(ByteArrayInputStream streamData) {
// set value from streamData
}
}
like this:
#JsonIgnoreProperties(value = { "foo" })
class Frodo {
private bytes[] value;
public Frodo(bytes[] value) {
this.value = value;
}
public ByteArrayInputStream getFoo() throws IOException {
return new ByteArrayInputStream(value());
}
public void setFoo(ByteArrayInputStream streamData) {
// set value from streamData
}
}
you can also ignore multiple properties: #JsonIgnoreProperties(value = { "foo", "anotherValue" })

Jackson filtering out fields without annotations

I was trying to filter out certain fields from serialization via SimpleBeanPropertyFilter using the following (simplified) code:
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
SimpleFilterProvider filterProvider = new SimpleFilterProvider().addFilter("test",
SimpleBeanPropertyFilter.filterOutAllExcept("data1"));
try {
String json = mapper.writer(filterProvider).writeValueAsString(new Data());
System.out.println(json); // output: {"data1":"value1","data2":"value2"}
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
private static class Data {
public String data1 = "value1";
public String data2 = "value2";
}
Us I use SimpleBeanPropertyFilter.filterOutAllExcept("data1")); I was expecting that the created serialized Json string contains only {"data1":"value1"}, however I get {"data1":"value1","data2":"value2"}.
How to create a temporary writer that respects the specified filter (the ObjectMapper can not be re-configured in my case).
Note: Because of the usage scenario in my application I can only accept answers that do not use Jackson annotations.
If for some reason MixIns does not suit you. You can try this approach:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setAnnotationIntrospector(new JacksonAnnotationIntrospector(){
#Override
public boolean hasIgnoreMarker(final AnnotatedMember m) {
List<String> exclusions = Arrays.asList("field1", "field2");
return exclusions.contains(m.getName())|| super.hasIgnoreMarker(m);
}
});
You would normally annotate your Data class to have the filter applied:
#JsonFilter("test")
class Data {
You have specified that you can't use annotations on the class. You could use mix-ins to avoid annotating Data class.
#JsonFilter("test")
class DataMixIn {}
Mixins have to be specified on an ObjectMapper and you specify you don't want to reconfigure that. In such a case, you can always copy the ObjectMapper with its configuration and then modify the configuration of the copy. That will not affect the original ObjectMapper used elsewhere in your code. E.g.
ObjectMapper myMapper = mapper.copy();
myMapper.addMixIn(Data.class, DataMixIn.class);
And then write with the new ObjectMapper
String json = myMapper.writer(filterProvider).writeValueAsString(new Data());
System.out.println(json); // output: {"data1":"value1"}
The example of excluding properties by name:
public Class User {
private String name = "abc";
private Integer age = 1;
//getters
}
#JsonFilter("dynamicFilter")
public class DynamicMixIn {
}
User user = new User();
String[] propertiesToExclude = {"name"};
ObjectMapper mapper = new ObjectMapper()
.addMixIn(Object.class, DynamicMixIn.class);
FilterProvider filterProvider = new SimpleFilterProvider()
.addFilter("dynamicFilter", SimpleBeanPropertyFilter.filterOutAllExcept(propertiesToExclude));
mapper.setFilterProvider(filterProvider);
mapper.writeValueAsString(user); // {"name":"abc"}
You can instead of DynamicMixIn create MixInByPropName
#JsonIgnoreProperties(value = {"age"})
public class MixInByPropName {
}
ObjectMapper mapper = new ObjectMapper()
.addMixIn(Object.class, MixInByPropName.class);
mapper.writeValueAsString(user); // {"name":"abc"}
Note: If you want exclude property only for User you can change parameter Object.class of method addMixIn to User.class
Excluding properties by type you can create MixInByType
#JsonIgnoreType
public class MixInByType {
}
ObjectMapper mapper = new ObjectMapper()
.addMixIn(Integer.class, MixInByType.class);
mapper.writeValueAsString(user); // {"name":"abc"}
It seems you have to add an annotation which indicts which filter to use when doing the serialization to the bean class if you want the filter to work:
#JsonFilter("test")
public class Data {
public String data1 = "value1";
public String data2 = "value2";
}
EDIT
The OP has just added a note that just take the answer that not using a bean animation, then if the field you want to export is very less amount, you can just retrieve that data and build a Map of List yourself, there seems no other way to do that.
Map<String, Object> map = new HashMap<String, Object>();
map.put("data1", obj.getData1());
...
// do the serilization on the map object just created.
If you want to exclude specific field and kept the most field, maybe you could do that with reflect. Following is a method I have written to transfer a bean to a map you could change the code to meet your own needs:
protected Map<String, Object> transBean2Map(Object beanObj){
if(beanObj == null){
return null;
}
Map<String, Object> map = new HashMap<String, Object>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(beanObj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
if (!key.equals("class")
&& !key.endsWith("Entity")
&& !key.endsWith("Entities")
&& !key.endsWith("LazyInitializer")
&& !key.equals("handler")) {
Method getter = property.getReadMethod();
if(key.endsWith("List")){
Annotation[] annotations = getter.getAnnotations();
for(Annotation annotation : annotations){
if(annotation instanceof javax.persistence.OneToMany){
if(((javax.persistence.OneToMany)annotation).fetch().equals(FetchType.EAGER)){
List entityList = (List) getter.invoke(beanObj);
List<Map<String, Object>> dataList = new ArrayList<>();
for(Object childEntity: entityList){
dataList.add(transBean2Map(childEntity));
}
map.put(key,dataList);
}
}
}
continue;
}
Object value = getter.invoke(beanObj);
map.put(key, value);
}
}
} catch (Exception e) {
Logger.getAnonymousLogger().log(Level.SEVERE,"transBean2Map Error " + e);
}
return map;
}
But I recommend you to use Google Gson as the JSON deserializer/serializer And the main reason is I hate dealing with exception stuff, it just messed up with the coding style.
And it's pretty easy to satisfy your need with taking advantage of the version control annotation on the bean class like this:
#Since(GifMiaoMacro.GSON_SENSITIVE) //mark the field as sensitive data and will not export to JSON
private boolean firstFrameStored; // won't export this field to JSON.
You can define the Macro whether to export or hide the field like this:
public static final double GSON_SENSITIVE = 2.0f;
public static final double GSON_INSENSITIVE = 1.0f;
By default, Gson will export all field that not annotated by #Since So you don't have to do anything if you do not care about the field and it just exports the field.
And if some field you are not want to export to json, ie sensitive info just add an annotation to the field. And generate json string with this:
private static Gson gsonInsensitive = new GsonBuilder()
.registerTypeAdapter(ObjectId.class,new ObjectIdSerializer()) // you can omit this line and the following line if you are not using mongodb
.registerTypeAdapter(ObjectId.class, new ObjectIdDeserializer()) //you can omit this
.setVersion(GifMiaoMacro.GSON_INSENSITIVE)
.disableHtmlEscaping()
.create();
public static String toInsensitiveJson(Object o){
return gsonInsensitive.toJson(o);
}
Then just use this:
String jsonStr = StringUtils.toInsensitiveJson(yourObj);
Since Gson is stateless, it's fine to use a static method to do your job, I have tried a lot of JSON serialize/deserialize framework with Java, but found Gson to be the sharp one both performance and handily.

Jaxb annotation #xmlelement(name="ElementName") not binding with xml element name

My Spring MVC Web Service code is as follows.
Model Class
#XmlRootElement(name="wrappedSecretData")
public class VendorData {
private long lKeyId;
#XmlElement(name="keyId")
public long getlKeyId() {
return lKeyId;
}
public void setlKeyId(long lKeyId) {
this.lKeyId = lKeyId;
}
}
Controller Method
#RequestMapping(value = "/vendor", method = RequestMethod.POST)
public String addVendor(#RequestBody VendorData vendorData) {
/*Checking recieved value*/
System.out.println(vendorData.getlKeyId());//**Returning 0 value **
return "Success";
}
Xml request body for web service
<wrappedVendorSecretsMetadata>
<keyId>1</keyId>
</wrappedVendorSecretsMetadata>
I am getting "0" value in lKeyId(Bold comment).
Where am I doing wrong.
Please provide the correct way to bind the xml element to object member using #XmlElement(name="keyId") annotation.
I think you need the #XmlElement only over the variable declaration.
try this:
#XmlRootElement(name="wrappedVendorSecretsMetadata")
#XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
public class VendorData {
private long lKeyId;
public VendorData(){
}
#XmlElement(name="keyId")
public long getlKeyId() {
return lKeyId;
}
public void setlKeyId(long lKeyId) {
this.lKeyId = lKeyId;
}
}
By default, annotations doesn't work with XmlMapper in jaxb. You have to register the annotation module for this purpose as I have done in the following code block:
String xmlData = getMyXmlData();
ObjectMapper objectMapper = new XmlMapper();
objectMapper.registerModule(new JaxbAnnotationModule());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyClass myObj= objectMapper.readValue(xmlData , MyClass.class);
In your case, you have to overwrite the Xml to Object binding process. To do that, you can receive the the HttpRequest in your controller and then convert the xml data to VendorData using your own java code.

Convert JSON String to Pretty Print JSON output using Jackson

This is the JSON string I have:
{"attributes":[{"nm":"ACCOUNT","lv":[{"v":{"Id":null,"State":null},"vt":"java.util.Map","cn":1}],"vt":"java.util.Map","status":"SUCCESS","lmd":13585},{"nm":"PROFILE","lv":[{"v":{"Party":null,"Ads":null},"vt":"java.util.Map","cn":2}],"vt":"java.util.Map","status":"SUCCESS","lmd":41962}]}
I need to convert the above JSON String into Pretty Print JSON Output (using Jackson), like below:
{
"attributes": [
{
"nm": "ACCOUNT",
"lv": [
{
"v": {
"Id": null,
"State": null
},
"vt": "java.util.Map",
"cn": 1
}
],
"vt": "java.util.Map",
"status": "SUCCESS",
"lmd": 13585
},
{
"nm": "PROFILE
"lv": [
{
"v": {
"Party": null,
"Ads": null
},
"vt": "java.util.Map",
"cn": 2
}
],
"vt": "java.util.Map",
"status": "SUCCESS",
"lmd": 41962
}
]
}
Can anyone provide me an example based on my example above? How to achieve this scenario? I know there are lot of examples, but I am not able to understand those properly. Any help will be appreciated with a simple example.
Updated:
Below is the code I am using:
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonString));
But this doesn't works with the way I needed the output as mentioned above.
Here's is the POJO I am using for the above JSON:
public class UrlInfo implements Serializable {
private List<Attributes> attribute;
}
class Attributes {
private String nm;
private List<ValueList> lv;
private String vt;
private String status;
private String lmd;
}
class ValueList {
private String vt;
private String cn;
private List<String> v;
}
Can anyone tell me whether I got the right POJO for the JSON or not?
Updated:
String result = restTemplate.getForObject(url.toString(), String.class);
ObjectMapper mapper = new ObjectMapper();
Object json = mapper.readValue(result, Object.class);
String indented = mapper.defaultPrettyPrintingWriter().writeValueAsString(json);
System.out.println(indented);//This print statement show correct way I need
model.addAttribute("response", (indented));
Below line prints out something like this:
System.out.println(indented);
{
"attributes" : [ {
"nm" : "ACCOUNT",
"error" : "null SYS00019CancellationException in CoreImpl fetchAttributes\n java.util.concurrent.CancellationException\n\tat java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat java.util.concurrent.FutureTask.",
"status" : "ERROR"
} ]
}
which is the way I needed to be shown. But when I add it to model like this:
model.addAttribute("response", (indented));
And then shows it out in a resultform jsp page like below:
<fieldset>
<legend>Response:</legend>
<strong>${response}</strong><br />
</fieldset>
I get something like this:
{ "attributes" : [ { "nm" : "ACCOUNT", "error" : "null
SYS00019CancellationException in CoreImpl fetchAttributes\n
java.util.concurrent.CancellationException\n\tat
java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat
java.util.concurrent.FutureTask.", "status" : "ERROR" } ] }
which I don't need. I needed the way it got printed out above. Can anyone tell me why it happened this way?
To indent any old JSON, just bind it as Object, like:
Object json = mapper.readValue(input, Object.class);
and then write it out with indentation:
String indented = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);
this avoids your having to define actual POJO to map data to.
Or you can use JsonNode (JSON Tree) as well.
The simplest and also the most compact solution (for v2.3.3):
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)
The new way using Jackson 1.9+ is the following:
Object json = OBJECT_MAPPER.readValue(diffResponseJson, Object.class);
String indented = OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
.writeValueAsString(json);
The output will be correctly formatted!
ObjectMapper.readTree() can do this in one line:
mapper.readTree(json).toPrettyString();
Since readTree produces a JsonNode, this should pretty much always produce equivalent pretty-formatted JSON, as it JsonNode is a direct tree representation of the underlying JSON string.
Prior to Jackson 2.10
The JsonNode.toPrettyString() method was added in Jackson 2.10. Prior to that, a second call to the ObjectMapper was needed to write the pretty formatted result:
mapper.writerWithDefaultPrettyPrinter()
.writeValueAsString(mapper.readTree(json));
For Jackson 1.9, We can use the following code for pretty print.
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
I think, this is the simplest technique to beautify the json data,
String indented = (new JSONObject(Response)).toString(4);
where Response is a String.
Simply pass the 4(indentSpaces) in toString() method.
Note: It works fine in the android without any library. But in java you have to use the org.json library.
You can achieve this using bellow ways:
1. Using Jackson
String formattedData=new ObjectMapper().writerWithDefaultPrettyPrinter()
.writeValueAsString(YOUR_JSON_OBJECT);
Import bellow class:
import com.fasterxml.jackson.databind.ObjectMapper;
It's gradle dependency is :
compile 'com.fasterxml.jackson.core:jackson-core:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'
2. Using Gson from Google
String formattedData=new GsonBuilder().setPrettyPrinting()
.create().toJson(YOUR_OBJECT);
Import bellow class:
import com.google.gson.Gson;
It's gradle is:
compile 'com.google.code.gson:gson:2.8.2'
Here, you can also download correct updated version from repository.
This looks like it might be the answer to your question. It says it's using Spring, but I think that should still help you in your case. Let me inline the code here so it's more convenient:
import java.io.FileReader;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;
public class Foo
{
public static void main(String[] args) throws Exception
{
ObjectMapper mapper = new ObjectMapper();
MyClass myObject = mapper.readValue(new FileReader("input.json"), MyClass.class);
// this is Jackson 1.x API only:
ObjectWriter writer = mapper.defaultPrettyPrintingWriter();
// ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above:
// ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
System.out.println(writer.writeValueAsString(myObject));
}
}
class MyClass
{
String one;
String[] two;
MyOtherClass three;
public String getOne() {return one;}
void setOne(String one) {this.one = one;}
public String[] getTwo() {return two;}
void setTwo(String[] two) {this.two = two;}
public MyOtherClass getThree() {return three;}
void setThree(MyOtherClass three) {this.three = three;}
}
class MyOtherClass
{
String four;
String[] five;
public String getFour() {return four;}
void setFour(String four) {this.four = four;}
public String[] getFive() {return five;}
void setFive(String[] five) {this.five = five;}
}
Since jackson-databind:2.10 JsonNode has the toPrettyString() method to easily format JSON:
objectMapper
.readTree("{}")
.toPrettyString()
;
From the docs:
public String toPrettyString()
Alternative to toString() that will
serialize this node using Jackson default pretty-printer.
Since:
2.10
If you format the string and return object like RestApiResponse<String>, you'll get unwanted characters like escaping etc: \n, \". Solution is to convert your JSON-string into Jackson JsonNode object and return RestApiResponse<JsonNode>:
ObjectMapper mapper = new ObjectMapper();
JsonNode tree = objectMapper.readTree(jsonString);
RestApiResponse<JsonNode> response = new RestApiResponse<>();
apiResponse.setData(tree);
return response;
Anyone using POJO, DDO, or response class for returning their JSON can use spring.jackson.serialization.indent-output=true in their property file. It auto-formats the response.

Categories

Resources