2

I'm trying to build a web-based GUI tool for our DB using Struts2.

I managed to render and populate all fields in the web-form but now have a problem saving the input into the DB.

Here is a reduced example of the problem (of course this is not the real code, but enough to understand the dilemma:

Animal.java:

public class Animal{
    private final static long serialVersionUID = 2L;
    protected String id;
    protected String comment;
    protected String name;
    protected BaseAnimal subanimal;
    protected Date undotted;

    // All getters+setters also exist.
    public String getAnimalType(){
        return subanimal.getClass().getSimpleName();
}

Cat.java:

public class Cat extends BaseAnimal{

    private final static long serialVersionUID = 2L;
    protected Gender gender;
    protected int age;
    protected Color color;
    protected Voice voice;
    //All getters+setters also exist
}

Turtle.java:

public class Turtle extends BaseAnimal{

    private final static long serialVersionUID = 2L;
    protected Gender gender;
    protected int circlesOnBack;
    protected int speed;
    //All getters+setters also exist
}

DoAction.java:

public class DoItem extends ActionSupport implements ModelDriven<Animal>{
    private static final long serialVersionUID = 2L;
    protected String idForm;
    protected Animal animal;

    @Override
    public String execute(){
        if (idForm != null && !idForm.equals("")){
            showAnimal(session); //loads animal from DB
        }
        return SUCCESS;
    }

    public void saveAnimal(Map<String,Object> session){
        // Stuck here, help?        
    }
    public Animal getModel() {
        return animal;
    }
    public void setModel(Object animal) {
        this.animal = (Animal) animal;
    }
    public String getIdForm() {
        return idForm;
    }
    public void setIdForm(String idForm) {
        this.idForm = idForm;
    }
    public Animal getAnimal() {
        return animal;
    }
    public void setAnimal(Animal animal) {
        this.animal = animal;
    }
}

animal.jsp:

<%@ taglib prefix="s" uri="/struts-tags" %>    
<html>
<head></head>
<body>

<s:form method="post" theme="simple">
<table>
<tr>
  <td><s:textfield key="name"/></td>
  <td><s:textarea key="comment"/></td>

  <td class='show4cat show4Turtle'>
    <s:select key="animal.subanimal.gender" list='getMap("Gender")'/>
  </td>
  <td class='show4cat'>
    <s:select key="animal.subanimal.color" list='getMap("Color")'/>
  </td>

  <td class='show4turtle'>
    <s:select key="animal.subanimal.speed" list='%{#{'1':'Fast','2':'Ultra Fast'}}'/>
  </td> 
</tr>
<tr>
  <td class='show4turtle'>
    <s:submit action='saveTurtle' name='submitAnimal' value='save'/>
  </td>
  <td class='show4cat'>
    <s:submit action='saveCat' name='submitAnimal' value='save'/>
  </td>
</tr>
</table>
</s:form>
</body>
</html>

I now want to submit this form and save the animals to the DB. How do I manage this save action? My main concern is creating an object of the appropriate child class.

NOTE: I can not change the Data Model design! but can change the JSPs or action classes.

Thanks in advance!

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
Slava
  • 160
  • 2
  • 11

1 Answers1

1

Your two <s:submit/> buttons are targeting two different actions (that you are not showing us).

That is the switch in your case.

Target two actions, one with the Turtle data, the other one with the Cat data, and do the right operation in the execute() method of each action. Since the user have choosen the right button, the action called knows which animal to save.

This actions can be both two different methods of the same physical Action file, or two different Action files, this is up to you and it also depends on how much "shared" code you do have in your Action that must be executed for both the actions. But in the first case, it would mean a lot of unused data in the same file (eg. with 100 animals, all the attributes of the 100 animals in a single action, but only one used when saving), so I'd go with the second way.

You can create three separate actions, one for showing the page before and after saving the animal (eg. ReadAnimal.java) and two actions for saving it (eg. SaveTurtle.java and SaveCat.java), and eventually making the last two extending the first. Read more on this answer.

Final thoughts:

  • SessionAware is the right way to get the Session in an Action class. And it should be at class-level, there is no need to pass it between the action methods.
  • consider NOT using ModelDriven, since it can be messy when not knowing exactly what to do.
Community
  • 1
  • 1
Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • Thanks for the ideas, which are followed by these 2 questions: Having 2 java files for each animal would sum up to writing about 50 java action classes (BaseAnimal is inherited by 20+ classes). I was aiming at doing it as general as possible. Any suggestions? Also, what do you suggest instead of ModelDriven? So far, it seems to suit me best for this use-case. – Slava May 04 '15 at 13:56
  • 1) It's up to you. 50 files each one with 5 attributes, or 1 file with 250 attributes and 50 methods. The first seems cleaner :) especially when you'll need to come back and add/alter/delete something. 2) Instead of using ModelDriven, use plain Actions. Note: you are not even using modeldriven in your JSP... just remove the `implements ModelDriven` from your action and it will work the same ;) P.S: please remember to upvote and / or accept the answer if it helped – Andrea Ligios May 04 '15 at 14:24