Getting whole query string from REST GET service call - java

Is there a way to get the whole query string without it being parsed? As in:
http://localhost:8080/spring-rest/ex/bars?id=100,150&name=abc,efg
I want to get everything following the ? as one string. Yes I will parse it later, but this allows my controller and all follow-on code to be more generic.
So far I've tried using #PathParam, #RequestParam as well as #Context UriInfo with the results following. But I can't seem to get the whole string. This is what I want:
id=100,150&name=abc,efg
Using curl #PathParam using
http://localhost:8080/spring-rest/ex/bars/id=100,150&name=abc,efg
produces id=100,150
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/spring-rest/ex/qstring/{qString}")
public String getStuffAsParam ( #PathParam("qstring") String qString) {
...
}
#RequestParam using
http://localhost:8080/spring-rest/ex/bars?id=100,150&name=abc,efg
gives name not recognized.
http://localhost:8080/spring-rest/ex/bars?id=100,150;name=abc,efg
produces exception.
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/spring-rest/ex/qstring")
public String getStuffAsMapping (#RequestParam (value ="qstring", required = false) String[] qString) {
...
}
EDIT - THE APPROACH BELOW IS WHAT I'D LIKE TO FOCUS ON.
This works almost. It doesn't give me the full query string in the MultivaluedMap. It is only giving me the first string up to the &. I've tried using other characters as the delimiter and still doesn't work. I need to get this string in its undecoded state.
#Context with UriInfo using
http://localhost:8080/spring-rest/ex/bars?id=100,150&name=abc,efg
gives value for queryParams id=[100,150]. Again the name= part was truncated.
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/spring-rest/ex/qstring")
public String getStuffAsMapping (#Context UriInfo query) {
MultivaluedMap<String, String> queryParams = query.getQueryParameters();
...
}
I'm thinking the query string is being decoded which I don't really want. How do I get the whole string?
Any help is greatly appreciated.

You should have a look at the list of supported parameters:
https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-methods
In your case, you can add a HttpServletRequest parameter and call getQueryString():
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/spring-rest/ex/qstring")
public String getStuffAsMapping(HttpServletRequest request) {
String query = request.getQueryString();
...
}
Another way is to use the #Context UriInfo, then call UriInfo.getRequestUri() followed by URI.getQuery():
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/spring-rest/ex/qstring")
public String getStuffAsMapping(#Context UriInfo uriInfo) {
String query = uriInfo.getRequestUri().getQuery();
...
}

