We have a use-case of processing JSON documents in a Java application. Although we do not use MongoDB, I would like to know if there are any Java library for JSON processing that supports similar MongoDB functionalities like querying, filtering, mapping, aggregating, unwind, etc.
You can map your json string to java object and query the object itself. There are many library that can achieve this. You can use Apache Commons for querying object property using PropertyUtils class and Google-Gson for mapping your json string to java object. Refer below's code.
String json = "{status : true, statusMsg : 'Success', preferredSchedule : {dateStr : '20 Apr 2015'}}";
Gson gson = new Gson();
VpVO vpVO = gson.fromJson(json, VpVO.class);
try {
Object dateObj = PropertyUtils.getProperty(vpVO, "preferredSchedule.dateStr");
System.out.println(dateObj); // result will print 20 Apr 2015
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Related
In a Java/Spring application, I have a POJO/bean. Let's call it CourseRequest. It is converted/serialized into a string and sent out in a PUT REST request. The conversion is done using org.codehaus.jackson.map.ObjectMapper. The sending is done using org.scribe.model.OAuthRequest. See simplified code:
OAuthRequest request = new OAuthRequest(...);
CourseRequest courseRequest = new CourseRequest(...);
ObjectMapper mapper = new ObjectMapper();
String courseJson = null;
try {
// convert to json.
courseJson = mapper.writeValueAsString(courseRequest);
request.addPayload(courseJson);
request.send();
} catch (JsonGenerationException e) {
logger.error(e);
} catch (JsonMappingException e) {
logger.error(e);
} catch (IOException e) {
logger.error(e);
}
I have run into a problem where I need to remove a property instructorId from the JSON/payload before sending the request. Obviously, I can't just naively remove the property in CourseRequest because the POJO/bean is used in other places too.
So, what is the best way to do it?
I can't use #JsonIgnore or alike annotations, because
I want to remove the property only on some conditions;
There are other requests elsewhere in the application which may want to keep the property
For initial thoughts:
As a "hack", I can do a regex replace on the courseJson to remove the property after mapper.writeValueAsString(courseRequest) but I think that's not a very clean way to do it.
I can parse the courseJson back into some kind of map and then remove the property but that's just clumsy.
P.S. I am using Jackson v1.9.13
I have a Entity named MyData. And I am trying to add MyData entity's values to database. Like below:
for (MyDataParent myDataParent : myDataParentList) {
MyData myData = new Mydata();
myData.setName("Hello");
myData.setNumber("1234567890");
myData.setGender("Male");
this.storeAndflush(myData);
}
And I want to skip inserting this myData entity if any exception occurred while storing data and continue to the loop. What is the way to do?
Use the try-catch block and log the relevant exception. If you are using SQL database it most likely will be SQLException.
for (MyDataParent myDataParent : myDataParentList) {
MyData myData = new Mydata();
myData.setName("Hello");
myData.setNumber("1234567890");
myData.setGender("Male");
try {
this.storeAndflush(myData);
} catch (SQLException ex) {
logger.log(ex);
}
}
Try not to catch all possible exceptions e.g. don't catch Exception or Throwable. Handle only these which are related to persistence to ensure that you are not hiding implementation errors.
I am working on a JavaSE application in which I would like to connect to a Spring-MVC based server to get List of objects, Objects itself. I looked up on net, and came upon JSON. While I agree that it is working, but it is very inefficient as I have to go through the 2 while loops and seems not so sophisticated. For this reason I researched and found out I can use Spring remoting to achieve the task.
One thing I would like to do is to send over objects directly, instead of converting them by JSON, and sending.
I am pasting my code below for what I have with JSON, I would appreciate if I know this seems more better or is Spring remoting more sophisticated in long term too. A replacement code for the client side would be nice. Thanks.
Client code :
public void getCanvas(){
JsonFactory jsonFactory = new JsonFactory();
String canvas = "";
try {
JsonParser jsonParser = jsonFactory.createJsonParser(new URL(canvasURL));
JsonToken token = jsonParser.nextToken();
while (token!=JsonToken.START_ARRAY && token!=null){
token = jsonParser.nextToken();
if(token==null){break;}
System.out.println("Token is "+jsonParser.getText());
}
while (token!=JsonToken.END_ARRAY){
token = jsonParser.nextToken();
if(token == JsonToken.START_OBJECT){
canvas = jsonParser.toString();
System.out.println("Canvas is "+canvas);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("Canvas is "+canvas);
}
Server code :
#RequestMapping(value = "/getcanvas",method = RequestMethod.GET)
public #ResponseBody String getCanvasforFX(){
System.out.println("Canvas was requested");
Canvas canvas = this.canvasService.getCanvasById(10650);
canvas.setCanvasimage(null);
ObjectMapper objectMapper = new ObjectMapper();
try {
System.out.println("Canvas value is "+objectMapper.writeValueAsString(canvas));
return objectMapper.writeValueAsString(canvas);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
In the client-code I am getting the information, but again I have to read the fields, set them in object and update the UI, even though I am programming the server also, I want to directly receive an object, and cut out the middle-man(JSON). Thanks.
I am using Jackson 2.5.1 (com.fasterxml.jackson.core.JsonGenerator) to write JSON document to an output stream. It looks like the API allow us to write wrong JSON to the stream? I thought if we try to write elements in wrong context, it is supposed to throw JsonGenerationException or IOException. Here is the code snippet :
try {
JsonFactory jfactory = new JsonFactory();
ByteArrayOutputStream b = new ByteArrayOutputStream();
JsonGenerator jsonGenerator = jfactory.createJsonGenerator(b, JsonEncoding.UTF8);
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("str1", "blahblah");
jsonGenerator.writeNumber(1234);
jsonGenerator.writeEndObject();
jsonGenerator.close();
System.out.println(b.toString());
} catch (Exception e) {
e.printStackTrace();
}
The output is : {"str1":"blahblah":1234} and it is not a valid JSON. Is this expected behavior or I am missing something? I thought the API itself tracks if the objects are written in correct context. Does it need to be enforced by the application itself? It is not clear from the documentation :
http://fasterxml.github.io/jackson-core/javadoc/2.0.0/com/fasterxml/jackson/core/JsonGenerator.html
We work on a Java (Java EE) application, and we generate XML files in order to send them to a remote .NET application with MSMQ reading on their side.
The XML file is generated by JDom, like so :
// add elements...
Document doc = new Document(root);
String XmlData = new XMLOutputter(Format.getPrettyFormat().setOmitEncoding(true)).outputString(doc);
try {
SendFile( XmlData, "title" , "path");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MessageQueueException e) {
e.printStackTrace();
}
Then we use this function, using the MsmqJava library to send the file :
private void SendFile(String data, String title, String outputPath) throws UnsupportedEncodingException, MessageQueueException{
String qname="name_of_the_queue";
String fullname= "server_path" + qname;
String body = data;
String label = title;
String correlationId= "L:none";
try {
Queue queue= new Queue(fullname);
Message msg= new Message(body, label, correlationId);
queue.send(msg);
} catch (MessageQueueException ex1) {
System.out.println("Put failure: " + ex1.toString());
}
}
They correctly receive the file, but they told us that the bodyType was set to "VT_EMPTY" while they wanted "VT_BSTR", and we haven't find a clue about how to fix this. If you know another lib who does the job, or a workaround to this one, we can change with no problem.
Thanks !
Looking at the documentation for the library you use, it is not possible using that library.
Jmsmqqueue also doesn't provide the functionality you need.
It seems sun also had an adapter: https://wikis.oracle.com/display/JavaCAPS/Sun+Adapter+for+MSMQ