Submit JSON data as request body in an Apache CXF REST Service - java

I know this has been asked before, but going through multiple answers did not help me solve my issue. So here it is: I'm a newbie trying to create a REST service using Apache CXF. I'm trying to write a POST method and send the data as JSON in the request body(using POSTMAN in Google Chrome to do this).
My interface looks something like this:
#Path("/")
#Produces("application/json")
public interface MyService{
#POST
#Path("/addNote/{id}")
#Consumes("application/json")
NoteResponse addNote(#PathParam("id") Long id, #QueryParam("note")Note note);
// OTHER #GET METHODS THAT WORK WELL
}
My implmentation:
#WebService(name = "testservice")
public class MyServiceImpl implements MyService{
#Override
public NoteResponse addNote(Long id, Note note){
// SOME IMPLEMENTATION
}
// OTHER #GET METHOD IMPLEMENTATIONS THAT WORK
}
I've read in some answers that I do not need the #QueryParam on my note annotation, instead just put and #XMLRootElement on my Note class, but doing that and trying going on localhost:8080/rest/addNote/1 will NOT call my addNote method.
The problem I am facing now is that the note parameter comes null.
Here's the JSON I've sent via POSTMAN:
{
"note":{
"id": 4958,
"anotherId": 7886,
"comment": "salut",
"mail": "mail#mail.com",
"gregorianDate": "01-01-2016",
"type": "INFO"
}
}

Please try changing your interface definition of API addNote to this:
NoteResponse addNote(#PathParam("id") Long id, Note note);
And send this JSON string via POSTMAN:
{
"id": 4958,
"anotherId": 7886,
"comment": "salut",
"mail": "mail#mail.com",
"gregorianDate": "01-01-2016",
"type": "INFO"
}
This should work.

Related

SpringBoot deserialize a JSON array in Java using Jackson

I am currently writing a SpringBoot application that retrieves a JSON array from an external API. The part of the JSON I need looks like:
{
"users": [
"id": 110,
"name": "john"
]
}
In my Controller I am doing the following:
ResponseEntity<Users> response = restTemplate
.exchange(url, headers, Users.class);
return response
I then have a Users class that looks like:
#JsonProperty("id")
public String id;
#JsonProperty("name")
public string name;
How can I access the information inside the JSON array?
Thanks in advance.
Instead of loading into a POJO based on your return type you need to accept list of Users.
You cannot accept List of user class in ResponseEntity you need to first cast into object class.
ResponseEntity<Object> response = restTemplate .exchange(url, headers, Object.class);
Then you need to convert it into list of users.
List<Users> usersList = (List<Users>) response.getBody();
The JSON you posted above is not correct. It needs to be:
{
"users": [
{
"id": 110,
"name": "john"
}
]
}
and whatever object is used needs a list of Users.
The other thing is you restTemplate call is wrong, you are expecting the call to return ResponseEntity<Opportunities> class yet when in your restTemplate you are giving it the User class and that will return ResponseEntity<User> instead

How to pass JSON String as Request Parameter to other service

I have two services running. One service will generate a JSON response. Below is the generated Json response.
{ "appliedCostMatrix": { "regionCostMatrix": "","costAreaCode": "", "costBoundaryId": 0, "isActive": "Y", "costRegionCode": "", "regionTypeCode": 3, "regionTypeDescription": "California", "solveTypeDescription": "Coaxial" }, "networkSolveRegion": "CALIFORNIA"}
Now To save the response i have to call other service and have to pass this Json as string.
http://localhost:8080/putSolvedRoutes?responseJson=(Above Mentioned JSON string)
Can any one tell me the best way to achieve this.
Thanks in Advance.
What have you tried? Your tags imply this is a Spring question so within the context of Spring boot, set up your controller (that receives the second request you send with the json data) as follows:
#RestController
public class YourRestController {
#RequestMapping(value="/your/endpoint", method=RequestMethod.POST)
public ResponseEntity<String> someMethod(#RequestBody YourDTO data) {
// business logic here
}
}
and send the request with whatever client you are using, in post.
If the client is also Spring, have a look at the documentation for one possible way to solve the problem. A brief example:
#Service
public class YourService {
private final RestTemplate rt;
public YourService(RestTemplateBuilder rtb) {
this.rt = rtb.build();
}
public YourDTO someRestCall(String param) {
return this.rt.postForObject("/your/endpoint", YourDTO.class, param);
}
}

How to print null values in the JSON rest webservice response in Java?

I have the below method in my rest service test class.
#Override
#JsonInclude(JsonInclude.Include.ALWAYS)
#GET
#Produces("application/json")
#Path("/list")
public List<XXX> findAll() {
System.out.println("inside wrapper class findall");
return super.findAll();
}
The JSON response does not print any null value fields in the response.
e.g.- It prints {"key":"1","value:2"} instead of {"key":1, "value":2, "dvalue":null}
I tried using #JsonInclude(JsonInclude.Include.ALWAYS) but that is not working either. I am using jackson-annotations-2.0.4 jar.
Please let me know what might I be missing.

JAX-RS unmarshal JSON sub property to hash map

I have a REST service endpoint that accepts JSON in the following format:
{
"name": "example",
"properties": {
"key1": "val1",
"key2": "val2"
}
}
Then I have this class
class Document {
private String name;
private Map<String, String> properties;
... setters/getters
}
And my REST service method
logger = Logger.getLogger("logger");
#POST
#Consumes(MediaType.APPLICATION_JSON)
Response addDocument(Document document) {
logger.info(document);
return Response.ok(200).build();
}
But whenever I post the JSON above it's not unmarshalling my properties. It is always null. The name property is mapped correctly..
I would gladly accept any help/clues.Thanks!
EDIT: I did not mention that I am using glassfish 4.1 and what comes with it. I don't have any lib dependency for marshal/unmarshal.
I just added Gson and created custom entity provider for JSON. It works now as expected, but I would've been more glad to not handle it myself but let the container do it with whatever is configured for JAXB.
Your JSON, the Java class the JSON will be parsed into and your JAX-RS resource method look fine:
{
"name": "example",
"properties": {
"key1": "val1",
"key2": "val2"
}
}
public class Document {
private String name;
private Map<String, String> properties;
// Getters and setters omitted
}
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response addDocument(Document document) {
...
return Response.ok(200).build();
}
Instead of using Gson as you mentioned in your answer, you could consider using a JSON provider which integrates with Jersey. Jackson is a good choice and Maps should work fine.
For details on how to use Jackson with Jersey, refer to this answer.

Access JSON data in PUT request - Jersey Dropwizard

I am using jersey dropwizard and trying to update a record as follow:
#PUT
#Path("api/v1/tasks/{taskId}")
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
#Produces(MediaType.APPLICATION_JSON)
#UnitOfWork
public Task updateMyTask(#PathParam("taskId") long taskId, #QueryParam("description") String description) {
...
System.out.println(description); // Always `null`
...
}
My request data:
{ "description": "dummy description" }
My problem is that I am unable to access the data coming in PUT request. It always shows as null. I already have tried this with #FormParam, no luck.
EDIT:
After Sam's response, I have made suggested changes and getting following exceptions:
#PUT
#Path("api/v1/tasks/{taskId}")
#Consumes(MediaType.APPLICATION_JSON)
#UnitOfWork
public Task updateTask(Task task, #PathParam("taskId") long taskId) {
...
System.out.println(task.getDescription());
...
}
Returning error:
{
"code": 400
"message": "Unable to process JSON"
}
The data isn't a #FormParam or a #QueryParam, it's just the body of the request, so it doesn't need any annotations.
What it does need is a POJO that describes the format of the JSON data you're providing. For a simple String value that could look like this:
class Task {
String description;
... // other fields
}
Your #Consumes annotation is confused, too. You've annotated the method as #Consumes(MediaType.APPLICATION_FORM_URLENCODED), but you're trying to send it JSON data. Declare your method as:
#Consumes(MediaType.APPLICATION_JSON)
...
public Task updateMyTask(Task task, #PathParam("taskId") long taskId) {
System.out.println(task.description); // not null any more
}
You'll need to make sure you have JSON mapping enabled in Jersey.

Categories

Resources