提交表单时未填充POJO的集合

时间:2011-06-22 16:47:17

标签: struts2

我有一个名为“FlashCard”的POJO,它有一个名为“links”的字段,它是Link对象的集合(集合)。 当我向我的Action提交FORM时,所有POJO字段都填充了表单中除“链接”集合之外的值。我不知道为什么没有填充。

有关如何解决此问题或如何更好地解决此问题的任何建议将非常感激。

另外,我的POJO系列是一套。我使用的是套件而不是列表是否重要(或使事情复杂化)?

我在下面提供了我的代码的简化版本。

这是我的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;
}
}

这是Link对象的POJO:

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;
}
}

这是行动的相关部分

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 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();
}

}

最后这是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();%>

2 个答案:

答案 0 :(得分:1)

首先,我认为你不能在这里使用Set,因为集合是无序的,你不能通过索引或密钥来获取集合中的项目,如List和{{ 1}}。唯一的方法是遍历集合并获取项目 第二个假设您使用的是非集合的集合,在:

Map

您尝试将文本字段的值设置为<s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66"/> 的{​​{1}}字段,该字段是一个集合,但没有这样的字段。因此,您需要从正在编辑的集合中获取特定项目并传递值。像:

url

但由于您无法获取正在修改的特定项目,因此我建议您在links中创建一个<s:textfield name="flashCard.links[0].url" key="label.flashcard.link" size="66"/> 字段,并设置更新后的链接。然后,您可以执行逻辑以将更新的链接与您的抽认卡中的过时链接相关联。希望这会有所帮助。

答案 1 :(得分:0)

由于你使用的是modeldriven而且模型是FlashCard,我认为如下

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

应改为

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

名称字段应该没有前缀flashcard.al所以你应该提供'value'属性,以便预先填充它。