Generate a Get query string in Java - java

I want to generate a Get query string in java like so
www.example.com/somethingToGet?key1=value&key2=value....
So my method has 2 parameters the base url(www.example.com/somethingToGet) is the first argument and the 2nd argument is a map data structure. I want to iterate over the map and generate a string like so
key1=value&key2=value....
It shouldn't end with ampersand.
I don't want to use any built in functions, I want to know the logic how such strings are generated.

Something like this:
public static String getQuery(String base, java.util.Map<String, String> map) {
StringBuilder str = new StringBuilder(base);
str.append('?');
boolean first = true;
for (java.util.Map.Entry<String, String> e : map.entrySet()) {
if (first)
first = false;
else
str.append('&');
str.append(e.getKey());
str.append('=');
str.append(e.getValue());
}
return str.toString();
}

You can also use the format method in URLEncoder class from the Apache HttpComponents library to create a query string. As per the documentation it
Returns a String that is suitable for use as an application/x-www-form-urlencoded list of parameters in an HTTP PUT or HTTP POST.

Related

Description for String[] entries

so i'm working on a project and i need the following to work:
Let's say I have a String[] contatining out of f.e 3 values "0D", "0A", "01A0"
Now in the background I got like a defined description for each of these values and I want to show them in another string.
So in the end i want to call a method with String"0D" and the method returns me the description, in this example "speed"
same for the others, if i call the method with "0A" it returns String "Fuel Pressure"
Is there an efficient way for achieving this? Cause i've got a pretty long list and don't want to manually input all the descriptions to the commands..
Yeah a HashMap would work.
You could try this:
HashMap<String, String> valueDescription = new HashMap<>();
valueDescription.put("0D", "speed");
valueDescription.put("0A", "Fuel Pressure");
valueDescription.put("01A0", "Temperature");
public String getDescription(String value) {
if (valueDescription.containsKey(value)) {
return valueDescription.get(value);
} else {
return "Description not found";
}
}
I would consider using a hashmap of <String, String>. The key would be the command, and the value is the description.

Check 2 strings without case sensitivity or use equalsIgnoreCase method

