Way to Consume Json request as Json object in Jersey Rest Service - json

Hi I tried googling around but cannot find solution that I want to achieve.
Example to map json to java object we do
#POST
#Consumes(application/json)
#Produces(application/json)
public Response createUpdateDeleteManualClinicalData(MyJavaPojo definedPojo) {
// this maps any json to a java object, but in my case I am dealing with generic json structure
}
What I want to achieve is Keep it as json object itself
public Response createUpdateDeleteManualClinicalData(JSONObject json)
Work around: I can get data as plain text and convert that to json. But its an overhead from my side which I want to avoid.
Edit: I am open to using any Json library like JsonNode etc... as far as I get Json object Structure directly without the overhead of String to Json from my side. This should be common usage or am I missing some core concept here.

It was a straight solution that I happened to overlooked... my bad.
Jersey is way smarter than I thought... curious to know what magic happens under the layers
#POST
#Consumes(application/json)
#Produces(application/json)
public Response createUpdateDeleteManualClinicalData(JsonNode jsonNode) {
//jsoNode body casted automatically into JsonNode
}

What is the web.xml configuration you are using? Is it something similar to here web.xml setup gists for Jersey1 and Jackson2?

If you are using the same configuration as web.xml setup gists for Jersey1 and Jackson2, then you may do as below. This is a possible alternative than using JSONObject
#POST
#Path("/sub_path2")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Map<String,Object> saveMethod( Map<String,Object> params ) throws IOException {
// Processing steps
return params;
}

Related

Jersey Web Service

I am using Jersey Rest Service. I am getting clients requests in json and getting java object out of it. Everything works fine. However, is there anyway I can get the exact json that was pass from client without even converting to java object.
Issue is json request contents just two parameters and below ObjectMapper converts back to Json but with null values. To ignore, I have to put #JsonInclude(Include.NON_NULL) on each pojo class. If I can get just client json, then it would be good.
ObjectMapper mapper=new ObjectMapper();
String jsonString= mapper.writeValueAsString(body);
Keep the following in your resource method:
#Consumes("application/json")
public Response fn(String payload){} //Notice the payload of type string.
That way the payload will be just a String. I am still not sure why you want it this way, but it should work.

JSON encoding using produces={"application/json; charset=UTF-8"} and ObjectMapper

I am trying to develop a microservice using Spring MVC and Spring Boot. In my service I am giving result back as JSON encoded format. Currently I added action like:
#RequestMapping("/checkUsers")
public String checkLogin() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
List<Users> useObj = (List<Users>) userRepo.findAll();
return(mapper.writeValueAsString(useObj));
}
And now I found the other options through the following method
produces={"application/json; charset=UTF-8"}
Here I am not sure which method is properly using for encoding the data into JSON format in Spring. How can I proceed?
Why don’t you just use
ResponseEntity
And return
new ResponseEntity<String>(“your message”, HttpStatus.OK);
#RequestMapping(method = GET, value = "my/random/uri", produces = "application/json;charset=UTF-8")
Here produces attribute inside my #RequestMapping annotation is the producible media types of the mapped request. The format is a single media type or a sequence of media types, with a request only mapped if mentioned one matches one of these media types. and here, my #RequestMapping annotation is already serving my purpose of encoding.
Now somewhere from Spring Boot documentation:
Spring Boot is a brand new framework designed to simplify the bootstrapping and development of a new Spring
application. The framework takes an opinionated approach to
configuration, freeing developers from the need to define boilerplate
configuration.
Please don't kill the purpose of Spring Boot. :)
Additionally, I would suggest you use org.springframework.http.MediaType class. It has got all encoding types you'll ever require. Happy coding.
Please let me know if you face any difficulty while going with suggested approach.
If you use #RestController on your controller, all request mappings will produce application/json by default.
Also, there is no need to to the object mapping yourself, just return the object without mapping and let Spring/Jackson do its thing.
#RestController
public class UsersController {
// #RequestMapping("/checkUsers")
// There is an even simpler and more concise
#GetMapping("/checkUsers")
public List<User> checkLogin() throws JsonProcessingException {
return userRepo.findAll();
}
}

Dropwizard good practices

