RestEasy : GET request with multiple dynamic arguments - web-services

The required URL should be something like this :
http://<host>:<port>/path/item?<arguments>
The arguments key and value supposed to be multiple and dynamic, so I cannot use #BeanParam or #QueryParam. Also I can only call this interface without implementation.
My current code is something like this :
public interface RestService {
#GET
#Path("/path/item")
#Produces(MediaType.APPLICATION_JSON)
public JsonNode method(#QueryParam("params") String params);
}
Example of arguments that I want to pass : brand=myBrand&price=myPrice
Is there any way to do something like this ?
My References :
REST Web Service - Dynamic Query Parameters
Passing indefinite Query Parameters with RESTful URL and reading them in RESTEasy

Use UriInfo.getQueryParameters(), as following:
#GET
#Path("/path/item")
#Produces(MediaType.APPLICATION_JSON)
public JsonNode method(#Context UriInfo uriInfo) {
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
...
}
It returns a MultivaluedMap. Then just iterate over it.

Related

Swagger, Endpoints and Pathparameters

TLDR: Multiple Pathparameters and Endpoints with Swagger
What i would like to to is some API Endpoint like this:
/foo/{id}/bar
Now afaik foo or the first node in the path is defining the endpoint and also the resource to aqcuire. Therefore a FooApiServiceImpl is generated.
The generated ProjectsApiService stub looks like this atm:
#GET
#Path("/{id}/bars")
...
public Response getBarsByFooId(#ApiParam(value = "The id of the foo with the bars",required=true ) #PathParam("id") String id)
throws NotFoundException {
return delegate.getBarByFooId(id);
}
Now my wished behaviour would be to GET all the Bar resources that are connectted to the Foo with the given {id}. Kinda like the reverse order. Is this somehow possible?
If this is not possible... then would also like to ask, how can i get url nodes (foo, bar) that are not defined as {xxx} paramaters in brackets?
Something like this:
public Response getBarsByFooId(String foo, String id, String bar)
throws NotFoundException {
return delegate.getBarByFooId(id);
}
To get the paths segments, inject a UriInfo in your resource class or method:
#Context
private UriInfo uriInfo;
And then invoke UriInfo.getPathSegments() from it:
List<PathSegment> segments = uriInfo.getPathSegments();
See the UriInfo.getPathSegments() documentation:
Get the path of the current request relative to the base URI as a list of PathSegment. This method is useful when the path needs to be parsed, particularly when matrix parameters may be present in the path. All sequences of escaped octets in path segments and matrix parameter values are decoded, equivalent to getPathSegments(true).

how pass Employee object in restFul Get method

I am passing an Employee Object Form Client in RestFul webservices Jaxrs2/jersy2
#GET
#Path("{empObj}")
#Produces(MediaType.APPLICATION_XML)
public Response readPK(#PathParam("empObj")Employee empObj) {
//do Some Work
System.out.println(empObj.getName());
return Response.status(Response.Status.OK).entity(result).build();
}
how can achive this object using GET method??
thanx in advance
By using #PathParam on a method parameter / class field you're basically telling JAX-RS runtime to inject path segment (usually string) to your (String) parameter. If you're sending an object (Employee) representation directly via your URI (query param, path param) you should also provide ParamConverterProvider. Beware that this is not possible in some situation and it's not a recommended practice. However, if you're sending the object from client to server in message body, simply remove #PathParam and MessageBodyReader will take care of converting input stream to your type:
#GET
#Path("{empObj}")
#Produces(MediaType.APPLICATION_XML)
public Response readPK(Employee empObj) {
//do Some Work
System.out.println(empObj.getName());
return Response.status(Response.Status.OK).entity(result).build();
}

How to pass a custom object in REST webservice

i'm having problems transfering a custom object to the client. How can i transfer a custom object to the client and receive it back to the webservice? i'm transferring a file by chunks. i want to know how i should write my client. i tried passing it as MediaType.APPLICATION_JSON in client but i get no result meaning it doesn't get passed back to the webservice. Below is a bit of code im working on.
Webservice
#POST
#Path("/fileTransfer")
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
public final TransferInfomation transferInfo(final FileModel file)
{
...
}
...(some code)(lets just say a syso)
FileModel Class
public class FileModel {
private String fileID;
private DataHandler dataHandler;
/**
* Constructor.
*/
public FileModel() {
}
(lets assume setters and getters are made)
(Not sure if the webservice is correct). Still learning REST, i want to know how the client should be.
thanks in advance.
A good way to "marshal" and "unmarshal" "custom objects" (in JSON, XML, etc.) in Jersey is to use JAXB (https://jaxb.java.net/).
To do this you need to create a "jaxb class", with the proper getters and setters (and annotations), e.g.:
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class FileModel{
private String fileID;
private DataHandler dataHandler;
public String getFileID(){
return fileID;
}
public void setFileID(String fileID){
this.fileID = fileID;
}
public DataHandler getDataHandler(){
return dataHandler;
}
public void setDataHandler(DataHandler dataHandler){
this.dataHandler = dataHandler;
}
}
Do not forget to declare the #XmlRootElement. Then you can simply declare and use these objects in your API endpoints (methods):
#POST
#Path("/fileTransfer")
#Consumes({MediaType.APPLICATION_JSON})
#Produces({MediaType.APPLICATION_JSON})
public final FileModel transferInfo(FileModel file)
{
// read file in "FileModel" format
// ... make several operations
// return new FileModel (or another format if you will)
}
This should work. Make sure you follow the data structure defined for FileModel correctly in the client side. See here a example on how to handle that in Jersey: How do I POST a Pojo with Jersey Client without manually convert to JSON? (where JAXB is also used).
Your REST endpoint indicates you want to consume and produce JSON. So the REST client needs to send JSON that can be deserialized into FileModel, and the TransferInfomation returned by transferInfo needs to be serialized into JSON to return to the client.
Typically, Java REST frameworks like RESTEasy, Restlet, Camel, and Spring MVC provide facilities that let you define a JSON serializer/deserializer like Jackson and the mapping rules from JSON <--> Java, and the framework handles the details for you.
So if you use one of these frameworks, you will just have to configure them to use the preferred JSON tool and define the rules.
You can achive this like below:
Server Side:
#PUT
#Consumes(MediaType.APPLICATION_XML)
#Produces(MediaType.APPLICATION_XML)
public String addRecord(CustomClass mCustomClass)
{
///
///
///
return "Added successfully : "+CustomClass.getName();
}// addRecord
Client Side:
public static void main(String[] args)
{
///
///
///
CustomClass mCustomClass = new CustomClass();
Client client = ClientBuilder.newClient();
String strResult = client.target(REST_SERVICE_URL).request(MediaType.APPLICATION_XML).put(Entity.xml(mCustomClass), String.class);
}

Web Service Class of AS in Flex 4

I am trying to receive data from the Web Service and I am getting the Data from Web Service back but it is form of [object Object]. Can anybody help me on this.
Below is the code for my web service:
public class WebServiceAccess
{
private var webService:WebService;
private var serviceOperation:AbstractOperation;
private var myValueObjects:ValueObjects;
private var method:String;
[Bindable]
public var employeeData:ArrayCollection;
[Bindable]
public var employees:ArrayCollection;
public function WebServiceAccess(url:String, method:String)
{
webService = new WebService();
this.method = method;
webService.loadWSDL(url);
webService.addEventListener(LoadEvent.LOAD, ServiceRequest);
}
public function ServiceRequest():void
{
serviceOperation = webService.getOperation(method);
serviceOperation.addEventListener(FaultEvent.FAULT, DisplayError);
serviceOperation.addEventListener(ResultEvent.RESULT, DisplayResult);
serviceOperation.send();
}
public function DisplayError(evt:FaultEvent):void
{
Alert.show(evt.fault.toString());
}
public function DisplayResult(evt:ResultEvent):void
{
employeeData = evt.result as ArrayCollection;
Alert.show(employeeData.toString());
}
}
First of all, evt.result is not an ArrayCollection, it is an Object (unless your SOAP service/WSDL are completely screwed up/malformed XML).
Second, you can't just display an Array or ArrayCollection (or generic Object, even) as a String (even though the .toString() method always seems to imply that) anyway, you have to parse the data to get what you want from it.
Now, the WebService class is nice in that it automatically parses the XML file that a SOAP service returns into a single usable Object. So that is actually the hard part.
What you need to do is call various properties of the object to get the data you need.
So if the XML return (look at your WSDL to see what the return should be, I also highly suggest soapUI) is this:
<employee name="Josh">
<start date="89384938984"/>
<photo url="photo.jpg"/>
</employee>
And you wanted to display "Josh" and the photo, you would do this.
var name:String = e.result.employee.name;
var url:String = e.result.employee.photo.url;
It does get more complicated. If the WSDL allows for multiple nodes with the same name at the same level, it does return an ArrayCollection. Then you have to loop through the array and find the exact item you need.
Just remember: The WSDL is god. Period. If it says there can be multiple "employee" nodes, you have to code accordingly, even if you don't see more than one in your tests. The issue is that there always could be multiple nodes.

Spring 3 MVC Web services: many parameters with same name

I am running into the next problem. I have declared a method in the controller like the next one, to be used as a web service:
#RequestMapping(value = "/" + "prueba" , method = RequestMethod.GET)
public void prueba(ExampleBean pExample1, ExamlpleBean pExample2) {
// Wonderful code here
}
And the class ExampleBean is just, well, a Bean:
public class ExampleBean implements Serializable {
private String id;
private String whatever;
// getters, setters, and more.
}
If the interface were something like that:
#RequestMapping(value = "/" + "prueba" , method = RequestMethod.GET)
public void prueba(ExampleBean pExample1) {
// Wonderful code here
}
Each time I would like to call that web service, I would call the URL in the next way:
http://myWebProject/prueba?id=1&whatever=hola
But... How can I do when I have to give values to both params from the same class? I mean, I can not repeat parameters, so I dont know how to differ between the id from pExample1, and the id from pExample2 when writing the URL.
I mean, also with two parameters from different classes, but with an attribute with the same name. For example, if the second parameter is from the class DifferentExampleBean, which has also an "id" parameter.
Thanks a lot!
PS: I am using StringHttpMessageConverter.
What you would do is to create a parent class which would hold particular field you're interested in then both ExampleBean and ExampleBean1 would extend this parent class and you'd have only one type to be sent in prueba(ParentClass instance1, ParentClass instance2).
Where instance1 would be instance of ExampleBean and instance2 would be instance of ExampleBean2