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)
Related
#RequestMapping("/accounts")
public class controller {
#GetMapping("/get/{id}")
public final ResponseEntity<?> getHandler(){
}
#PostMapping(value = "/create")
public final ResponseEntity<?> createHandler(){
/*
trying to use some spring library methods to get the url string of
'/accounts/get/{id}' instead of manually hard coding it
*/
}
}
This is the mock code, now I am in createHandler, after finishing creating something, then I want to return a header including an URL string, but I don't want to manually concat this URL string ('/accounts/get/{id}') which is the end point of method getHandler(), so I am wondering if there is a method to use to achieve that? I know request.getRequestURI(), but that is only for the URI in the current context.
More explanation: if there is some library or framework with the implementation of route:
Routes.Accounts.get(1234)
which return the URL for the accounts get
/api/accounts/1234
The idea is, that you don't need to specify get or create (verbs are a big no-no in REST).
Imagine this:
#RequestMapping("/accounts")
public class controller {
#GetMapping("/{id}")
public final ResponseEntity<?> getHandler(#PathVariable("id") String id) {
//just to illustrate
return complicatedHandlerCalculation(id).asResponse();
}
#PostMapping
public final ResponseEntity<?> createHandler() {
//return a 204 Response, containing the URI from getHandler, with {id} resolved to the id from your database (or wherever).
}
}
This would be accessible like HTTP-GET: /api/accounts/1 and HTTP-POST: /api/accounts, the latter would return an URI for /api/accounts/2 (what can be gotten with HTTP-GET or updated/modified with HTTP-PUT)
To resolve this URI, you could use reflection and evaluate the annotations on the corresponding class/methods like Jersey does.
A Spring equivalent could be:
// Controller requestMapping
String controllerMapping = this.getClass().getAnnotation(RequestMapping.class).value()[0];
and
//Method requestMapping
String methodMapping = new Object(){}.getClass().getEnclosingMethod().getAnnotation(GetMapping.class).value()[0];
taken from How do i get the requestmapping value in the controller?
I have service(WildFly 10.1) which looks like that :
#GET
#Path("/retrieve")
public Response getModels(#BeanParam ModelQueryParams queryParams) {
return getModels();
}
With ModelQueryParams:
public class ModelQueryParams{
#QueryParam("offset")
private Long offset;
#QueryParam("limit")
private Long limit;
}
So the user can call endpoint like:
/retrieve?offset=100&limit=4
But how can I validate case when user pass into the query wrong parameter?
/retrieve?offset=100&limit=4&WRONG_PARAMETER=55
Is there the way to validate it somehow?
if you don't have any field or method parameters annotated with #QueryParam, then those extra parameters are not your problem and it's best to deal with only parameters you expect for your resource.
If you still need access to all query parameters, then inject UriInfo with #Context and call it's getQueryParameters() to get a MultivaluedMap of request parameters
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");
}
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
In my Jersey resource i have:
#GET
#Path("/{dataType}/{dataSet}")
public Response search(
#PathParam("dataType") String dataType,
#PathParam("dataSet") String dataSet){
...
}
Instead of strings i want to use my own classes:
#GET
#Path("/{dataType}/{dataSet}")
public Response search(
#PathParam("dataType") DataType dataType,
#PathParam("dataSet") DataSet dataSet){
...
}
However DataSet is dependent on DataType(DataSet uses DataType in it's constructor). Is there a way to do this with Jersey?
You can either use Jersey's built-in transformation using a static fromString() method (see the Jersey documentation), or use a custom provider to handle the path segments. For the latter, you will need a class something like this:
public class MyProvider extends PerRequestTypeInjectableProvider<Context, DataType> {
#Context UriInfo uriInfo;
public Injectable<DataType> getInjectable(ComponentContext componentCtx, Context ctx) {
uri.getPathSegments();
...
}
}