开发者

POJO's collection not populated when submitting form

I have a POJO named "FlashCard" which has a field named "links" which is collection (set) of Link objects. When I submit a FORM to my Action all the POJO fields are populated with values from the form except the collection of "links". I have no idea why this isn't getting populated.

Any advice on how to resolve this problem or how to better troubleshoot it would be much appreciated.

Also, my POJO's collection is a Set. Does it matter (or complicate things) that I'm using a Set and not a List?

I'm including a simplified version of my code below.

Here's my POJO:

public class FlashCard  implements java.io.Serializable {

 private int flashCardId;
 private String question;
 private String answer;
 private Set<Link> links = new HashSet<Link>(0);

public FlashCard() {
}

public FlashCard(String question, String answer) {
    this.question = question;
    this.answer = answer;
}
public FlashCard(String question, String answer, Set<Link> links) {
   this.question = question;
   this.answer = answer;
   this.links = links;
}

public int getFlashCardId() {
    return this.flashCardId;
}

public void setFlashCardId(int flashCardId) {
    this.flashCardId = flashCardId;
}
public String getQuestion() {
    return this.question;
}

public void setQuestion(String question) {
    this.question = question;
}
public String getAnswer() {
    return this.answer;
}

public void setAnswer(String answer) {
    this.answer = answer;
}
public Set<Link> getLinks() {
    return this.links;
}

public void setLinks(Set<Link> links) {
    this.links = links;
}
}

Here's the POJO for the Link object:

public class Link  implements java.io.Serializable {
 private int linkId;
 private String url;
 private Set<FlashCard> flashcards = new HashSet<FlashCard>(0);

public Link() {
}
public Link(String url) {
    this.url = url;
}

public Link(String url, Set<FlashCard> flashcards) {
   this.url = url;
   this.flashcards = flashcards;
}

public int getLinkId() {
    return this.linkId;
}

public void setLinkId(int linkId) {
    this.linkId = linkId;
}
public String getUrl() {
    return this.url;
}

public void setUrl(String url) {
    this.url = url;
}
public Set<FlashCard> getFlashcards() {
    return this.flashcards;
}

public void setFlashcards(Set<FlashCard> flashcards) {
    this.flashcards = flashcards;
}
}

Here's the relevant part of the Action

public class FlashCardAction extends FlashCardsAppBaseAction implements ModelDriven<FlashCard>, Preparable, SessionAware {

static Logger logger = Logger.getLogger(FlashCardAction.class);

FlashCard flashCard = new FlashCard();

Map <String,Object> httpSession;

Session session;
FlashCardPersister fcPersister;

public Map<String, Object> getHttpSession() {
    return httpSession;
}

public FlashCard getFlashCard() {
    return this.flashCard;
}

public void setFlashCard(FlashCard flashCard) {
    this.flashCard = flashCard;
}

public void validate() {
    logger.debug("Entering validate()");

    if ( flashCard.getQuestion().length() == 0 ){
        addFieldError("flashCard.question", getText("error.flashcard.question"));
    }

    if ( flashCard.getAnswer().length() == 0 ) {
        addFieldError("flashCard.answer", getText("error.flashcard.answer"));
    }       
}

public String saveOrUpdate() {
    logger.debug("Entering saveOrUpdate()");

    // assume we'll fail
    boolean result = false;

    // are we creating a New Flash Card or Updating and existing one
    // for now, let's assume we开发者_如何学JAVA are creating a New Flash Card
    boolean newFlashCard = true;

    // if this is an Update of an existing Flash CArd then we'll have a Flash Card Id other than 0 
    if (this.flashCard.getFlashCardId() != 0) {
        newFlashCard = false;
    }

    try {
        result = fcPersister.saveOrUpdateFlashCard(this.flashCard, session);

        // did we save a new FlashCard successfully?
        if (result == true && newFlashCard) {
            logger.debug("Flash Card created successfully");

            this.addActionMessage(getText("actionmessage.flashcard.created"));
        }
        // did we update an existing Flash Card successfully?
        else if (result == true && newFlashCard == false) {
            logger.debug("Flash Card updated successfully");

            this.addActionMessage(getText("actionmessage.flashcard.updated"));                  
        } 
        // such a failure
        else {
            logger.error("unable to create or update FlashCard");
            return "error";
        }
        return "success";

    } catch (Exception e) {
        logger.error("Exception in createFlashCard():", e);

        return "error";
    }
}


@Override
public FlashCard getModel() {
    return this.flashCard;
}
@Override
public void setSession(Map<String, Object> httpSession) {
    this.httpSession = httpSession;

}
@Override
public void prepare() throws Exception {
    logger.debug("Entering prepare()");

    // get a handle to a Hibernate session
    session = getHibernateSession();

    // get a handle to the FlashCard persistance utility class 
    fcPersister = new FlashCardPersister();
}

}

And lastly here's the JSP

<%@page import="com.opensymphony.xwork2.ActionContext"%>
<%@page import="com.opensymphony.xwork2.ActionSupport"%>

<%@ page contentType="text/html; charset=UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sjr" uri="/struts-jquery-richtext-tags"%>

<h3><s:text name="label.flashcard.title"/></h3>

<s:actionerror theme="jquery" />
<s:actionmessage theme="jquery"/>
<s:fielderror theme="jquery"/>

<s:form action="saveOrUpdate" method="post">
    <s:hidden name="flashCard.flashCardId" />
    <s:textfield name="flashCard.question" key="label.flashcard.question" size="66" />
    <sjr:tinymce 
        id="flashCard.answer" 
        name="flashCard.answer" 
        key="label.flashcard.answer"
        rows="20" 
        cols="50" 
        editorTheme="simple"
    />
    <s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66" />
    <tr>
        <td>
            <s:submit label="label.flashcard.submit" align="center" theme="simple" />
        </td>
        <td>
            <s:submit key="label.flashcard.cancel" name="redirectAction:list" theme="simple"  />
        </td>
    </tr>
</s:form>

<%((ActionSupport)ActionContext.getContext().getActionInvocation().getAction()).clearErrorsAndMessages();%>


First of all I don't think you can use Set here, because Sets are unordered and you can't get an item from a set by an index or key like List and Map. The only way is to iterate through the set and get the items.
Second assuming you're using a collection other than set, in:

<s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66"/>

You try to set the value of the text field to url field of links which is a collection and doesn't have such a field. So you need to get the specific item from the collection you're editing and pass the value. Like:

<s:textfield name="flashCard.links[0].url" key="label.flashcard.link" size="66"/>

But since you can't get the specific item you are editing I suggest you create a link field in your Action and set the updated link to it. Then you can perform a logic to relace the updated link with obsolete one in you flashcards. Hope this helps.


Since you are using modeldriven and the model is FlashCard, i think the following

<sjr:tinymce 
    id="flashCard.answer" 
    name="flashCard.answer" 
    key="label.flashcard.answer"
    rows="20" 
    cols="50" 
    editorTheme="simple"/>

should be changed to

<sjr:tinymce 
    id="flashCard.answer" 
    name="answer" 
    key="label.flashcard.answer"
    rows="20" 
    cols="50" 
    value="answer" 
    editorTheme="simple"/>

the name field should be given without the prefix flashcard.also you should provide the 'value' attribute in order for it to be pre-populated.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