Announcement Announcement Module
Collapse
No announcement yet.
Binding a List of objects having multiple properties Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Binding a List of objects having multiple properties

    Hello all. I'm new to Spring and I'm struggling a bit with a form binding task. I hope it's sufficient to state the problem as follows:

    I have a domain class as follows (well, my real class has many more props than this)...

    Code:
    public class Box {
      int id;
      String color;
      int size;
    }
    ...from my view, I send a POST request to my Form Controller which, if seen as a query string, might look like the following:

    ?box.id=1&box.color=red&box.size=4&box.id=2&box.co lor=blue&box.size=2

    Notice that I'm not including the index of the box in the POST data. I can get things to work if I do include the index position of each Box, but that is making my view very complicated given the CRUD functionality exposed from the UI. Nonetheless...

    Is it possible to have Spring treat the separate String arrays (box.id[], box.color[], box.size[]) as an array of Box objects? I was hoping the CustomCollectionEditor would be good for this, but I could not get that to work with anything that had more than one property to bind (i.e., I could trap the box.id[], box.color[], and box.size[] separately but not as a single box[]).

    Every path I go down for this is quite awkward, so I'm hoping there's some Spring functionality I've overlooked that could help with this task.

    Thanks very much for any help.

    Don

  • #2
    Not unless you write you own custom binder; but I have to ask; why not simply create a Box[] on your backing object and set the request parameters boxes[0].id=xyz etc.

    Of course; you need to make sure that the array contains the elements you are expecting.... In the command.getBoxes() returns an empty array, then it won't work...

    Comment


    • #3
      Well, I do have it working with the Box[] approach (including the index for every request field), but my HTML gets very, very nasty that way. Users are able to create new Box items and having to set the name attribute of all the input elements to a unique Box index via javascript (for the new items), is too complicated. I can do it, but it's just so ugly.

      You mention a custom binder. How would I go about doing that? Could I make it generic and reusable for other classes? (Answering the second question would likely mean there's already a Spring class for this, rightt? )

      Thanks.

      Don

      Comment


      • #4
        You could a number of things I suppose, but I don't think any of them are "out of the box".

        I did actually write such a thing a few years back; but I cannot remember what I did

        I am not sure though exactly what you are trying to do

        Are you trying to:

        - update a single, existing Box
        - update a collection of existing Boxen
        - create a new box

        Ta.

        Comment


        • #5
          Originally posted by yatesco
          I am not sure though exactly what you are trying to do

          Are you trying to:

          - update a single, existing Box
          - update a collection of existing Boxen
          - create a new box
          Sorry for not being clear. I am potentially creating new boxes, updating existing boxes, deleting existing boxes. But let's limit the operation to creating one or more new boxes (I am ok enough with the box[index].property approach for updates).

          With that in mind, again looking at a query string:

          ?box.id=1&box.color=red&box.size=4&box.id=2&box.co lor=blue&box.size=2

          We would get three String arrays as parameters:
          1. String[2] box.id = { 1, 2 }
          2. String[2] box.color = { red, blue }
          3. String[2] box.size = { 4, 2 }

          From that, I would assume (as a precondition) that I can line things up:
          1. String { box.id[0], box.color[0], box.size[0] }
          2. String { box.id[1], box.color[1], box.size[1] }

          These groupings would then beget new Box objects through a binding operation.

          Can I even do this with a property editor (or some other mechanism)? Is there a natural fit of this task/requirement with any Spring service/mechanism?

          I'm starting to see, like you say, there isn't an out-of-the-box utility or a usage idiom for this.

          Don

          Comment


          • #6
            You could introduce your own binder, or alternatively do a bit of magic on your backing object, i.e.:

            Code:
            setNewBoxIds(final String ids[]);
            setNewBoxSizes(final String sizes[])
            setNewBoxColors(final String colors[])
            and have each setNew method ensure that there are n boxen where n is the string array size.

            Ugly, hacky, but will work. Won't cope with multiple size arrays and assumes that the order of the elements is the same.

            Might just work, but don't tell anyone *I* recommended it

            Comment


            • #7
              Originally posted by yatesco
              Code:
              setNewBoxIds(final String ids[]);
              setNewBoxSizes(final String sizes[])
              setNewBoxColors(final String colors[])
              Cool. That's exactly how I was proceeding but I was having them as type List:

              Code:
              class Wrapper
              {
                setBoxes(List) // existing boxes
                setNewID(List)
                setNewName(List)
                setNewColor(List)
              }
              Thanks for approving that approach, however nasty.

              As you also suggest, I'll look into implementing a custom Binder.

              Thanks again for your help.

              Don

              Comment


              • #8
                Originally posted by thematic
                Thanks for approving that approach, however nasty.
                For the sake of my reputation; I absolutely cannot recommend you proceed with this horrific approach.

                Pragmatically; however; I expect it will work

                Comment

                Working...
                X