How do I get all the parameterNames in an HTML form in
the same sequence?
Example:
If the form contains FirstName, LastNameand Age
The output should appear exatcly in the same sequence
I have tried using the following but this shifts the
order of the output:
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
out.print(paramName);
}
I don't think there's nothing in the HTTP spec that forces browsers to send parameters in the order they appear in the form. You can work it around by prefixing a number to the name of the parameter like:
FirstName --> 0_FirstName
LastName --> 1_LastName
...
After that you could basically order the elements by the prefix. It is an ugly solution but it is the only way to do it. Something like:
// Assuming you fill listOfParameters with all the parameters
Collections.sort(listOfParameters, new Comparator<String>() {
int compare(String a,String b) {
return Integer.getInt(a.substring(0,a.indexOf("_"))) -
Integer.getInt(a.substring(0,b.indexOf("_")))
}
});
for (String param : listOfParameters) {
// traverse in order of the prefix
}
By the way - does it really matters the order in which you receive the parameters ?
None of the answers here really did answer my question. A HttpServletRequest saves all it's parameters in a HashMap, and a HashMap has NO ORDER. So, I saved the order of the parameters in an ordered ArrayList and saved it in a HttpSession, so I could retrieve the order of the parameters by querying the ArrayList (that was saved in the session) and achieve what I wanted!
request.getParameterNames () uses HashMap internally to store the name value pairs of form fields. There is no order maintained in this. if you need this in order then , some sort of naming convention for form parameters to control the order of retrieval.
SortedSet temp = new SortedSet();
Enumeration enumeration = request.getParameterNames();
while (enumeration.hasMoreElements())
{
temp.add((String)enumeration.nextElement());
}
Updated: You can use sorted set for that. Note that you must have all the parameters with different names (in this case it is most likely). Write any prefix as your parameter name.
Example:
<input type="text" name="1step">
<input type="text" name="2step">
Then in java code you can write:
SortedSet ss = new TreeSet();
Enumeration<String> enm = request.getParameterNames();
while(enm.hasMoreElements()) {
String pname = enm.nextElement();
}
Iterator i = ss.iterator();
while(i.hasNext()) {
String param = (String)i.next();
String value = request.getParameter(param);
}
HTML or Jsp Page
<input type="text" name="1UserName">
<input type="text" name="2Password">
<input type="text" name="3MobileNo">
<input type="text" name="4country">
and so on...
then in java code
SortedSet ss = new TreeSet();
Enumeration<String> enm=request.getParameterNames();
while(enm.hasMoreElements()){
String pname = enm.nextElement();
ss.add(pname);
}
Iterator i=ss.iterator();
while(i.hasNext()) {
String param=(String)i.next();
String value=request.getParameter(param);
}
Related
<th:block th:each="someData, index : ${someData.from.somewhere}">
<th:block th:each="image : ${images.foo0bar}">
<img th:src="${image}"/>
</th:block>
<hr/>
</th:block>
I want 0 in images.foo0bar to be replaced by index
How do I do something like th:each="image : ${images.foo + index + bar}"
You can use Thymeleaf's preprocessor to execute a getter based on a concatenated string:
__${...}__
For example:
<th:block th:each="someData, iterstat : ${someData}">
<th:block th:with="imageField=|images.foo${iterstat.index}bar|">
<th:block th:each="image : ${__${imageField}__}">
<img th:src="${image}">
</th:block>
</th:block>
</th:block>
In the above approach, the th:with="imageField=..." is used to build the string you need:
images.foo0bar
images.foo1bar
... and so on...
That imageField variable is then used with the Thymeleaf preprocessing syntax to handle it as a field name in your images object.
UPDATE
My solution above had a mistake, as originally written. Instead of this:
__${imageField}__
It should be this:
${__${imageField}__}
In other words, I forgot to wrap the pre-processor results in a Thymeleaf expression - so that the actual objects in each list (of image URLs) are retrieved.
I corrected this, above.
For backgound, here is the test data I used for the Thymeleaf model:
List<String> someData = Stream.of("abc", "def", "ghi")
.collect(Collectors.toList());
List<String> a = Stream.of("1", "2", "3")
.collect(Collectors.toList());
List<String> b = Stream.of("4", "5", "6")
.collect(Collectors.toList());
List<String> c = Stream.of("7", "8")
.collect(Collectors.toList());
Images images = new Images();
images.setFoo0bar(a);
images.setFoo1bar(b);
images.setFoo2bar(c);
Map<String, Object> model = new HashMap<>();
model.put("someData", someData);
model.put("images", images);
And my Images class contains these 3 fields:
private List<String> foo0bar;
private List<String> foo1bar;
private List<String> foo2bar;
Just a suggestion...
The Java objects which support this appear to be a bit convoluted, behind the scenes.
You have a collection of someData which you do not directly access, except to iterate through a count of its contents.
You then use this count to build a field name, so you can executed the related getter - and iterate through that collection of image URLs, in a completely different (seemingly unrelated) object.
Just as a suggestion: If you re-arrange your Java data, you could avoid this Thymeleaf complexity.
Here is SpringMVC Controller code snippet:
#RequestMapping(value = "/getCityList", method = RequestMethod.POST)
public #ResponseBody LinkedHashMap<String, String> getCityList(#RequestParam(value = "countryCode") String countryCode, HttpServletRequest request) throws Exception {
//gets ordered city list of country [sorted by city name]
LinkedHashMap<String, String> cityList = uiOperationsService.getCityList(countryCode);
for (String s : cityList.values()) {
System.out.println(s); //prints sorted list [sorted by name]
}
return cityList;
}
Here is ajax call:
function fillCityList(countryCode) {
$.ajax({
type: "POST",
url: '/getCityList',
data: {countryCode:countryCode},
beforeSend:function(){
$('#city').html("<option value=''>-- SELECT --</option>" );
}
}).done(function (data) {
console.log(data); // UNSORTED JSON STRING [Actually sorted by key... not by city name]
})
}
Sorted LinkedHashMap returns as unsorted JSON object from getCityList method. Why order is changed during return process ?
Is LinkedHashMap converted to HashMap because of ResponseBody annotation?
I can convert my sorted object to json string via Gson library and return json string from my getCityList method but i don't like this solution. What can i do to provide javascript callback method with sorted list?
You're expecting a JSON object's entries to have the same order as the LinkedHashMap entries. That won't happen, because JavaScript object keys have no intrinsic order. They're just like Java HashMaps.
If you need a JavaScript data structure that maintains an order, you should use an array, not an object. Return a sorted List<City> from your method, where City has a key and a value.
If you wanted to send sorted data then pass List of Your object or City as List<City> which have sorted data.
I have also face same problem when I have used HashMap in my application, it doesn't guarantee that it will receive in same order in which we add them. We have to access it via it's key.
so it's better to use List instead of LinkedHashMap.
Most implementations of JSON make no effort to preserve the order of an object's name/value pairs, since it is (by definition) not significant.
We have couple of related drop downs where results of one drop down relate to other dropdown.
We have a mapping defined for what to select when in the form of map-of-map, like this;
Map<String,Map<String,String>> topics = new HashMap<String, Map<String,String>>();
Map<String,String> ds = new HashMap<String, String>();
ds.put("Array", "Array");
ds.put("LL", "LL");
topics.put("DS", ds);
Map<String,String> algo = new HashMap<String, String>();
algo.put("BS", "BS");
algo.put("Sorting", "Sorting");
topics.put("Algorithm", algo);
Map<String,String> phil = new HashMap<String, String>();
phil.put("phil1", "phil1");
phil.put("phil2", "phil2");
topics.put("Philosophy", phil);
Map<String,String> others = new HashMap<String, String>();
others.put("others", "others");
topics.put("Others", others);
As per the above map, when "DS"is selected, we want to display "Ă„rray"and "LL". Similar is the case with other mappings.
I pass this map to JSP and use JSTL to render the options. While making decision to call JS to populate subsequent drop-down, I want to change it to JSON.
I want to pass specific map of the selected option to the JS method and populate subsequent drop down.
Is converting to JSON the only way? If yes, how about passing it from the controller? If we don't pass it from the controller, what are the cleaner ways to do it in JSP itself?
JSP Block is as follows:
<div>Subject</div>
<select name="topic" onchange="callJavaScriptMethodWithMapOfSelectedComponent(mapOfSelectedValue)");">
<c:forEach var="entry" items="${topics}">
<option value="${entry.key}">${entry.key}</option>
</c:forEach>
</select>
<select name="college">
<option value="default">Select Subject</option>
</select>
Depending on the values selected in first drop down, we need to populatevalues in second drop down.
JS method would take map of selected value in first drop down and populate second one.
function setOptions(chosen) {
var selbox = document.myform.college;
selbox.options.length = 0;
if (chosen == " ") {
selbox.options[selbox.options.length] = new Option('Please select one of the options above first',' ');
}
selbox.options[selbox.options.length] = new Option('//Choosen from the map passed','oneone');
}
}
First off I think you better change it so that topics is a Map < String, List < String > >, that'd make more sense since it's a single depth hierarchy.
Next up you have the choice of either converting the map into JSON and using eval to fill an object in javascript, or manually transverse the map keys and add them to the object, it all depends on the tools you have at hand to serialize the map into JSON server side (You can use new JSONObject(topics); from json.org) then just eval the json into a variable on Javascript.
I have a collection Map as (String,String), and the String inputText.
What could you recommend to scan the inputText to check, if it contains any key from Map.
E.g. I have the next:
//hashmap is used - I don't need the order
Map<String, String> mapOfStrings = new HashMap<String,String>();
mapOfStrings.put("java","yep, java is very useful!");
mapOfStrings.put("night","night coding is the routine");
String inputText = "what do you think about java?"
String outputText = ""; //here should be an <answer>
Set<String> keys = mapOfStrings.keySet();
for (String key:keys){
String value = mapOfStrings.get(key);
//here it must uderstand, that the inputText contains "java" that equals to
//the key="java" and put in outputText the correspondent value
}
All I know, it's not the equals() or compareTo(). May be I should somehow check the order of characters in inptuText?
Regards
You can use the following:
for (String key:keys){
String value = mapOfStrings.get(key);
//here it must uderstand, that the inputText contains "java" that equals to
//the key="java" and put in outputText the correspondent value
if (inputText.contains(key))
{
outputText = value;
}
}
I want to do the below thing in JSP starting from for loop- I just want to loop HashSet and HashMap and print the result
private static HashMap<Long, Long> histogram = new HashMap<Long, Long>();
private static Set<Long> keys = histogram.keySet();
for (Long key : keys) {
Long value = histogram.get(key);
System.out.println("MEASUREMENT, HG data, " + key + ":" + value);
}
I am working with Spring MVC, so I added these two things in my model
model.addAttribute("hashSet", (keys));
model.addAttribute("histogram", (histogram));
And in my JSP page, I was doing something like this to emulate the above JAVA code but it was giving me an exception that something is wrong in my JSP page.
<fieldset>
<legend>Performance Testing:</legend>
<pre>
<c:forEach items="${hashSet}" var="entry">
Key = ${entry.key}, value = ${histogram}.get(${entry.key})<br>
</c:forEach>
</pre>
<br />
</fieldset>
Exception I got-
Caused by: javax.el.PropertyNotFoundException: Property 'key' not found on type java.lang.Long
at javax.el.BeanELResolver$BeanProperties.get(BeanELResolver.java:195)
at javax.el.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:172)
at javax.el.BeanELResolver.property(BeanELResolver.java:281)
at javax.el.BeanELResolver.getValue(BeanELResolver.java:62)
Can anyone help me out with this?
You don't need to make use of keySet to access the values in the HashMap. When you iterate over HashMap using <c:forEach..>, you get back the EntrySet, for which you can use: - EntrySet#getKey() and EntrySet#getValue() directly: -
<c:forEach items="${histogram}" var="entry">
Key = ${entry.key}, value = ${entry.value}<br>
</c:forEach>