#QueryParam Retrieve Form Parameters - java

I have query parameters which are being sent from browser in the following format
sort[0][field]:prodId
sort[0][dir]:asc
How can I retrieve the above parameters in server using #QueryParam?
From chrome console
take:5
skip:0
page:1
pageSize:5
sort[0][field]:prodId
sort[0][dir]:asc

#QueryParam should be obtained from a Query String that is appended to the end of the request URL. Something like
http://host:port/app/something?key1=value2&key2=value2
You could then get value1 and value2 with
#QueryParam("key1") String value1,
#QueryParam("key2") String value2
Now in the title of your post, you use the word "Form". If this is form data you are trying to submit, you should consider some things. When putting the form data in the query String, this is usually done with data that is not sensitive, and used mainly for GET request, where the parameter values are used to help filter in getting the resource. If this is sensitive data that should be stored on the server, you generally want to POST the data as form data in the body of the request, as seen in the answer from your previous post
UPDATE
If you don't know the key names, which is required to use #QueryParam, you can obtain the entire query string from an injected UriInfo. Something like
#GET
#Path("/path/to/resource")
public Response getKendo( #Context UriInfo uriInfo) {
MultivaluedMap params = uriInfo.getQueryParameters();
StringBuilder builder = new StringBuilder();
for (Object key : params.keySet()) {
builder.append(key).append(":")
.append(params.getFirst(key)).append("\n");
}
return Response.ok(builder.toString()).build();
}
getQueryParameters() will return all the keys and values in MultivalueMap
Alternatively, if you know the keys, which are shown in the URL you posted in the comment
test.jsp?take=5&skip=0&page=1&pageSize=5&sort%5B0%5D%5Bfield%5D=prodId&sort%5B0%5D%5Bdir%5D=asc
then you cause just use all those key for the QueryParam, i.e.
public Response getKendo(#QueryParam("take") int take,
#QueryParam("skip") int skip,
#QueryParam("page") int page,
#QueryParam("sort[0][field]") String field...) {
}
All this crazy stuff sort%5B0%5D%5Bfield%5D is just how URL are encoded with special character, but JAX-RS will convert back to their rightful form, ie "sort[0][field]"

Related

HttpServletRequest get query parameters from a GET call

I'm trying to get the query parameter client_id from a GET call with a url like this:
https://example.com?client_id=aclient-id&param2=value2&param3=value3
I'm getting a null value for clientId when I try to get the query parameter, any ideas why this is happening?
HttpServletRequest httpRequest = (HttpServletRequest) request;
final String clientId = httpRequest.getParameter("client_id");
The other calls like http.getRequestURI() and http.getMethod return the expected values.
Please check what the string value of the client id that is actually being sent to the server. In your example you say clientId in your code you're looking for client_id, while they make semantic sense to humans, those are different values to a computer.
You can also take a peek at all the parameter values in your HttpServletRequest:
httpRequest.getParameterMap()
.entrySet()
.stream()
.forEach(System.out::println);

How to parse a 2d array query parameter with Java's Jersey framework