I have some inputted String String usrInput; that user could import some string once into App without any case-sensitivity policy like: "start","Start","START","end" ,"END" and etc.
And I have a Map that i inserted my strings for example "start" into that and put it into HashMap<String, String> myMap:
Map<String, String> listOfActions = new HashMap<>();
listOfActions.put(myStr, myStr);
Now I want to check listOfActions members to get for example "start" filed in every case model ("start","Start","START") , currently I do like below:
if (listOfActions.containsKey(usrInput.toUpperCase())
|| listOfActions.containsKey(usrInput.toLowerCase())) {
/// some do
}
So I want to know:
1. Is there any way to get String value without case-sensitivity?
I will also add this here I couldn't use equalsIgnoreCase() method for get items from Map because its return Boolean.
2. I have similar problem in switch-case statements to check 2 string equality without case-sensitivity.
You can use
Map<String, String> listOfActions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
Other solutions can be Apache's CaseInsensitiveMap or Spring's LinkedCaseInsensitiveMap.
Please see https://www.baeldung.com/java-map-with-case-insensitive-keys for more details about these solutions.
If you only use inputs as map keys (i.e. you don't need to later reproduce the strings in original casing), I suggest just lowercasing all inputs before inserting them into the map:
Map<String, String> listOfActions = new HashMap<>();
listOfActions.put(myStr.toLowerCase(), myStr);
This will simplify locating the values later on, since you know that all keys are already lowercased, so the lookup becomes easy:
if (listOfActions.containsKey(myStr.toLowerCase())) {
// do something
}
When you create a new instance of HashMap, you can override some of its methods, such as put and containsKey like this:
Map<String, String> map = new HashMap<>() {
#Override
public String put(String key, String value) {
return super.put(key.toLowerCase(), value);
}
#Override
public boolean containsKey(Object key) {
return super.containsKey(key.toString().toLowerCase());
}
};
map.put("START", "doStart");
System.out.println(map); // {start=doStart}
System.out.println(map.containsKey("START")); // true
System.out.println(map.containsKey("Start")); // true
System.out.println(map.containsKey("start")); // true
One thing you can do is make everything upper-case or lower-case, then compare them.
string.toLowerCase().equals("other string");
string.toUpperCase().equals("OTHERSTRING");
This way, whether it is lower-case or upper-case, it will only be compared as one or the other, and acts as though it were case insensitive.

How to get Result of LinkedHashMap within Inverted commas [duplicate]

This question already has answers here:
How to convert HashMap to json Array in android?
(5 answers)
Closed 5 years ago.
I am developing an Android app in which I have to send LinkedHashMap results by API but the problem what I am getting is format of result is different. How can I put keys and values both in inverted commas?
I'm getting result like this:
list: {0=816444014066, 1=747083010945, 2=816444010969}
And I want result like this:
list: {"0" : "816444014066","1" : "747083010945","2" : "816444010969"}
How to change the format of result?
Use My Answer. It worked for me.
LinkedHashMap<String, String> data = new LinkedHashMap<String, String>();
// Instantiate a new Gson instance.
Gson gson = new Gson();
// Convert the ordered map into an ordered string.
String json = gson.toJson(data, LinkedHashMap.class);
// Print ordered string.
Log.e("list", ""+json); // {"0" : "816444014066","1" : "747083010945","2" : "816444010969"}
To get the quotes you need to make your keys and values String in your LinkedHashMap
Edit:
maybe what you need is already provided in this answer
In Java you can put quotes to String with :
String value = " \"1\" ";
You could do it like this:
Map<String, String> linkedmap = new LinkedHashMap<>();
linkedHashMap.put(setQuotes("1"), setQuotes("5445454"));
public static String setQuotes(String value){
String result = "";
if(!value.isEmpty()){
result = "\"" + value + "\"";
}
return result;
}
If you print it in the console, it returns:
{"1"="5445454"}
I think that possibility is to create your own Map class that extends LinkedHashMap and to create and implement in it method with behavior similar to behavior of toString() method. This link might help you to get started with implementation of that method:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8u40-b25/java/util/AbstractMap.java#AbstractMap.toString%28%29

Parsing dynamic JSON values to Java objects

In my application I have lot of overviews (tables) with sorting and filtering capabilities. And becuase the different column can hold different value type (strings, numbers, dates, sets, etc.) the filter for these columns also can bring different values. Let me show you few examples (converted to JSON already as is sent to server via REST request):
For simple string value it is like:
{"<column_name>":"<value>"}
For number and date column the filter looks like:
{"<column_name>":[{"operator":"eq","value":"<value>"}]}
{"<column_name>":[{"operator":"eq","value":"<value1>"},{"operator":"gt","value":"<value2>"}]}
For set the filter looks like
{"<column_name>":["<value1>","<value2>"(,...)]}
Now I need to parse that JSON within a helper class that will build the WHERE clause of SQL query. In PHP this is not a problem as I can call json_decode and then simply check whether some value is array, string or whatever else... But how to do this simply in Java?
So far I am using Spring's JsonJsonParser (I didn't find any visible difference between different parsers coming with Spring like Jackson, Gson and others).
I was thinking about creating an own data object class with three different constructors or having three data object classes for all of the three possibilities, but yet I have no clue how to deal with the value returned for column_name after the JSON is parsed by parser...
Simply looking on the examples it gives me three possibilities:
Map<String, String>
Map<String, Map<String, String>>
Map<String, String[]>
Any idea or clue?
Jackson's ObjectMapper treeToValue should be able to help you.
http://fasterxml.github.io/jackson-databind/javadoc/2.2.0/com/fasterxml/jackson/databind/ObjectMapper.html#treeToValue%28com.fasterxml.jackson.core.TreeNode,%20java.lang.Class%29
Your main problem is that the first version of you JSON is not the same construction than the two others. Picking the two others you could deserialize your JSON into a Map<String, Map<String, String> as you said but the first version fits a Map.
There are a couple solutions available to you :
You change the JSON format to always match the Map<String, Map<String, String> pattern
You first parse the JSON into a JsonNode, check the type of the value and deserialize the whole thing into the proper Map pattern.
(quick and dirty) You don't change the JSON, but you try with one of the Map patterns, catch JsonProcessingException, then retry with the other Map pattern
You'll have to check the type of the values in runtime. You can work with a Map<String, Object> or with JsonNode.
Map<String, Object>
JsonParser parser = JsonParserFactory.getJsonParser();
Map<String, Object> map = parser.parseMap(str);
Object filterValue = filter.get("<column_name>");
if (filterValue instanceof String) {
// str is like "{\"<column_name>\":\"<value>\"}"
} else if (filterValue instanceof Collection) {
for (Object arrayValue : (Collection<Object>) filterValue) {
if (arrayValue instanceof String) {
// str is like "{\"<column_name>\":[\"<value1>\",\"<value2>\"]}"
} else if (arrayValue instanceof Map) {
// str is like "{\"<column_name>\":[{\"operator\":\"eq\",\"value\":\"<value>\"}]}"
}
}
}
JsonNode
ObjectMapper mapper = new ObjectMapper();
JsonNode filter = mapper.readTree(str);
JsonNode filterValue = filter.get("<column_name>");
if (filterValue.isTextual()) {
// str is like "{\"<column_name>\":\"<value>\"}"
} else if (filterValue.isArray()) {
for (JsonNode arrayValue : filterValue.elements()) {
if (arrayValue.isTextual()) {
// str is like "{\"<column_name>\":[\"<value1>\",\"<value2>\"]}"
} else if (arrayValue.isObject()) {
// str is like "{\"<column_name>\":[{\"operator\":\"eq\",\"value\":\"<value>\"}]}"
}
}
}

