GeeCON Prague 2014*
The moose likes Struts and the fly likes Problem populating a newly created HashMap in a Struts2 Action Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Frameworks » Struts
Bookmark "Problem populating a newly created HashMap in a Struts2 Action" Watch "Problem populating a newly created HashMap in a Struts2 Action" New topic
Author

Problem populating a newly created HashMap in a Struts2 Action

Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Hey guys, hoping to get a hand here before my head pops =)

I'm creating a webshop where a product is supposed to be based on a template and recieve several attribute containers. An attribute has a name and optionally a measurement, while the actual value of the attribute is stored in a HashMap<Attribute, String> in the Product bean. This is to dynamically and easily create different types of products that always have a given set of attributes.

For instance, a product named Cat would have the Animal template, which has the "Number of paws" and "Favorite food" attributes. The values of the attributes would in this case be <Number of paws, "4"> and <Favorite food, "Whiskas">. My problem arises when I try to create a product like this using a jsp.

My flow is like this:

a) User selects a template.
b) Get the ArrayList of attributes in the chosen Template and create a textfield in my jsp for each using a Struts 2 iterator. The textfields are currently created this way:
<s:textfield name="attributeValues['+#{iteratorStatus.index}+']"/>
c) Create a new hashmap<attribute, string> in the action class to populate.
d) User fills out all fields required to create a Product, as well as values to each attribute in the chosen template.
e) Validate input. Attribute values are not validated.
f) A new Product instance is created using the specified input and saved to the DB. This is done during Execute, using a builder pattern bean.

The problem is, my hashmap doesn't live past the initialisation of the action class, so at the time of validate (the attributes are not used in Validate) and execute my new hashmap is null.

So, where should I define my hashmap and how do I get it to survive long enough to be set into the newly created Product at the time of Execution?
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

No way to help without seeing the server side code--that's where you say you're having a problem.

Sounds like you're creating the map wrong.
Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Certainly. I've cut it down to the bare basics, only dealing with the steps I defined above. I added some comments, but if I need to clarify it somewhere, please do tell.


David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Still difficult to say, since I have no idea what's actually being executed. Obviously I'd be pretty skeptical of the init() method, since it appears to be the only thing creating the map. Most likely the map is being properly created by the framework itself (hard to say) and filled in by the "params" interceptor, whereupon it's overwritten by the newly-created one.
Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Hm. That might just be it. First time I'm trying to populate a map or collection using struts, so I had no real idea it created such things itself. I'll mess around with it some and report back.

Thanks for now!
Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Right, worked on it for a bit, removing the instansiation of the hashmap but otherwise keeping the code the same. However, I can't figure out how to make the textfield refer to the Value of the hashmap in question. Right now I'm doing it like this, which doesn't seem to be working.


I'm not quite sure where in the documentation to read about this sort of thing either, what would this sort of issue be called?
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

Mark Avery wrote:what would this sort of issue be called?

"Misunderstanding of OGNL" ;)

#{} is a JSF(/UEL?) escape. %{#status} is an OGNL escape referring to a named variable "status" (i.e. not on the stack itself).

So first make sure the HTML is rendering correctly.
Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Hah, I deserved that. Anyway, cool. Gonna have to read up on OGNL it seems. Now, if I understand this correctly my current textfield, seen below, attempts to set the key of the hashmap rather than the value. Is that correct?



Reason I'm asking is, while it doesn't crash (anymore), I get ognl.NoConversionPossible-entries into my map as well as 'Invalid field value for field "attributeValues[0]" ' during validation, causing the action to return "input".

Thus, it seems I could make, say, an ArrayList with these values and solve it that way, but is there a way to get Struts2 to populate a HashMap the way I want here, IE <Iterated_Attribute_Object, "Contents of the textfield"> ?
David Newton
Author
Rancher

Joined: Sep 29, 2008
Posts: 12617

A map should work just fine; I do maps with ID keys all the time. Off the top of my head I'm not thinking of anything else useful. It could be a conversion issue with the value itself, in other words, you're mapping a string to a domain object, and it may be choking there rather than on the map key itself.
Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Hm. I changed the map to a <String, String> map and printed the results. Seems the keys added are [1, 0] (I can only assume those are the iterator status integers), while the values set are [Length (cm), Height (M)], those being the toStrings of the two Attributes I'm working with currently.

So basically, it seems that my current tag gets the toString of the currently iterated ValueStack object.

Beyond that, I'm very much stuck again.

Here's my current code:
Mark Avery
Greenhorn

Joined: Jun 03, 2010
Posts: 7
Alright, I gave up on the map for now. Since I need to create Templates anyway I decided to take up populating a simple List with Attributes. However, it's still getting stuck at Validate with the same problem, IE Conversion not possible. (Getting [ognl.NoConversionPossible] entries into the List)

I've been reading up on Type Conversion, trying the following, but frankly I see no result at all and I'm quite stuck.

ManageTemplatesAction.java


ManageTemplatesAction-conversion.properties


managetemplats.jsp (relevant part)


Now, if I've been reading the documentation and Strus2 in Action right, this should convert any selected entries into proper Attribute objects. So, three concrete questions:

a) What should I, in this case, set the listValue of the <s:select> to? The unique id of the Attribute or something else?
b) What should I set listKey to?
c) Why doesn't my class seem to recognise my ManageTemplatesAction-conversion.properties?
 
GeeCON Prague 2014
 
subject: Problem populating a newly created HashMap in a Struts2 Action