how to retrieve JSON request into method using rest java? - java

i am using simple java and jersey for rest. below is method. from postman i am sending json request and want to retrieve this data into method without declaring POJO class. but unable to retrieve.
#Path("{entity}/markLabel")
#PUT
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response markLabel()
throws Exception {
}
i want to retrieve request json parameter(fileType,groupId,sourceId) into method this request json parameter.
this is header part
can someone help me in this?

Why would you want to retrieve the request parameters or headers in another method?
One method handles one request, thats the way, but if you want to isolate some part of the functionality into seperate method you can call the other method inside the request handling method.
#Path("{entity}/markLabel")
#PUT
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response markLabel(ReqObject String reqBody) throws Exception {
//////do something
someOtherMethod(reqBody);
//////do something
}
class ReqObject{
String fileType;
String groupId;
String sourceId;
//getters and setters
}

Related

Jenkins - How to bind a url to a java method which returns json string?

I am practicing developing a jenkins plugin. And I want to send an ajax request with some cookies in front end for back end processing and then receive some json response to continue processing my front end logic. Is it possible for me to bind a url to a back end java method with parameters like StaplerRequest and StaplerResponse and simply get the returned json from the method as my response?
After searching around, I found a site introducing how Jenkins stapler works. Particularly, the action method might be helpful for me
According the document I found:
Action Method
If url is of the form "/fooBar/...." and node has a public "action" method named doFooBar(...), then this method is invoked.
to retrieve a json response,
In front end,
$.ajax({
url: "./someUrl/",
}).done(doSomethingOnData(data));
In back end, define a corresponding action method:
public void doSomeUrl(StaplerRequest request, StaplerResponse response) {
Cookie[] myCookies = request.getCookie();
doSometingBasedOnCookies(myCookies);
response.setStatus(200);
response.setContentType("application/json;charset=UTF-8");
String myJson = getJson();
response.getWriter().print(myJson);
}
Yes, you can create simple Rest Method which consume nothing but response back in JSON, something like this
#POST
#Path("/somemethod")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public CommonResponseBean somemethod() {
return response(); // return CommonResponseBean, this will automatically converted into json using jackson
}

Jersey 2.x - Conflicting route priority of PUT and GET

