I have a domain model that features a number of 'elements', pieces of text that can be rendered to show rich content. There are pieces of HTML text, textile text, Flash objects and so on. The basic features of these elements are encapsulated in AbstractElement
, which has implementations HTMLElement
, FlashElement
and so on. The model therefore has a List<AbstractElement>
to contain all the elements it can have.
When editing the model, I want the user to be able to dynamically add elements, and save these when the user submits the form. So what I have is a form that is dynamically expandible with some JavaScript, which results in the following form:
<form action=...>
<!-- Other attributes -->
<textarea name="object.elements[0].content"/>
<textarea name="object.elements[1].content"/>
<!-- Some elements are based on text, others on files -->
<input type="hidden" name="object.elements[2].file" value="somevalue"/>
<textarea name="object.elements[3].content"/>
<!-- Submit button -->
</form>
This goes wrong when submitting the form. It's quite obvious why - when submitted, Spring tries to instantiate the required elements in the list. Since the list of elements contains objects of type AbstractElement
which is abstract, Spring cannot instantiate new elements.
How would I go about having Spring instantiate the proper type of element? Could add type information in the form, and have some ModelAttribute do it? How would that work? Is there something I can do in the model that'll do this automatically?
For example, in C#, if you use the generic type parameter T, then you can write a List<T> class that is declared as either List<int>, List<string>, or List<MyClass>. With .NET Framework interoperability, you can define DotNet variables for generics. You cannot specify generic type names in C/AL.
You can add, delete, populate, sort Generic Lists. <T> is a placeholder for data types and replaced by datatype at compile time. How it is different from Collection Lists?
FDA publishes a list of reported authorized generics and updates that list quarterly. On September 27, 2007, the President signed into law the Food and Drug Administration Amendments Act (FDAAA) (Public Law 110-85). Among other things, FDAAA added new subsection (t) to section 505 of the Federal Food, Drug, and Cosmetic Act (the Act).
The generics autowiring feature works with the help of ResolvableType class behind the scenes. It was introduced in Spring 4.0 to encapsulate Java Type and handle access to supertypes, interfaces, generic parameters and finally resolve to a Class: The output of the above code would show the corresponding simple and generic types:
It sounds like you need to create one (or more ) customer property editors which can take the request parameters and convert them to the correct class instances to add to the collection.
Spring uses PropertyEditor instances registered with the data binder to bind request parameters. In cases where the default set of PropertyEditors can't determine the correct type, you can register your own editors to handle the logic.
The process is described in the Spring docs at this link:
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/validation.html
Specifically, see section 5.4.2.1 on how to register customer property editors.
You can register your property editors using the registerCustomEditor() method of the WebDataBinder class in the initBinder() method of your controller (identified with the @InitBinder annotation).
I ended up solving this by implementing a ModelAttribute that constructs the list of elements by parsing the raw form data. Parsing the raw form data can be used by using the HttpServletRequest
object, looping through the parameter map and just create the required objects 'by hand'. It's reusable if you put it in a helper function, though I need a ModelAttribute in every controller I use it in.
It's not the ideal solution, but it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With