Given the following request:
GET /schools?primaryKey=1&secondaryKey=11
&array2d[0][key]=student_number&array2d[0][value]=123456
&array2d[1][name]=student_name&array2d[1][value]=john
&searchField=school_name
The web API call can send any number of array2d name-value pairs.
I need to create a GET web handler to process the request and extract the query parameters into relevant data structures.
Given the data structures, I'd like to query the database and return a response.
How can I deserialize a complex input like this with Jersey?
I have tried the following code:
#GET
#Path("/{primaryKey}{secondaryKey : (/\\d+)?}/{searchField}")
#Produces("application/json")
public String getInputs(
#PathParam("primaryKey ") String projectid,
#PathParam("secondaryKey ") String classid,
#PathParam("searchField") String searchField)
throws Exception { #some code here }

Path on Client side of RESTful Web Service

Ok so this is the code on the server side i just have question on how is the path gonna be defined on the client's side.
This is the method on the server
#Path("{index}/{product}/{amount}")
#PUT
#Produces("text/plain")
public String editTable (#PathParam("index") Integer index, #PathParam("product") String product, #PathParam("amount") Integer amount)
{...}
Now on the client side
{url = new URL( "http://localhost:8080/OrderService/service/tableservice/"+num+"/"+product+"/"+amount);
.....}
/"+num+"/"+product+"/"+amount);
Is this the correct syntax??
Also can the num and amount be integers while the product a string or am i gonna have a problem with it?
You will have problems if the product name has 'unsafe' URL characters in it. Which will probably be the case. To get around that you could URL encode the name before appending it to the URL.
But I think you should rethink your PATH definition in the first place. A good resource endpoint should uniquely identify it. But in your case you are including an amount field in the URL! Which means depending on who is ordering the product the resource URL is changing:
Customer A orders 2 Furbies:
/OrderService/service/tableservice/9/Furbies/2
Customer B orders 1 Furbie
/OrderService/service/tableservice/9/Furbies/1
But in both cases the customers are trying to order the same thing - a Furbie! This is not RESTful. Instead you should define a unique resource endpoint, then send the additional order information as appended data. So for example:
public class Order {
private Integer productId;
private Integer amount;
}
#PUT
#Path("/{productId}/orders")
#Produces("text/plain")
public String updateOrder(#PathParam("productId"), Order order) { ... }
You will notice I removed the index field as well, you can add that back in if absolutely required. You will notice I also added tacked an orders suffix to the end of the URL. To indicate that you are PUT'ing an updated representation for an order made for a product.
If you are mapping any #QueryParam to Integer, ensure that you are taking care of the following:
From the link on Oracle docs:
If a query parameter exists in the query component of the request URI, then the value will be extracted and parsed as a 32–bit signed integer and assigned to the method parameter. If the value cannot be parsed as a 32–bit signed integer, then an HTTP 400 (Client Error) response is returned.
Just to be safe, have your index and amount as String. Parse them to Integer within your service and handle NumberFormatException instead of HTTP 400.

HttpServletRequest - Get query string parameters, no form data

In HttpServletRequest, getParameterMap returns a Map of all query string parameters and post data parameters.
Is there a way to get a Map of ONLY query string parameters? I'm trying to avoid using getQueryString and parsing out the values.
You can use request.getQueryString(),if the query string is like
username=james&password=pwd
To get name you can do this
request.getParameter("username");
Contrary to what cularis said there can be both in the parameter map.
The best way I see is to proxy the parameterMap and for each parameter retrieval check if queryString contains "&?<parameterName>=".
Note that parameterName needs to be URL encoded before this check can be made, as Qerub pointed out.
That saves you the parsing and still gives you only URL parameters.
The servlet API lacks this feature because it was created in a time when many believed that the query string and the message body was just two different ways of sending parameters, not realizing that the purposes of the parameters are fundamentally different.
The query string parameters ?foo=bar are a part of the URL because they are involved in identifying a resource (which could be a collection of many resources), like "all persons aged 42":
GET /persons?age=42
The message body parameters in POST or PUT are there to express a modification to the target resource(s). Fx setting a value to the attribute "hair":
PUT /persons?age=42
hair=grey
So it is definitely RESTful to use both query parameters and body parameters at the same time, separated so that you can use them for different purposes. The feature is definitely missing in the Java servlet API.
As the other answers state there is no way getting query string parameters using servlet api.
So, I think the best way to get query parameters is parsing the query string yourself. ( It is more complicated iterating over parameters and checking if query string contains the parameter)
I wrote below code to get query string parameters. Using apache StringUtils and ArrayUtils which supports CSV separated query param values as well.
Example: username=james&username=smith&password=pwd1,pwd2 will return
password : [pwd1, pwd2] (length = 2)
username : [james, smith] (length = 2)
public static Map<String, String[]> getQueryParameters(HttpServletRequest request) throws UnsupportedEncodingException {
Map<String, String[]> queryParameters = new HashMap<>();
String queryString = request.getQueryString();
if (StringUtils.isNotEmpty(queryString)) {
queryString = URLDecoder.decode(queryString, StandardCharsets.UTF_8.toString());
String[] parameters = queryString.split("&");
for (String parameter : parameters) {
String[] keyValuePair = parameter.split("=");
String[] values = queryParameters.get(keyValuePair[0]);
//length is one if no value is available.
values = keyValuePair.length == 1 ? ArrayUtils.add(values, "") :
ArrayUtils.addAll(values, keyValuePair[1].split(",")); //handles CSV separated query param values.
queryParameters.put(keyValuePair[0], values);
}
}
return queryParameters;
}
Java 8
return Collections.list(httpServletRequest.getParameterNames())
.stream()
.collect(Collectors.toMap(parameterName -> parameterName, httpServletRequest::getParameterValues));
I am afraid there is no way to get the query string parameters parsed separately from the post parameters. BTW the fact that such API absent may mean that probably you should check your design. Why are you using query string when sending POST? If you really want to send more data into URL use REST-like convention, e.g. instead of sending
http://mycompany.com/myapp/myservlet?first=11&second=22
say:
http://mycompany.com/myapp/myservlet/11/22

Get key-value pairs from POST body in Restlets

This may or may not be the dumbest question ever.
I'm using Restlet. When the client (which I do not control) POSTs to the URL, I can call the function:
representation.getText();
Which produces the following example list of key-value pairs in string form:
CallStatus=in-progress&CallerCountry=US&CalledZip=24013&ApiVersion=2008-08-01&CallerCity=ARLINGTON&CalledCity=ROANOKE&CallSegmentGuid=&CalledCountry=US&DialStatus=answered&CallerState=VA&CalledState=VA&CallerZip=22039
How can I access this data as a Map of key-value pairs in Restlet?
ANSWER:
Form newForm = new Form(getRequest().getEntity());
Check out these examples quoted from restlet.org (a Form is like a Map):
Getting values from a web form
The web form is in fact the entity of the POST request sent to the server, thus you have access to it via request.getEntity().
There is a shortcut which allows to have a list of all input fields :
Form form = request.getEntityAsForm();
for (Parameter parameter : form) {
System.out.print("parameter " + parameter.getName());
System.out.println("/" + parameter.getValue());
}
Getting values from a query
The query is a part of the identifier (the URI) of the request resource. Thus, you have access to it via request.getResourceRef().getQuery().
There is a shortcut which allows to have a list of all "key=value" pairs :
Form form = request.getResourceRef().getQueryAsForm();
for (Parameter parameter : form) {
System.out.print("parameter " + parameter.getName());
System.out.println("/" + parameter.getValue());
}

Categories

Resources