Struts2 波乔';提交表单时未填充的集合

Struts2 波乔';提交表单时未填充的集合,struts2,Struts2,我有一个名为“FlashCard”的POJO,其中有一个名为“links”的字段,它是链接对象的集合(集合)当我将表单提交到我的操作时,所有POJO字段都会填充表单中的值,但“链接”集合除外。我不知道为什么这里没有人烟。 任何关于如何解决此问题或如何更好地排除故障的建议都将不胜感激 另外,我的POJO系列是一套。我使用的是集合而不是列表,这有关系(或使事情复杂化)吗 下面是我的代码的简化版本 这是我的想法: public class FlashCard implements java.io.S

我有一个名为“FlashCard”的POJO,其中有一个名为“links”的字段,它是链接对象的集合(集合)当我将表单提交到我的操作时,所有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;
}
}
公共类FlashCard实现java.io.Serializable{
私有int FlashCard;
私有字符串问题;
私有字符串应答;
私有集链接=新哈希集(0);
公共抽认卡(){
}
公共抽认卡(字符串问题,字符串答案){
这个问题=问题;
这个答案=答案;
}
公共抽认卡(字符串问题、字符串答案、设置链接){
这个问题=问题;
这个答案=答案;
this.links=链接;
}
public int getFlashCardId(){
把这个还给我;
}
公共无效setFlashCardId(int flashCardId){
this.flashcard=flashcard;
}
公共字符串getQuestion(){
回答这个问题;
}
公共问题(字符串问题){
这个问题=问题;
}
公共字符串getAnswer(){
回答这个问题;
}
公共无效设置应答(字符串应答){
这个答案=答案;
}
公共集getLinks(){
返回此链接;
}
公共无效设置链接(设置链接){
this.links=链接;
}
}
以下是链接对象的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类链接实现java.io.Serializable{
私有int-linkId;
私有字符串url;
私有集flashcards=新哈希集(0);
公共链接(){
}
公共链接(字符串url){
this.url=url;
}
公共链接(字符串url,设置抽认卡){
this.url=url;
this.flashcards=flashcards;
}
public int getLinkId(){
返回此.linkId;
}
public void setLinkId(int linkId){
this.linkId=linkId;
}
公共字符串getUrl(){
返回this.url;
}
公共void setUrl(字符串url){
this.url=url;
}
公共集getFlashcards(){
归还这张卡片;
}
公共作废设置抽认卡(设置抽认卡){
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();
}

}
公共类FlashCardAction扩展了FlashCardSappaseAction实现了模型驱动、可准备的SessionAware{
静态记录器=Logger.getLogger(FlashCardAction.class);
FlashCard FlashCard=新的FlashCard();
Map-httpSession;
会议;
FlashCardPersister;
公共映射getHttpSession(){
返回httpSession;
}
公共FlashCard getFlashCard(){
归还这张卡片;
}
公共无效设置FlashCard(FlashCard FlashCard){
this.flashCard=flashCard;
}
public void validate(){
debug(“输入validate()”);
如果(flashCard.getQuestion().length()==0){
addFieldError(“flashCard.question”,getText(“error.flashCard.question”);
}
如果(flashCard.getAnswer().length()==0){
addFieldError(“flashCard.answer”,getText(“error.flashCard.answer”);
}       
}
公共字符串saveOrUpdate(){
debug(“输入saveOrUpdate()”;
//假设我们会失败
布尔结果=假;
//我们是在创建新的闪存卡还是在更新现有闪存卡
//现在,让我们假设我们正在创建一个新的闪存卡
布尔值newFlashCard=true;
//如果这是对现有闪存卡的更新,那么我们将使用除0之外的闪存卡Id
if(this.flashCard.getFlashCardId()!=0){
newFlashCard=false;
}
试一试{
结果=fcPersister.saveOrUpdateFlashCard(this.flashCard,会话);
//我们是否成功保存了新的闪存卡?
if(结果==true&&newFlashCard){
logger.debug(“已成功创建闪存卡”);
this.addActionMessage(getText(“actionmessage.flashcard.created”);
}
//我们是否成功更新了现有闪存卡?
else if(结果==true&&newFlashCard==false){
logger.debug(“闪存卡更新成功”);
this.addActionMessage(getText(“actionmessage.flashcard.updated”);
} 
//这样的失败
否则{
logger.错误(“无法创建或更新闪存卡”);
返回“错误”;
}
返回“成功”;
}捕获(例外e){
logger.error(“createFlashCard()中的异常:”,e);
返回“错误”;
}
}
@凌驾
公共FlashCard getModel(){
归还这张卡片;
}
@凌驾
公共无效设置会话(映射httpSession){
this.httpSession=httpSession;
}
@凌驾
public void prepare()引发异常{
debug(“输入prepare()”);
//获取Hibernate会话的句柄
会话=getHibernateSession();
//获取FlashCard持久性实用程序类的句柄
fcPersister=新的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();%>

由于您使用的是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。此外,您还应提供“value”属性,以便对其进行预填充。

首先,我认为您不能在此处使用
Set
,因为集合是无序的,您无法通过
List
Map
等索引或键从集合中获取项目。唯一的方法是遍历集合并获取项目。
第二,假设您使用的是集合以外的集合,在:

<s:textfield name="flashCard.links.url" key="label.flashcard.link" size="66"/>
但是,由于您无法获取正在编辑的特定项目,我建议您在
操作中创建一个
链接
字段,并设置
<s:textfield name="flashCard.links[0].url" key="label.flashcard.link" size="66"/>