Java REST API Query annotation - java

I am currently trying to add a new feature to my REST API.
Basically I want to add the ability to add query parameters to the end of a path and turn this into a Map of all the query options for example.
my current code allows me to do things like
localhost:8181/cxf/check/
localhost:8181/cxf/check/format
localhost:8181/cxf/check/a/b
localhost:8181/cxf/check/format/a/b
and this will use all the #pathparam as String variables to generate a response.
What I want to do now is add:
localhost:8181/cxf/check/a/b/?x=abc&y=def&z=ghi&...
localhost:8181/cxf/check/format/a/b/?x=abc&y=def&z=ghi&...
and I would then have this generate a Map which can be used along with the pathparam to build the response
x => abc
y => def
z => ghi
... => ...
I was thinking something like this [Below] however the #QueryParam seem to only handle one key value and not a Map of them.
#GET
#Path("/{format}/{part1}/{part2}/{query}")
Response getCheck(#PathParam("format") String format, #PathParam("part1") String part1, #PathParam("part2") String part2, #QueryParam("query") Map<K,V> query);
below is my current interface code.
#Produces(MediaType.APPLICATION_JSON)
public interface RestService {
#GET
#Path("/")
Response getCheck();
#GET
#Path("/{format}")
Response getCheck(#PathParam("format") String format);
#GET
#Path("/{part1}/{part2}")
Response getCheck(#PathParam("part1") String part1,#PathParam("part2") String part2);
#GET
#Path("/{format}/{part1}/{part2}")
Response getCheck(#PathParam("format") String format, #PathParam("part1") String part1, #PathParam("part2") String part2);
}

QueryParam("") myBean allows to get all the query parameters injected. Remove also the last {query} part
#GET
#Path("/{format}/{part1}/{part2}/")
Response getCheck(#PathParam("format") String format, #PathParam("part1") String part1, #PathParam("part2") String part2, #QueryParam("") MyBean myBean);
public class MyBean{
public void setX(String x) {...}
public void setY(String y) {...}
}
You can also not declare parameters and parse the URI. This option could be useful if you can accept non-fixed parameters
#GET
#Path("/{format}/{part1}/{part2}/")
public Response getCheck(#PathParam("format") String format, #PathParam("part1") String part1, #PathParam("part2") String part2, #Context UriInfo uriInfo) {
MultivaluedMap<String, String> params = uriInfo.getQueryParameters();
String x= params.getFirst("x");
String y= params.getFirst("y");
}

Related

RestEasy rest client format query parameters

I need to call a 3rd party rest service from my Java application with a formatted URI:
.../rest/v1/search?filter[first_name]=john&filter[last_name]=smith
The reason for this format is, that there are several query fields (20+) and I can't create a #QueryParam parameter for every fieldname.
#POST
#Path("/rest/v1/search")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
Response searchCustomer(#QueryParam("filter") Map<String, String> filter);
My example with a map results in
/rest/v1/search?filter={first_name=John,+last_name=Smith}
How do I achieve the URI form with square brackets?
You can use #Context UriInfo to get a map of all the query params instead of hardcoding every param
example:
#POST
#Path("/rest/v1/search")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response searchCustomer(#Context UriInfo info){
//here are some different ways you can use the uriinfo
MultivaluedMap<String,String> map = info.getQueryParameters();
String firstName = map.getFirst("filter");
String lastName = map.getFirst("lastName");
}

How to automatically map multipart/form-data input to a bean in Jersey

I have a Jersey REST api that receives inputs as multipart/form-data. The signature is as follows:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/getorders")
public Response getOrders(final FormDataMultiPart request) {
The input parameters in the form are:
clientName
orderType
year
I would like instead to have something like this:
#POST
#Consumes(MediaType.MULTIPART_FORM_DATA)
#Path("/getOrders")
public Response getOrders(final OrderBean order) {
And get all my inputs in a bean like this:
public class OrderBean {
private String clientName;
private int orderType;
private int year;
// Getters and setters
}
Is there a way to do that automatically with Jersey? I know that I can map the fields manually and fill in the bean, but actually I'm looking for an annotation or something like that, that can fill in the bean automatically.
Jersey supports #FormDataParams in a #BeanParam bean. If you were to do this (as you would see in most examples):
#POST
public Response post(#FormDataParam("clientName") String clientName) {}
Then you can also do
class OrderBean {
#FormDataParam("clientName")
private String clientName;
// getter/setters
}
#POST
public Response post(#BeanParam OrderBean order) {}

Requested resource not available jax-rs service

I wrote a jax-rs service using jersey, and the class is as follows,
I want to define the url for the following like this,
One to get the reports by passing parameters
http://localhost:8085/DiginReport/rs/Reports/getreport/{test1:value,test2:value}
One to start the Engine:
http://localhost:8085/DiginReport/rs/Reports/start
#Path("Reports")
public class ReportService {
#GET
#Path("/getreport}/{parameters}")
#Produces(MediaType.TEXT_PLAIN)
public Response getReport(#PathParam("reportName") String reportName,#PathParam("parameters") String parameters) throws KettleXMLException, KettleMissingPluginsException, JSONException, UnknownParamException {
JSONArray jsonarr;
return Response.status(200).entity("ok").build();
}
#GET
#Path("{start}")
#Produces(MediaType.TEXT_PLAIN)
public Response startEngine(#PathParam("start") String command) {
return Response.status(200).entity("ok").build();
}
}
When i type this in url , it says resource not avaliable,
http://localhost:8085/DiginReport/rs/Reports/start
Try the following code.
I would also consider the following things:
Pass Json data as application/json instead of string as path parameter (note that you need to escape.
Use another method than GET to start the engine (e.g. POST), since get should be only used to retrieve data.
Use resources within the URL instead of start or getreports.
#Path("Reports")
public class ReportService {
#GET
#Path("/getreport/{parameters}")
#Produces(MediaType.TEXT_PLAIN)
public Response getReport(#PathParam("parameters") String parameters) throws KettleXMLException, KettleMissingPluginsException, JSONException, UnknownParamException {
JSONArray jsonarr;
return Response.status(200).entity("ok").build();
}
#GET
#Path("/start")
#Produces(MediaType.TEXT_PLAIN)
public Response startEngine() {
return Response.status(200).entity("ok").build();
}
}

Parsing the String params received in POST query

I running a very simple REST web service to receive string params in post query, process them and send back a string response. In order to parse the params from string
param1=testData1&param2=testData2&
I'm using String.split() as under:
#POST
#Produces(MediaType.TEXT_PLAIN)
public String post(String str) {
String[] parts = str.split("&");
String part1 = parts[0]; // param1=testData1
String part2 = parts[1]; // param2=testData2
......do something on these values and return String....
return str;
}
for getting the param values I'll have to split again.....
can someone please suggest a cleaner and elegant solution to get these param values..
Assuming its form parameters, one way that will work for either Jersey 1.x or Jersey 2.x is to inject MultivaluedMap
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String post(MultivaluedMap<String, String> form) {
StringBuilder builder = new StringBuilder();
for (Map.Entry<String, List<String>> params : form.entrySet()) {
for (String key: params.getValue()) {
builder.append("key: ").append(params.getKey()).append("; ")
.append("value: ").append(params.getValue().get(0)).append("\n");
}
}
return builder.toString();
}
If you know ahead of time the name of the form key, you could create a bean.
public class Bean {
#FormParam("key1")
private String value1;
#FormParam("key2")
private String value2;
// getter and setters
}
For Jersey 2.x, you would inject with #BeanParam
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(#BeanParam Bean bean) {
}
For Jersey 1.x you would inject with #InjectParam
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(#InjectParam Bean bean) {
}
Note that the bean injection will work for all the other #XxxParams also, not just #FormParam, for instance #QueryParam, #PathParam. You can mix and match them.
Or if you know the names ahead of time, if you don't need the bean, you can simply declare all the form params in the method signature
#POST
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public Response post(#FormParam("key1") String value1,
#FormParam("key2") String value2) {
}

Mapping methods in Jersey framework

Is it possible to map methods to methods calls to URL path both with ID and with parameters? For instance:
http://localhost/ws/updateUser/32332?name=John?psw=123
public void updateUser(Sting name, String psw){..}
It seems that current #PathParam annotation supports only parameters in path, like:
http://localhost/ws/updateUser/32332/John/123
Try using #QueryParam to capture name and psw parameters:-
public void updateUser(#QueryParam Sting name, #QueryParam String psw) {
..
}
You can combine #QueryParam and #PathParam in one method:
#GET
#Path("/user/{userId}")
public ShortLists getShortListsOfUser(#PathParam("userId") String userId,
#QueryParam("pageNumber") Integer pageNumber,
#QueryParam("pageSize") Integer pageSize,
#Context UriInfo uriInfo) {
/*do something*/
}
This method matches http://localhost/api/user/222?pageNumber=1&pageSize=3
When using a UriBuilder to run this method, mind to use queryParam:
URI uri = getBaseUriBuilder().path("/user/user111").queryParam("pageSize", 2)
.queryParam("pageNumber", 3).build();
This doesn't work: getBaseUriBuilder().path("/user/user111?pageSize=2&pageNumber=3").build();
(because the question mark is replaced with %3F by the builder)

Categories