restful post with additional url parameters? - java

I have a web service which consumes a json request and outputs a json response. I have an issue where the customer needs to send an additional parameter in the url that can't be in the json body. Is there a way to do that?
For example, here is the method of a #WebService that consumes the incoming json request:
#POST
#Path("/bsghandles")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public BsgHandleResponse getBsgHandlesJson(BsgHandleRequest obj) {
HttpServletRequest request = getRequestObject();
return processGetBsgHandleByRateCode("key", obj.getRateCodes(), obj.getCorp(),
obj.getHeadend(), obj.getEquipmentProtocolAiu(), obj.getEquipmentTypeAiu(), request);
}
Notice that "key" is a hard-coded parameter. I need that parameter to be passed to it by the user in the url, but not the json structure. Is there a way to do that?

Just add a parameter annotated with #QueryParam to your method:
#POST
#Path("/bsghandles")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public BsgHandleResponse getBsgHandlesJson(#QueryParam("key") String key,
BsgHandleRequest obj) {
...
}
And consume it using:
POST /api/bsghandles?key=value HTTP/1.1
Content-Type: application/json
Accept: application/json
{
...
}

Yes there is!
You can pass it as a Query Param. For example:
www.yourhost.com/server?key=value
In java, yo can define it like this in your code:
#GET
#Path("/server")
public Response myMethod(#QueryParam("key") String value) { //your RESTFULL code}
So if you call that url as said before, you will have what you want in the variable value.
Hope it helps..
Cheers

Related

Java - How to get http header in interface implementation?

I'm trying to get the x-forwarded-for header from an http request using postman with an interface method. I want to get the IP address in the implementation method, but it either comes in null or blank.
When I test using Postman, if I use #Headerparam it returns null and if I use #RequestHeader it returns blank.
DataService interface class:
#POST
#Path(PATH)
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#WebMethod(operationName="submit")
#ExecutableBy(anonymous = true)
public Response submit(Data data, #RequestHeader(value = "x-forwarded-for") String ipAddr);
DataService implementation:
#Override
public Response submit(Data data, String ipAddr) {
LOG.debug("ip addr from header " + ipAddr);
...
}
Are you sure that "x-forwarded-for" header is there?
#HeaderParam("x-forwarded-for") works for me.

How can I have myObject from Response Object

I have a resource which I would like to test. To do that, I want to extract myObject from javax.ws.rs.core.Response. How can I do that?
The resource looks like this:
#Post
#Path("/test")
public MyObjectClass myresource(){return myObject}
My test:
#Test
public void test(){
Response response = resources.getJersyTest()
.target("/test")
.request()
.post(javax.ws.rs.client.Entity.json(String.class));
assertThat...
}
In general it is not a good idea to return custom object from Rest resource. You may reconsider to use one of standard formats JSON or XML and return a Response instead of MyObjectClass. also you need to take either request or String (or both) as parameter(s) to the resource method to work with what you posts in request.
As example:
#Post
#Path("/test")
#Produces(MediaType.APPLICATION_JSON)
public Response myresource(#Context HttpServletRequest request, String postedBody){
MyObjectClass myObject = new MyObjectClass();
// ... set myObject properties ...
return Response.status(200).entity(myObject).build();
}
Of course for JSON your MyObjectClass must be annotated for JSON...
Then in your response on client side you will have JSON representation of your myObject in the response.getEntity and it can be unmarshalled back to MyObjectClass.
but if you still want to return your custom object you have to create a mechanism to marshal/unmarshal your object on both sides.
Check this answer for it RestEasy - Jax-rs - Sending custom Object in response body
From other hands in the unit test you can call your resource method directly and just cast result.
I found an other solution, just specify the type of the response in the function post:
#Test
public void test(){
MyObjectClass response = resources.getJersyTest()
.target("/test")
.request()
.post(javax.ws.rs.client.Entity.json(String.class), MyObjectClass.class);
assertThat(...
}

How to pass List of hash map as query param in jersey

I tried something like below, M getting error
[[FATAL] No injection source found for a parameter of type public Response
#context UriInfo wont work as i need different data types as query param,like it may be integers and date.Kindly Help.
#GET
#Path("/getdetails")
#Produces({ "application/json", "application/xml" })
public Response getDetails(#QueryParam("field1") String fieldOne,#QueryParam("field2") List<HasMap<String,String>> fieldTwo){
//Processing
}
You will have to use POST and attach the list inside the request body
If the list your passing is json, you should also add the appropriate #Consumes value.
#POST
#Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
#Consumes(MediaType.APPLICATION_JSON)
public void getDetails(List<HasMap<String,String>> listFromClient) {
// do something with your list..
}

Injection of HttpServletRequest in Jersey POST handler

Consider this case:-
I am injecting HttpServletRequest in a Rest Service like
#Context
HttpServletRequest request;
And use it in a method like:-
#GET
#Path("/simple")
public Response handleSimple() {
System.out.println(request.getParameter("myname"));
return Response.status(200).entity("hello.....").build();
}
This works fine but when I try to send it through POST method and replace the #GET by #POST annotation, I get the parameter value null.
Please suggest me where I am mistaking.
You do not need to get your parameters etc out of the request. The JAX-RS impl. handles that for you.
You have to use the parameter annotations to map your parameters to method parameters. Casting converting etc. is done automaticly.
Here your method using three differnt ways to map your parameter:
// As Pathparameter
#POST
#Path("/simple/{myname}")
public Response handleSimple(#PathParam("myname") String myName) {
System.out.println(myName);
return Response.status(200).entity("hello.....").build();
}
// As query parameter
#POST
#Path("/simple")
public Response handleSimple(#QueryParam("myname") String myName) {
System.out.println(myName);
return Response.status(200).entity("hello.....").build();
}
// As form parameter
#POST
#Path("/simple")
public Response handleSimple(#FormParam("myname") String myName) {
System.out.println(myName);
return Response.status(200).entity("hello.....").build();
}
Documentation about JAX-RS Annotations from Jersey you can find here:
https://jersey.java.net/documentation/latest/jaxrs-resources.html

How to make post ajax call with JSON data to Jersey rest service?

I have been through this link. but this did not helped me out.
I am using jersey lib v1.17.1.
My jersey rest service:
#POST
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
#Path("/post1")
public ResponseBean post1(#QueryParam("param1")String param1)
{
return ResponseFactory.createResponse(param1, "TEST", "TEST", null, true);
}
url is: /test/post1
My ajax call:
var d = {"param1":"just a dummy data"};
$.ajax({
type : "POST",
url : "http://localhost:7070/scl/rs/test/post1",
contentType :"application/json; charSet=UTF-8",
data : d,
dataType : "json"
})
.done(function(data){
console.log(data);
})
.fail(function(data){
console.log(data);
});
It hits to my rest service but as param1 I am alway getting null value. The alternate solution is to add JavaBean with #XMLRootElement which will marshal/unmarshal the java object to json and vice versa, but I do not want to use this.
Is there any way to post data and receive it using appropriate annotation like #QueryParam or something like that ?
Please help
Your server-side code should be like this:
#POST
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
#Path("/post1")
public ResponseBean post1(Data param1)
{
return ResponseFactory.createResponse(param1, "TEST", "TEST", null, true);
}
where Data is a (POJO) class annotated with #XmlRootElement and corresponds to the JSON data what your client will send (ie, have a param1 field with getter and setter). The JAX-RS implementation will unmarshall the body of the POST into an instance of Data.
#QueryParam annotation is used ot retrieve the query params in a (usually) GET requests. Query params are the params after the question mark (?). Eg: #QueryParam("start") String start will map be set to 1 when the following request is processed: GET http://foo.com/bar?start=1, but this is not what you're doing in your case, AFAICS.
You can simply take Post dat as a string and then you can parse it using JSONObject.
#POST
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
#Path("/post1")
public Response postStrMsg(String msg) {
String output = "POST:Jersey say : " + msg;
return Response.status(200).entity(output).build();
}
the #XMLRootElement is the way to do that since the json must be unmarshaled before you can use any of its elements.

Categories