0

I have in my controller a Map<String, Boolean>

private Map<String, Boolean> selectedRequestsMap;
selectedRequestsMap = new HashMap<String, Boolean>();

When i put elements in it added normally (as a Boolean value)

selectedRequestsMap.put(StringValue, booleanValue);

enter image description here But when i loop over a Map to read the values
Its considered (as a String value)

// Loop over selectedRequestsMap
for (Map.Entry<String, Boolean> entry : selectedRequestsMap.entrySet()) {
    String key = entry.getKey();
    Boolean value = entry.getValue(); // An Exception is raised 
    // ...  
}

enter image description here Then When i read the Boolean value

An Exception is raised
java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Boolean

Need to know
How i can read a Boolean value normally ?

Ahmed Nabil
  • 17,392
  • 11
  • 61
  • 88
  • Either a ghost or the code changed the Boolean value to String. Usually it's the code. Something replaces the Boolean with its toString(). – nakosspy May 30 '13 at 09:16
  • Give us some sample test data and exact stacktrace . In its current form , this should work. – AllTooSir May 30 '13 at 09:17
  • You can't say that.... A malicious poltergeist can do that! – Thihara May 30 '13 at 09:17
  • How are you using the collection (what do you do with it between putting in the values and the for each loop)? – dratewka May 30 '13 at 09:17
  • Post the entire class and the usages... – Thihara May 30 '13 at 09:18
  • 2
    It looks like some of your code might be changing the parametrized types of your Map. Then some other code actually puts a key value pair of String, String in the Map (hence, "someString", "true"). Try posting all the code that impacts on that specific Map. – Mena May 30 '13 at 09:18
  • Can you put some code how you are putting values into map.. – Sumit Singh May 30 '13 at 09:18
  • No problem at all: http://browxy.com/SavedCode/4024 – Konstantin Yovkov May 30 '13 at 09:19
  • Don't get me wrong, we all get to situations where we think that the inexplicable is happening, but we just need to take a closer look at the code. – nakosspy May 30 '13 at 09:19
  • The code you show is fine. Either your machine is hosed, or something that you haven't shown us is corrupting things. – Nate May 30 '13 at 09:31
  • 1
    How do you populate the map? You mentioned JSF: if you use it, show the corresponding code that you use to initialize the map and set its contents, otherwise, show the relevant code that deals with map data population. My guest is that you populate it with EL (that's reflection-based) with something that has a textual 'true' value. – skuntsel May 30 '13 at 09:38
  • 1
    The most plausible problem with your code is that the values derived from the request are in fact strings and not objects of other types. You might need to 'explain' JSF what type of values you expect to recieve by providing a converter. In this light not string `"true"` will be applied to the map entry, but rather `Boolean.TRUE`. This is because **reflection-based** and **runtime** EL language does not respect generics 'too much'. – skuntsel May 30 '13 at 09:50

1 Answers1

1

The way how you manipulated the map value is broken. You have set a string value of "true" instead of the boolean literal true. That it passed the parameterized generic type constraint can only mean that it's been done via reflection. Considered that the question is asked in JSF context, this in turn means that you're manipulating the map's value in the view side with JSF tags and EL. In that case, you should not be specifying "true" in EL, but instead #{true}.

You didn't show the problem in SSCCE flavor, so it's hard to point out the mistake and provide an exact answer. So, here's just one of the most probable causes:

<h:selectOneRadio value="#{bean.selectedRequestsMap[some.key]}">
    <f:selectItem itemLabel="Yes" itemValue="true" />
    <f:selectItem itemLabel="No" itemValue="false" />
</h:selectOneRadio>

This is not only designtechnically wrong (you should have used a <h:selectBooleanCheckbox> instead), but this is also functionally wrong as it specifies the item values as plain strings instead of as real booleans. In this construct, EL won't be able to auto-coerce those strings to booleans because the parameterized generic type information of the map value is not available during runtime. EL has no idea that the map value is a boolean and without an explicit converter, it will thus put the plain unconverted string submitted value in there.

The fix would then be to explicitly specify them as booleans in EL context:

<h:selectOneRadio value="#{bean.selectedRequestsMap[some.key]}">
    <f:selectItem itemLabel="Yes" itemValue="#{true}" />
    <f:selectItem itemLabel="No" itemValue="#{false}" />
</h:selectOneRadio>

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555