I have seen in a lot of places that a resource class in a dropwizard project has methods for GET and POST. These methods then access data from the database using the DAO and return back a json
public class DropwizardResource {
private DropwizardDAO ddao;
public DropwizardResource (DropwizardDAO ddao) {
this.ddao = ddao;
}
#GET
#Timed
#UnitOfWork
public List<String> getAllResources() {
return ddao.findAll();
}
}
Is it advisable to have a resource initialized with other clients for some other service and then have the json returned by manual conversion?
public class DropwizardResource {
private NonDbClient client;
public DropwizardResource (NonDbClient client) {
this.client = client;
}
#GET
#Timed
#UnitOfWork
public List<String> getAllResources() {
return toJson(client.findAll());
}
}
First off, let's be clear: you can do whatever you like in a Dropwizard resource - there's nothing inherently special about them.
On your specific question on whether you can use "[a client] for some other service" (e.g. another Dropwizard service, or something completely separate), the answer is yes, that's perfectly fine. Note, however, if you're not using Hibernate to access a database within your resource method, you don't need the #UnitOfWork annotation (which is for declaring that a session & transaction should be managed for you when that method is called).
Finally, you ask whether it's okay to "then have the json returned by manual conversion". It's a little hard to answer that question without knowing what client you're thinking of using, and what it returns when you call its findAll method. I can think of a couple of possible scenarios:
You get deserialised plain old Java objects back from your client (regardless of how they were serialised in transit - JSON, XML, crazy proprietary binary protocol, whatever). In this case, you just need to transform these into whatever object you want to return from your Dropwizard resource method (a List<String> in the case of your example). From there, Jersey and Jackson will deal with serialising this to JSON for you and putting that in the response from your resource.
You get a string containing JSON back from your client. In this case, you'll need to manually deserialise the JSON to Java objects (using a Jackson ObjectMapper - you can grab one from the Dropwizard Environment in your application's run method). At that point you can transform then and return them as in the above case.
In either case, I can't think why you'd want to be serialising to JSON (as in your example). That'd give you a String (not a List<String>). Unless you're doing something pretty quirky, you probably don't want to be returning a JSON string from your Dropwizard resource - that will then serialise it as JSON again, and will then result in a string full of JSON being deserialised again at the other end!

List<Object> to JSON using annotations

OK, here goes, hopefully this makes sense! I have a small project based off of the appfuse web service only archetype. I have a business facade which has a DAO injected, through this DAO I request some data, simple example:
PersonManager.java
#GET
#Path("{people}")
List<Person> getPeople(#QueryParam("surname") String surname);
PersonManagerImpl.java (implements PersonManager)
public List<Person> getPeople(String surname) {
return personDao.getPeople(String surname);
}
I can make a request to invoke this method through a URL configured to point to "getPeople", however, as the DAO returns the list of people as an array list, I get the following error
Error serializing the response, please check the server logs, response class : ArrayList.
I know I can wrap this method and use Jackson Object Mapper to change the list to a string, but I didn't want another layer in my code, just to marshal JSON requests/responses.
I also don't want to change the interface to return a string, because the interface may be used later to return other data types, thus, I don't want to lock it in to only returning a string representing JSON.
My dilemma is that, I don't quite get how keeping the above interface and implementation, I can have Jackson convert the list of people to a json list of people, with annotations only!
Any help is greatly appreciated.
Please help!
Upgrading Jackson from 1.7.1 to 1.9.5 resolved this issue.

Rendering Views as String with Spring MVC and Apache Tiles

I am trying to reuse some of my tiles in a controller which is returning a json response to the client. I would like to return a json response similar to the following format:
{
'success': <true or false>,
'response': <the contents of an apache tile>
}
In my controller I would like to perform logic similar to this pseudocode:
boolean valid = validator.validate(modelObj)
String response = ""
if(valid){
response = successView.render() // im looking for a way to actually accomplish
// this, where the successView is the apache tiles view.
// I would also need to pass a model map to the view somehow.
}else{
response = errorView.render()
}
writeJsonResponse(httpResponse, /* a Map whose json representation looks like the one I described above. */)
I belive that you want to implement a view class that will wrap the output of a jsp in json. The class in question may be org.springframework.web.servlet.view.tiles2.TilesView.
Another option may be to extend the JSON converter. org.springframework.http.converter.json.MappingJacksonHttpMessageConverter
If you need to render the view using Apache Tiles 2, you must use
org.springframework.web.servlet.view.tiles2.TilesViewResolver
See the example tutorial here: http://krams915.blogspot.com/2010/12/spring-mvc-3-tiles-2-integration.html
If you need to render the response as JSON, you can use the #ResponseBody which requires Jackson in your classpath. See the example here http://krams915.blogspot.com/2011/01/spring-mvc-3-and-jquery-integration.html (The controller returns JSON). You can also see a similar example of the #ResponseBody at http://krams915.blogspot.com/2010/12/jqgrid-and-spring-3-mvc-integration.html