Convert HTML form Post Param string to Java Map - java

I am reading the request body payload from an HttpServletRequest instance. the body is created by HTML form post. e.g. "param1=value1&param2=value2&param1=value3", thus it will have string and array as the value of the param. And I want to convert it into Map so that the Object can be either String or List
Is there a utility method I can use from apache-commons, googlecommon/guava, or springframework that can make this magic happen without me checking whether it is an array of values or just a single value etc?

Related

Java QueryParam with key and value in the same parameter

I'm creating a endpoint (using Jersey annotations) that receives a list of Strings as it's parameter. The strings need to contain a key and a value.
So on the url it would look something like
?params=key1=value1&params=key2=value2&params....
Two questions:
I'm not sure if the above example would work, I assume you would have to encode the = sign between key and value. Is that correct?
Is there a better or more standard way to approach this?
Obviously the most standard way would be to have the RHS be the key and the LHS of the equal sign would be the value. The problem is I don't want to define every possible key value pair in my method signature. I want to accept a general list of keys and values and let the user pass in the pairs that are relevant to their query.
So far I've tried several google queries but haven't found an answer:
java url key and value parameter
java url parameters with key and value
list of key value pairs in url java
Storing a list of key value pairs in a url parameter, javascript. (has an answer for php but I'm using Java, would this work in Java?)
how to send an array in url request (suggests the above would work in java, if so, can the index be a string like &params[key2]=value2...?)
Yes. Jersey can handle it even = between key and value is not encoded.If query parameter is params=key1=value1&params=key2=value2 , the params list below will be [key1=value1, key2=value2]
#GET
public Response q34211549(#QueryParam("params") List<String> params) {
//parse params list and convert it into key and value
}
You can also consider to create a ParamConverter to let Jersey to do this conversion for you.
Reference
JAX-RS ParamConverter and ParamConverterProvider Example

rest-assured jsonPath returns HashMap instead of LinkedHashMap

This pertains to Java.
I would like to be able to change the default behavior of how a JsonPath object returns itself when parsed from a json response so that I can still leverage the methods it comes with such as getMap(), getList(), etc. Ideally I would like all the JsonPath methods to return their Map objects as a LinkedHashMap instead of a HashMap or at the minimum have the getMap() method return as a LinkedHashMap so I can preserve key ordering.
The below response object's json key ordering matches the browser's json response:
Response response = given().get(urlQuery).then().extract().response();
However, when you attempt to grab an object or value from the response via jsonPath() then the json key ordering is all screwed up due to the fact that JsonPath methods are leveraging a HashMap instead of a LinkedHashMap behind the scenes such as the code snippet below does:
Map map = response.jsonPath().getMap("path.to.a.map");
I'm hoping the answer lies within changing the config to something, or overloading a method somewhere, etc. as I like using the rest-assured library for all my json parsing except I now need to preserve key ordering.
Aside from the response object as mentioned above, I would be content if I could at the minimum get the JsonPath methods to return the json in the correct order as shown by the below code example:
import com.jayway.restassured.path.json.JsonPath;
String json = "{\"fields\":{\"field1\":1,\"field2\":2,\"field3\":3,\"field4\":\"4\"}}";
// The value of the JsonPath object stays in the correct order: {"fields":{"field1":1,"field2":2,"field3":3,"field4":"4"}}
JsonPath jsonpath = new JsonPath(json);
// When using any of the JsonPath methods the order is messed up and returns: "{field4=4, field3=3, field2=2, field1=1}"
Object map = jsonpath.getMap("fields");
I would like to somehow get the JsonPath methods to keep the order by leveraging LinkedHashMap types but am unsure how or where to implement this.

Getting JSON data from a .java file

I have a Java Method, in a class called by a Java Servlet, that returns an Array of JSONObjects. For example, if I loop through the array in a standard for loop, each object is printed as you would expect a JSONObject to appear.
I am struggling to understand how to use the .getJSON() Jquery method to get this data. Somehow, I need to get these JSONObjects to be called by this method, so I can populate a DataTable (using AJAX).
{"lastName":"doe","requestVar":3,"name":" John","rqTime":"1402600668949"}
{"lastName":"doe","requestVar":4,"name":" Jane","rqTime":"1402677126117"}
Currently, the only answers I can find are when people use the .getJSON method on a .JSON file; is there any way for me to .getJSON from a .java file?
In the .getJSON method, you can call a URL. So make a servlet call in this URL. Make that servlet return the JSON Array as string. In Javascript, get the output and use it.

Can I use varargs in a retrofit method declaration?

I've got an API endpoint that is defined as:
GET https://api-server.com/something/{id_or_ids}
where ids can be a single object id or a comma separated list of ids.
e.g.
https://api-server.com/something/abcd1234
https://api-server.com/something/abcd1234,abcd4567,gdht64332
if a single id is given (and a matching object is found) I get back a json object:
{ "blah" : "blah" }
If multiple ids are given, I get the response in a json array:
[{"blah1":"bleh"}, {"blah2":"meh"}, {"blah3":"blah"}]
I'm currently thinking that I should implement this as two methods (can it be done in one?):
one that takes a single id and returns a single object:
#GET("/something/{id}")
void getObject (#Path("id") String objectId, Callback<MyObject> callback)
and
one that takes multiple ids and returns an array of objects.
#GET("/something/{ids}")
void getObject (Callback<MyObject[]> callback,#Path("ids") String ... objectIds)
Is there a way to feed the 2nd method varargs and concatenate them in the id field?
Thanks
Retrofit can't know how you want to join the strings in the path. While commas seem obvious, there's no reason why someone might want pipes (|) or colons (:) or whatever.
Because of this fact, we don't do anything and rely on you to choose.
There's two solutions to this:
Use String as the argument type and join at the call site. For example:
foo.getObject(Joiner.on(',').join(things));
Use a custom object whose toString() method deals with returning the correct format for one or many objects.

Does this return the pointer to the values or does it copy the values?

Well OK, I got confused. I believe it returns the pointer to the original map?
private HttpServletRequest originalRequest;
Map params = originalRequest.getParameterMap();
params.remove("parameter-to-remove");
params.put("parameter-to-add", "<a value>");
Now are the parameters in the originalRequest going to change after these actions? Or does it just copy the values to params and it doesn't matter what I do with them and nothings going to be changed in originalRequest?
Returned map is immutable Map, that could be the reason why you are not seeing the changes reflected.
As per getParameterMap javadoc
an immutable java.util.Map containing parameter names as keys and parameter values as map values. The keys in the parameter map are of type String. The values in the parameter map are of type String array.
If you would like to set some value to request, you should use setAttribute.
No, you are not allowed to remove or add any request parameter(s) to the request object. They must remain (as they arrived to the server) until the request object goes out of scope (after the end of the request processing cycle).
Logically, if you were allowed to do something like that, then the request object would not represent the original request any more. During the whole request processing cycle, we want to process the request sent by the client, not the one that has been tampered.
The method you should use instead is void setAttribute(java.lang.String name, java.lang.Object o).

Categories

Resources