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:
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?
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.
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?
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" ' 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"> ?
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.
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.
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.
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?
Something must be done about this. Let's start by reading this tiny ad:
a bit of art, as a gift, the permaculture playing cards