Jersey Deserialize Post Param with an additional Id - java

I'm just wondering how to modify the following
#POST
#Consumes(MediaType.APPLICATION_JSON)
public Response createObject(Object object) {
...
}
to also allow a path parameter? I was thinking something like
#POST
#Path("{server}")
#Consumes(MediaType.APPLICATION_JSON)
public Response createObjectOnServer(#PathParam("server") String url, Object object) {
...
}
but that either is just wrong or I don't know how the json should be structured.

The second block of code should work, in my project:
#POST
#Path("/{mode}")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.TEXT_PLAIN)
public String renderWidget(#PathParam("mode") String mode,RenderingRequest renderingRequest){
...
}
where 'mode' is a path param and 'RenderingRequest' is a pojo that maps the request body(a json).

Related

How can I determine the order of parameters for x-www-form-urlencoded in Microprofile RestClient?

Use Case
I have following rest client
#RegisterRestClient(configKey = "service")
public interface Service {
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Response request(#QueryParam("instance") String instance, #BeanParam Input input);
}
Input is a class which is a POJO including properties like
public class Input {
#FormParam("title")
public String title;
#FormParam("description")
public String description;
Problem
The request to the API is working fine, but in my case, the order of properties does matter (The reason behind that is something, I cannot answer at the moment, sorry).
So sending title=Test&description=Testdescription is different to description=Testdescription&title=Test.
Other solutions I have tried
With Form instead of POJO: No data is send to the server
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
CustomResponse requestForm(#QueryParam("instance") String instance, #BeanParam Form form);
With Entit<Form>: No data is send to the server
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
CustomResponse requestForm(#QueryParam("instance") String instance, #BeanParam Entity<Form> form);
Assumption
I found out, that org.jboss.resteasy.client.jaxrs.internal.proxy.processors.FormProcessor is using a HashMap internally. I think that is exactly the problem, because there is no guaranteed order. Is my assumption correct?
Question
How can I work around that and always provide the same order for the API using the Microprofile Rest Client.
Workaround
It works with a org.jboss.resteasy.client.jaxrs.ResteasyClient invoking like
Response response = target
.request(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_FORM_URLENCODED)
.post(Entity.form(form));
It's works for me, see:
#POST
#Path(value = "/auth/realms/{realm}")
#Consumes(APPLICATION_FORM_URLENCODED_VALUE)
AuthenticateResponse authenticate(#PathParam("realm") String realm, MultivaluedMap<String,?> params);
Try to use MultivaluedMap

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.

Jersey #Path mapping queries

I have a following jersey class .
#Path("/static1/static2")
public class DoStuff {
#POST
#Path("/static3")
#Consumes(MediaType.APPLICATION_XML)
#Produces("application/xml")
public Response validation(String inputXML){
so my url is localhost/static1/static2/static3 and I get a 200
my goal is to have a URL that is
localhost/static1/{variable}/static2/static3
I tried modifying my class in the following way
#Path("/static1/{variable}/static2")
public class DoStuff {
#POST
#Path("/static3")
#Consumes(MediaType.APPLICATION_XML)
#Produces("application/xml")
public Response validation(String inputXML){
but I keep getting a 404 , what am I doing wrong ?
The problem seems to be with the last path segment static3.{format}. Try the following:
#Path("/static1/{variable}/static2")
public class DoStuff {
#POST
#Path("/{segment3:static3.*}")
#Consumes(MediaType.APPLICATION_XML)
#Produces("application/xml")
public Response validation(#PathParam("variable") String variable,
#PathParam("segment3") String segment3,
String inputXML) {
...............
}

How to bind a JSON data to String in Jersey

My service consumes a Json data. I want to bind this into a String. I tried the following code but unsuccessful:
#POST
#Path("file/save")
#Consumes(MediaType.APPLICATION_JSON)
public JsonResponse save(String content) {
}
I got the error: "Error 400 Can not deserialize instance of java.lang.String out of START_OBJECT token"
How could I fix this problem?
Try creating a container class for your request and then using that class as a parmeter in your resource method. For example:
Class MyRequest {
public String name;
public String address;
}
#POST
#Path("file/save")
#Consumes(MediaType.APPLICATION_JSON)
public JsonResponse save(MyRequest req) {
//req.name, req.address
}
If that doesn't work for you, can you give more details on what you are trying to achieve?

Receiving JSON Response

I am trying to receive a JSON response with Jersey but it is always sending null. Here is my service code:
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML })
#Path("/songs/")
public Room AddSong(#PathParam("json") String Info) {
Song newSong = new newSong();
newSong.addSong(Info);
return newSong;
}
In this case, "Info" is always null. I receive a 200 response from the server so I know the JSON is being sent. The only other thing im not sure is, should I sent JSON in UTF-8?
First of all, you need to use #PathParam correctly. You need to specify {json} in your url. Look at the example
UPD: It's just occurred to me, you in your case you don't need to use #PathParam at all. Just put it away and it should work.
Path parameters take the incoming URL and match parts of the path as a parameter. By including {name} in a #Path annotation, the resource
can later access the matching part of the URI to a path parameter with
the corresponding "name". Path parameters make parts of the request
URL as parameters which can be useful in embedding request parameter
information to a simple URL.
#Path("/books/{bookid}")
public class BookResource {
#GET
public Response invokeWithBookId(#PathParam("bookid") String bookId) {
/* get the info for bookId */
return Response.ok(/* some entity here */).build();
}
#GET
#Path("{language}")
public Response invokeWithBookIdAndLanguage(#PathParam("bookid") String bookId, #PathParam("language") String language) {
/* get the info for bookId */
return Response.ok(/* some entity here */).build();
}
}
In your rest code argument Info takes value from #Path("/songs/{json}") but you have specify #Path("/songs/") so json will always be null
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML })
#Path("/songs/")
public Room AddSong(#PathParam("json") String Info) {
Song newSong = new newSong();
newSong.addSong(Info);
return newSong;
}
You do like this and then everything will be fine :
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML,
MediaType.TEXT_XML })
#Path("/songs/{json}")
public Room AddSong(#PathParam("json") String Info) {
Song newSong = new newSong();
newSong.addSong(Info);
return newSong;
}
For more info refer JAX-RS Parameters
You do not need the #PathParam as the JSON contents should be in the POST body. You have declared the return type to be Room, but are you not trying to return type Song? Assuming this is a simple JSON wrapped string, the contents are in the POST body, and you want Song returned in the 200 OK then you can try this:
#POST
Consumes(MediaType.APPLICATION_JSON)
#Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
#Path("/songs/")
public Song AddSong(String Info) {
Song newSong = new newSong();
newSong.addSong(Info);
return newSong;
}
Optionally, if you want to use a JSON representation of Song in the API, you can replace String Info with Song newSong and then specific Song in the POST body.

Categories

Resources