I'm working with Dropwizard, which uses Jersey internally. I have two methods on a controller:
PUT /garbage/[id1,id2,...idN] is intended to take a path parameter that's a list of numeric IDs representing resources to be updated. I'm using a regex-based PathParam here. I've fudged the regex in this example because I don't think it matters, but the point is that a single numeric ID should match the regex.
GET /garbage/[id] fetches data about a single piece of garbage.
Jersey seems to get confused, despite the difference in method. When I query with something like
curl localhost:8080/garbage/1
Jersey gives me a 405 error. If I take the PUT out of the picture (for example, sabotage the path param regex, or remove it entirely), the GET endpoint works fine.
I assume there is some detail in JAX-RS 3.7.2 I'm missing that explains why this should be the case, but I can't figure out what it is.
Here's the code:
#Path("/garbage")
#Produces(MediaType.APPLICATION_JSON)
public class GarbageController {
private static final Logger LOG = LoggerFactory.getLogger(GarbageController.class);
#PUT
#Path("/{params: [\\d,]+}")
#Consumes(MediaType.APPLICATION_JSON)
#Timed
public Response updateGarbage(#PathParam("params") List<PathSegment> params) {
LOG.warn("updateGarbage");
return Response.status(Response.Status.OK).build();
}
#GET
#Path("/{garbageId}")
public Response getGarbageById(#PathParam("garbageId") long garbageId) {
LOG.warn("getGarbage");
return Response.status(Response.Status.OK).build();
}
}
The main purpose of #PathSegment is to handle fragments of the URI which is useful to retrieve Matrix Parameters. For example the method below:
#GET
#Path("/book/{id}")
public String getBook(#PathParam("id") PathSegment id) {...}
Should be able to handle this request:
GET /book;name=EJB 3.0;author=Bill Burke
Because the #PathSegment intercepts the entire URL fragment the GET method seems to be ignored. You can handle the comma-separated IDs on the PUT request with a simple String split:
#PUT
#Path("/{params}")
#Consumes(MediaType.APPLICATION_JSON)
#Timed
public Response updateGarbage(#PathParam("params") String params) {
LOG.warn("updateGarbage ", params.split(","));
return Response.status(Response.Status.OK).build();
}
You can also change the request format to query parameters or implement a Converter/Provider to handle a custom object. All of them should solve the GET not implemented issue.
I believe this is not a case of route priorities between GET and PUT but instead this is related to the #Consumes annotation which cannot be used on a GET request. Either DW is ignoring this endpoint or is converting it into the default POST method, which would explain the 405 response for the GET request.
I figured this out, although I have not traced far enough into Jersey to know why it works. The solution is to rewrite the #GET method to use the same regex syntax as the #PUT. Jersey will handle the type conversion in the method signature, with the note that it will return a 404 if the type conversion fails (ie, GET /garbage/xyz).
#PUT
#Path("/{params: .+}")
#Consumes(MediaType.APPLICATION_JSON)
public Response updateGarbage(#PathParam("params") List<PathSegment> params) {
LOG.warn("updateGarbage");
return Response.status(Response.Status.OK).build();
}
#GET
#Path("/{params: .+}")
public Response getGarbageById(#PathParam("params") long garbageId) {
LOG.warn("getGarbage {}", garbageId);
return Response.status(Response.Status.OK).build();
}

Jersey server, rest api : How to remove the code and type from the response body?

I'm trying to create a Rest Api using Jax-rs Jersey from a base code generated by swagger.
The specifications are for exemple for a specific Request :
Code : 200
Description : User token for login
Schema : String
My problem is that the generated code use the class :javax.ws.rs.core.Response that should not be extended according to the documentation.
I'm using this kind of code to build the response :
return Response.ok().entity(new ApiResponseMessage(ApiResponseMessage.OK,apiToken)).build();
The response generated looks like that :
{"code":4,"type":"ok","message":"uHN2cE7REfZz1pD17ITa"}
When i only want to have :"uHN2cE7REfZz1pD17ITa" in the body. Is that possible using Jersey ? Or is this format part of the jax-rs specifications ?
Thank you.
ApiResponseMessage from Swagger does not extend Response from JAX-RS. Check the code and you will see that ApiResponseMessage is just a POJO. That is, the piece of code you posted in your question is just fine.
If you only need the token, you can use:
return Response.ok(apiToken).build();
The following gives you the same result:
return Response.ok().entity(apiToken).build();
Since your resource method will produce just a piece of text (not a valid JSON unless the piece of text is wrapped into quotes), the most suitable media type for the response would be text/plain. It could be achieved by either annotating the resource method with #Produces(MediaType.TEXT_PLAIN) or setting the media type in the response, as following:
#GET
#Produces(MediaType.TEXT_PLAIN)
public Response getToken() {
String apiToken = ...
return Response.ok(apiToken).build();
}
#GET
public Response getToken() {
String apiToken = ...
return Response.ok(apiToken, MediaType.TEXT_PLAIN).build();
}
Alternatively you also could make your method return just a String:
#GET
#Produces(MediaType.TEXT_PLAIN)
public String getToken() {
String apiToken = ...
return apiToken;
}
JAX-RS does not require Request or Response in specific format for text,json, xml, or html fallowing a schema . But They all have to be well formated in according to their specifications.
You can send text response like this in jersey
like this
return Response.ok().entity("uHN2cE7REfZz1pD17ITa").build();
I am new to swagger myself So i don't know if the Response in question can be changed or not . But There is no restriction from jersey side

Adding POST Method within Jersey Class

Let's say I have a Jersey JAX-RS api end-point for handling http://<some_path>/foo. Ignore the ....
#Path("foo")
public class FooResource
#GET
#Produces("application/json")
public response getMethod(...)
I want to create POST end-point for foo/{id}/bar, where id is a path parameter and there's a body associated with the HTTP POST.
Example: HTTP POST foo/1/bar with body: { data : "...." }.
How can I add this POST method within the FooResource class? I tried an inner class, but it didn't work when I tested with Postman.
#POST
#Path("{id}/bar")
#Produces("application/json")
public response myPostMethod(...)
You can have path at method level. This will have your post method accessible via /foo/{id}/bar

How to use two web methods for two different operations using Restful webservices?

I am using Jersey Restful webservices. I have below web method to get the results.
#Path("/persons")
public class PersonWS {
private final static Logger logger = LoggerFactory.getLogger(PersonWS.class);
#Autowired
private PersonService personService;
#GET
#Path("/{id}")
#Produces({MediaType.APPLICATION_XML})
public Person fetchPerson(#PathParam("id") Integer id) {
return personService.fetchPerson(id);
}
#DELETE
#Path("/{id}")
public void deletePerson(#PathParam("id") Integer id) {
return personService.deletePerson(id);
}
}
In above Jersey RESTful webservice, i have two web methods one for get and one more for delete with same number of parameters. In above case will there be any ambiguity? If not what should be the URIs for both of the methods? Thanks!
Thanks!
Jersey decides which method to call based on the HTTP method specified in the request. If you use multiple methods with the same HTTP method like GET, then the choice is made by more Annotations like Consumes or Produces etc.
BTW: If you use the URI /persons/{id} for all endpoints, then you can annotate your class with #Path("/persons/{id}") instead of annotating every method with this sub-URI.
There is no ambiguity as the HTTP Method is different (GET vs DELETE).
The same url would also be used to update the object, using the HTTP method PUT
No ambiguity since the HTTP methods used are different i.e GET and DELETE
And the urls will be same as the param required is "id" for both
IN Jersey client program use GET http method for fetching person info, Use DELETE http method for deleting the person.

Categories