how to print Original request body JSON without any modification in java? - java

Normally to print out request body i using ObjectMapper, but this way removing space and printing object to string in one line, example :
if i send request body like this :
{
"Header" : "value"
}
and i using objectMapper to print that object
ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(requestBody)
the out put is like this :
{"Header":"value"}
how to print Original request body without any modification ?

I'm not sure if you can print it in it's original form but you can pretty print it.
With Jackson's Object Mapper, you can do something like:
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(body);
System.out.println(json);
or
ObjectMapper mapper = new ObjectMapper().enable(SerializationFeature.INDENT_OUTPUT);
String json = mapper.writeValueAsString(body);
System.out.println(json);

I don't think you can do this without using any framework.
But you can use the gson for this if you enable the prettyPrinting option. Example:
Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
prettyPrintedString = gson.toJson(requestBody, Object.class);

Related

Store request body as JSON into the database - Java

I want to store the request body into the database. I am storing the headers and request into the audit trail table.
For conversion of headers, I am creating a map and then storing the json into the database like this:
String method = httpServletRequest.getMethod();
Enumeration<String> values = httpServletRequest.getHeaderNames();
Map<String,String> headers = new HashMap<String, String>();
while (values.hasMoreElements()) {
String key = values.nextElement();
String innerValue = (String)httpServletRequest.getHeader(key);
headers.put(key,innerValue);
}
// converting object to Array
auditTrail.setHeaders(appUtility.objectToString(headers));
How can I store the request body as json into the database (ignore files for now)? The request body can be one object, array of objects or a combination.
Right now, I have written an ASPECT which will store all the incoming requests into the database. It's easy to store the json of the object when I know the Object but how can we make it generic?
If you know that content is JSON and want to read data from stream you can do it on this way:
String jsonBody = request.getReader().lines()
.collect(Collectors.joining(System.lineSeparator()));
If you need to validate is jsonBody really JSON you can use Jackson:
public static boolean isJSONValid(String jsonInString ) {
try {
final ObjectMapper mapper = new ObjectMapper();
mapper.readTree(jsonInString);
return true;
} catch (IOException e) {
return false;
}
}
If you have a body as the object you can use Jackson.
Example:
SomeObject body = ...; // Your body
ObjectMapper objectMapper = new ObjectMapper();
String bodyAsString = objectMapper.writeValueAsString(body); // To JSON
body = objectMapper.readValue(bodyAsString, SomeObject.class); // From JSON
Jakson with maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>

Parsing unquoted JSON keys using org.json.simple in Java

I have a JSON stored in a string.
String data = "{code: '0', distCode: '123'}";
I need to get the values of code, distCode. But when I try to parse it as below
JSONParser parser = new JSONParser();
JSONObject Details = (JSONObject) parser.parse(data);
Unexpected character (c) at position 2 exception is thrown.
I am sure it is because of unquoted keys in the string. How to parse the string into an JSON object using org.json.simple library?
Could not find way to achieve it using org.json.simple library. Finally done it using jackson libraries.
String data = "{code: '0', distCode: '123'}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
Map<String, String> Shop_Details = mapper.readValue(data), Map.class);

Using Java ObjectMapper to get JSON String

I am using writeValueAsString of the ObjectMapper . However, it's giving me a Java String representation so I get:
{"network_id":5000370004610700049753}
instead of
"{\"network_id\":5000370004610700049753}"
which is failing for other services when deserializing. How do I get this kind of serialization with the ObjectMapper?
To get the second result, send it through the ObjectMapper again.
Map<String, Object> data = new HashMap<>();
data.put("network_id", new BigInteger("5000370004610700049753"));
ObjectMapper objectMapper = new ObjectMapper();
String plainJson = objectMapper.writeValueAsString(data);
System.out.println(plainJson);
String encodedJson = objectMapper.writeValueAsString(plainJson);
System.out.println(encodedJson);
Output
{"network_id":5000370004610700049753}
"{\"network_id\":5000370004610700049753}"

convert arrayList multimap to json string?