I would go with
http://localhost:8080/spring-rest/ex/bars?id=100,150;name=abc,efg
and have this RequestMapping
#RequestMapping(value="/spring-rest/ex/bars")
public String getStuffAsParam(#RequestParam("id")String id, #RequestParam("name")String name)

If you need access to the raw query you need to get it from the request object. Refer to this old question to get access to it. Even though the answer is not accepted it is a well researched response.
Spring 3 MVC accessing HttpRequest from controller
The following code snippet should give the query string once you get access to HttpServletRequest
httpservletrequest.getQueryString()
After I posted this I see #Andreas has posted a similar answer. Accept his answer if the solution helps you.

Related

How can I determine the order of parameters for x-www-form-urlencoded in Microprofile RestClient?

Use Case
I have following rest client
#RegisterRestClient(configKey = "service")
public interface Service {
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Response request(#QueryParam("instance") String instance, #BeanParam Input input);
}
Input is a class which is a POJO including properties like
public class Input {
#FormParam("title")
public String title;
#FormParam("description")
public String description;
Problem
The request to the API is working fine, but in my case, the order of properties does matter (The reason behind that is something, I cannot answer at the moment, sorry).
So sending title=Test&description=Testdescription is different to description=Testdescription&title=Test.
Other solutions I have tried
With Form instead of POJO: No data is send to the server
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
CustomResponse requestForm(#QueryParam("instance") String instance, #BeanParam Form form);
With Entit<Form>: No data is send to the server
#POST
#Path("Invoice")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
CustomResponse requestForm(#QueryParam("instance") String instance, #BeanParam Entity<Form> form);
Assumption
I found out, that org.jboss.resteasy.client.jaxrs.internal.proxy.processors.FormProcessor is using a HashMap internally. I think that is exactly the problem, because there is no guaranteed order. Is my assumption correct?
Question
How can I work around that and always provide the same order for the API using the Microprofile Rest Client.
Workaround
It works with a org.jboss.resteasy.client.jaxrs.ResteasyClient invoking like
Response response = target
.request(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_FORM_URLENCODED)
.post(Entity.form(form));
It's works for me, see:
#POST
#Path(value = "/auth/realms/{realm}")
#Consumes(APPLICATION_FORM_URLENCODED_VALUE)
AuthenticateResponse authenticate(#PathParam("realm") String realm, MultivaluedMap<String,?> params);
Try to use MultivaluedMap

Customize Path to REST params in Pageable

I am using spring to build a REST api with PageAble, to get numberofPages,itens...
first, i did a mapping like this
public ResponseEntity<Data> findByName(#PathVariable(value="name",required=true) String name, #RequestParam(value="page", defaultValue="0") Integer page, #RequestParam(value="qtd", defaultValue="10") Integer linesPerPage, #RequestParam(value="sort", defaultValue="nome") String sort, #RequestParam(value="direction", defaultValue="ASC") String direction)
So in my url i get for example "url?name=erick&direction=asc" but i need to change to "url?name=erick!asc"
How can i change it?
You can do this. Look at page 3 of https://www.ietf.org/rfc/rfc1738.txt
In you case,you should use #RequestParam("name") instead of #PathVariable.Then the request url will be like "url?name=erick&direction=asc"
Spring has three kinds of Annotation.
#PathVariable
This annotation means the variable is on the url.For example:
#RequestMapping("/{id}")
public void pathVariable(#PathVariable("id") Long id){}
The variable was put between the brace at the url.
#RequestParam
This annotation means the variable is part of the quest param,the request url looks like
stackoverflow.com?name=hhhh
For example:
#RequestMapping("/")
public void requestParam(#RequestParam("id")Long id){}
#RequestBody
This annotation means you will receive some data from request body.And some kind of converter,like jackson,will convert it into a properly object.For example:
#PostMapping("/")
public void requestBody(#RequestBody Example example){}

How Spring controller handles parameter implicitly?

I am a newbie on Spring framework and maybe this is an easy question.
I have a link as follows and attempt Spring controller handles the value"201610061023" of this link.However,my code did not work.
I know this value can be attached as a parameter or pathvariable in path but I just curious can I pass this value implicitly?
Thank you very much.
201610061023
#RequestMapping(value = "/Order")
public String requestHandlingMethod(#ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
Spring will not handle the title of the link simply because the title of the link will not be sent by the browser. To send it you can either:
add the value as parameter: 201610061023
add the value as path variable: 201610061023
add a JavaScript that will copy the title onClick into the href or send the generated URL with document.location. This can be automated, but it's pretty uncommon.
Your a-tag is wrong, you need to submit the id, there is no implicit way to submit the link-text (except a lot of java script code)!
201610061023
#RequestMapping(value = "/Order/{orderId}")
public String requestHandlingMethod(#PathVariable("orderId") long orderId, #ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
or
201610061023
#RequestMapping(value = "/Order")
public String requestHandlingMethod(#RequestParam("orderId") long orderId, #ModelAttribute("test") String name, HttpServletRequest request) {
return "nextpage";
}
See #RequestParam vs #PathVariable for the difference between this two approaches

Match empty path parameters in REST

I have a service in rest that looks like:
#GET
#Path("get-policy/{policyNumber}/{endorsement}/{type}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber,
#PathParam("endorsement")String endorsement,
#PathParam("type")String type){
...
}
And i want to know if there is a way that i can accept every parameter as null value if they are not sent, so if somene makes a call to my service without the params or with not all the params still can match the definition of my service.
Examples:
http://localhost:8080/service/policy/get-policy/
or this:
http://localhost:8080/service/policy/get-policy/5568
or this:
http://localhost:8080/service/policy/get-policy/5568/4
Im well aware that i can define a regex expression like in this answer, but in that case there was only 1 path param defined, what if i have more than one?
That didnt work for me but maybe im doing something wrong, i tried this with no success:
#GET
#Path("get-policy/{policyNumber: .*}/{endorsement: .*}/{type: .*}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber,
#PathParam("endorsement")String endorsement,
#PathParam("type")String type){
...
}
is the only way to achive this trough a POST? Im using Jersey btw!
You have to create a complete use case scenario for this and call a general method every time if you dont want to write code multiple times.
Say: For an instance use only one parameter passed, then 2 and then all, and none
#GET
#Path("get-policy/{policyNumber: .*}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber)
{
doSomething(policyNumber, "", "");
}
#GET
#Path("get-policy/{policyNumber: .*}/{endorsement: .*}")
#Produces(MediaType.APPLICATION_XML)
public String getPolicyIndividual(
#PathParam("policyNumber")String policyNumber,
#PathParam("endorsement")String endorsement)
{
doSomething(policyNumber,endorsement, "");
}

How to pass argument to a REST method

I have created simple rest service #GET and takes 2 parameters username and password.
I m trying to search how to pass parameters through rest service client and how to get it using the method. I am unable to get the exact answer I want.
How can I pass parameters and how to use that in my webservice?
I don't know what framework you are using but if you use Spring, you can do it like this:
#Controller
public class SampleController {
#RequestMapping(value="/test/{name}/{password}", method = RequestMethod.GET)
public String doTest(#PathVariable String name,#PathVariable String password, ModelMap model) {
System.out.println("REST paras name:"+name+",password:"+password);
return "samplePage";
}
}
then ,url path like [/test/{name}/info] [/test/{name}/info.*] [/test/{name}/info/]
will pass to this method!
You should look on something like:
#HeaderParam or #PathParam
in Jersey it looks like:
#Get
#Path("/mywebservice")
public Response myWebService(#HeaderParam String username,
#HeaderParam String password)
{
...
}
but you should remember that this way of sending/receiving username and password isn't too secure ;)

Categories

Resources