Lang ToStringBuilder request parameters logging

I need to log all the request parameters in some situations for debug purposes...
I tried using ToStringBuilder.reflectionToString(request), but it still showed memory addresses
Is there any easy way to log request parameters in plain text so that I could do something
logger.info(ToStringBuilder.reflectionToString(request)); ?
I also tried logger.info(ToStringBuilder.reflectionToString(request.getParameterMap());
reflectionToString only uses reflection on the object given, to find the attributes to print. The attributes themselves are output using their toString() methods.
Neither the request nor the parameter map have the request parameters you are interested in as direct attributes, so reflectionToString fails for you.
I know of no OOTB way to deeply reflection-print an object, in JDK or commons-lang.
What does the simple call
logger.info(request.getParameterMap());
produce for you?
Ah, I see: The parameter values are String arrays, which only print their hashcode.
You might try a helper function like this (disclaimer: uncompiled and untested)
public static String getParameterToString(ServletRequest request){
StringBuilder sb = new StringBuilder("{");
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()){
sb.append(entry.getKey()).append(":");
sb.append(Arrays.toString(entry.getValue())).append(",");
}
if (sb.length() > 1)
sb.setLength(sb.length() - 1);
return sb.append("}").toString();
}
This function is tested
public static String dumpParams(ServletRequest req) {
StringBuilder sb = new StringBuilder();
Set<Map.Entry<String, String[]>> entries = req.getParameterMap().entrySet();
for (Map.Entry<String, String[]> entry : entries) {
sb.append(entry.getKey())
.append(" = ")
.append(Arrays.toString(entry.getValue()))
.append(", ");
}
if (sb.length() > 2)
sb.setLength(sb.length() - 2); //Removes the last comma
return sb.toString();
}

Categories