I have the following code:
public static void postHttpStream(ArrayListMultimap<String, String> fcmbuildProperties){
HttpClient client = new HttpClient();
Gson gson = new Gson();
System.out.println(fcmbuildProperties);
String jsonString = gson.toJson(fcmbuildProperties);
System.out.println(jsonString);
}
where fcmbuildProperties is an ArrayListMultimap. I try to convert that to JSON here: String jsonString = gson.toJson(fcmbuildProperties); But this returns an empty array. What do I need to do instead?
This is the input that fcmbuildProperties contain : {build.name=[test_project], build.timestamp=[1425600727488], build.number=[121]}
I need to convert this to Json. with key/values.
Use ArrayListMultimap#asMap()
String jsonString = gson.toJson(fcmbuildProperties.asMap());
Gson considers ArrayListMultimap as a Map and ignores its internal state which actually manages the multimap. asMap returns a corresponding Map instance which you can serialize as expected.

Convert JsonNode into POJO

This may seem a little unusual, but I am looking for an efficient way to transform/map a JsonNode into a POJO.
I store some of my Model's information in json files and I have to support a couple of version of my model.
What I do is load the json file in memory in a JsonNode, apply a couple of versioning strategies to make it match the latest version of my Model.
ObjectMapper mapper = new ObjectMapper();
BufferedReader fileReader = new BufferedReader(new FileReader(projPath));
JsonNode rootNode = mapper.readTree(fileReader);
//Upgrade our file in memory
applyVersioningStrategy(rootNode);
ProjectModel project = mapJsonNodeToProject(rootNode);
Unless there's a faster way to do it, I will probably end up simply manually applying the JsonNodes to my Model
In Jackson 2.4, you can convert as follows:
MyClass newJsonNode = jsonObjectMapper.treeToValue(someJsonNode, MyClass.class);
where jsonObjectMapper is a Jackson ObjectMapper.
In older versions of Jackson, it would be
MyClass newJsonNode = jsonObjectMapper.readValue(someJsonNode, MyClass.class);
This should do the trick:
mapper.readValue(fileReader, MyClass.class);
I say should because I'm using that with a String, not a BufferedReader but it should still work.
Here's my code:
String inputString = // I grab my string here
MySessionClass sessionObject;
try {
ObjectMapper objectMapper = new ObjectMapper();
sessionObject = objectMapper.readValue(inputString, MySessionClass.class);
Here's the official documentation for that call: http://jackson.codehaus.org/1.7.9/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(java.lang.String, java.lang.Class)
You can also define a custom deserializer when you instantiate the ObjectMapper:
http://wiki.fasterxml.com/JacksonHowToCustomDeserializers
Edit:
I just remembered something else. If your object coming in has more properties than the POJO has and you just want to ignore the extras you'll want to set this:
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Or you'll get an error that it can't find the property to set into.
If you're using org.codehaus.jackson, this has been possible since 1.6. You can convert a JsonNode to a POJO with ObjectMapper#readValue: http://jackson.codehaus.org/1.9.4/javadoc/org/codehaus/jackson/map/ObjectMapper.html#readValue(org.codehaus.jackson.JsonNode, java.lang.Class)
ObjectMapper mapper = new ObjectMapper();
JsonParser jsonParser = mapper.getJsonFactory().createJsonParser("{\"foo\":\"bar\"}");
JsonNode tree = jsonParser.readValueAsTree();
// Do stuff to the tree
mapper.readValue(tree, Foo.class);
String jsonInput = "{ \"hi\": \"Assume this is the JSON\"} ";
com.fasterxml.jackson.databind.ObjectMapper mapper =
new com.fasterxml.jackson.databind.ObjectMapper();
MyClass myObject = objectMapper.readValue(jsonInput, MyClass.class);
If your JSON input in has more properties than your POJO has and you just want to ignore the extras in Jackson 2.4, you can configure your ObjectMapper as follows. This syntax is different from older Jackson versions. (If you use the wrong syntax, it will silently do nothing.)
mapper.disable(com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNK‌​NOWN_PROPERTIES);
This is also a different way and can be used for an array of objects
ObjectReader reader = mapper.readerFor(new TypeReference<List<SomeClass>>() {
});
assert someJsonNode.isArray()
List<SomeClass> list = reader.readValue(someJsonNode);

Categories