【问题标题】:JSF nested objects set to null on submitJSF 嵌套对象在提交时设置为空
【发布时间】:2017-11-20 00:42:13
【问题描述】:

我面临这个 SO 线程 Why does JSF null out a nested class successfully instantiated in the backing bean? 中描述的类似问题 我有一个简单的表单(JSF-2.2)来创建一个具有多个嵌套对象及其各自属性的对象。实例化成功发生,我可以看到所有对象及其子对象不为空,但由于某种原因,当我提交表单时,整个对象树再次设置为空。在下面的示例中,值模板将导致

javax.el.PropertyNotFoundException: 目标无法到达,'null' 返回 null。

因为出于某种原因,ArticleListConfiguration 在提交之前被设置为 null。

<ui:composition template="../template/template.xhtml">
<ui:define name="content">
    <h:form id="createArticleListForm">
        <p:panel styleClass="content-panel">
            <h:panelGrid
                    columns="2"
                    styleClass="borderless-grid"
                    columnClasses="create-article-list-panel, create-article-list-panel">
                <p:panel
                        id="listValuesPanel">
                    <p:inputText
                            id="articleListName"
                            value="#{createArticleListController.articleList.name}"/>
                    <p:inputText
                            id="articleListSize"
                            maxlength="3"
                            value="#{createArticleListController.articleListSize}">
                    </p:inputText>
                    <p:selectBooleanCheckbox
                            id="saveArticleListConfigurationAsTemplate"
                            value="#{createArticleListController.articleList.articleListConfiguration.template}"/>
                    <h:panelGrid
                            columns="1">
                        <p:fileUpload
                                id="upload"
                                widgetVar="fileUploadWidget"
                                fileUploadListener="#{createArticleListController.uploadImages}"
                                multiple="true"
                                onstart="submitSelection()"
                                oncomplete="handleMultiFileUploadRequest(PF('fileUploadWidget'));"
                                allowTypes="/(\.|\/)(jpg|png)$/"
                                styleClass="ui-widget"/>
                        <p:remoteCommand
                                name="submitSelection"
                                process="@this"/>
                    </h:panelGrid>
                </p:panel>
            </h:panelGrid>
            <br/>
            <p:commandButton
                    id="createArticleListButton"
                    process="@this @form"
                    value="#{contentController.getContent('createArticleList')}"
                    actionListener="#{createArticleListController.onCreate()}"/>
        </p:panel>
    </h:form>
</ui:define>

这是支持 bean

@ManagedBean
@ViewScoped
public class CreateArticleListController extends AbstractController {

@Inject
private ArticleListService articleListService;

private ArticleList articleList;
private Integer articleListSize;
private List<Pair<String, InputStream>> files;


@PostConstruct
public void init() {
    //The constructor of ArticleList creates and attaches instances of all necessary nested objects
    articleList = new ArticleList();
    files = new ArrayList<>();
}

public void onCreate() throws IOException {
    articleListService.create(articleList, files);
    navigateTo("articleListOverview");
}

public void uploadImages(FileUploadEvent event) {
    try {
        files.add(Pair.of(event.getFile().getFileName(), event.getFile().getInputstream()));
    } catch (IOException e) {
        LOGGER.log(Level.ERROR, "Error uploading files");
        JsfMessageUtils.sendErrorMessageToUser("Error uploading files");
    }
}

public ArticleList getArticleList() {
    return articleList;
}

public void setArticleList(ArticleList articleList) {
    this.articleList = articleList;
}

public Integer getArticleListSize() {
    return articleListSize;
}

}

【问题讨论】:

    标签: jsf primefaces nested submit jsf-2.2


    【解决方案1】:

    缺少二传手

    private Integer articleListSize;
    

    p:inputText 找不到它。

    添加

    public void setArticleListSize(Integer articleListSize) {
        this.articleListSize = articleListSize;
    }
    

    CreateArticleListController

    还要确保 ArticleList 类及其子类已定义所有引用的 getter 和 setter。

    更新:

    我创建的控制器工作正常与您的原始 xhtml 页面

    //...
    import javax.faces.bean.ViewScoped;
    //...
    
    @ManagedBean(name = "createArticleListController")
    @ViewScoped
    public class CreateArticleListController implements Serializable {
    
        ArticleList articleList;
        private Integer articleListSize;
    
        @PostConstruct
        public void init() {
            System.out.println("On init controller");
            // initiliazing data
            articleList = new ArticleList();
            articleList.setName("List 1");
            //if you omit following lines, you will get the same exception posted in your question
            ArticleListConfiguration ac = new ArticleListConfiguration();
            ac.setTemplate(false);
            articleList.setArticleListConfiguration(ac);
        }
    
        public ArticleList getArticleList() {
            return articleList;
        }
    
        public void setArticleList(ArticleList articleList) {
            this.articleList = articleList;
        }
    
        public Integer getArticleListSize() {
            return articleListSize;
        }
    
        public void setArticleListSize(Integer articleListSize) {
            this.articleListSize = articleListSize;
        }
    
        public void onCreate() throws IOException {
            System.out.printf("On create -> Article name: %s, size: %s, template: %s\r\n", articleList.getName(), articleListSize, articleList.getArticleListConfiguration().isTemplate());
        }
    
        public void uploadImages(FileUploadEvent event) {
            System.out.println("On upload image " + event.getFile().getFileName());
        }
    }
    

    因此,ArticleList 或其他对象的初始化过程肯定缺少某些东西。使用您的页面运行我的示例控制器并检查它是否工作正常并将您的调试范围缩小到问题中未发布的控制器部分。

    【讨论】:

    • 抱歉,忘记将这个设置器复制到一个最小的工作示例中。我真正的控制器有点大,肯定包括那个二传手。我还检查了我的实体。我确实错过了一个实例化,但添加它根本没有解决问题。任何想法如何最好地调试?
    • 我没有其他想法。
    • 我已经用控制器更新了我的答案,该控制器可以在你的 xhtml 页面上正常工作。看看吧。
    • @JohnPlata:发布代码时请更加准确,始终、始终、始终创建minimal reproducible example。否则我们可能会把时间花在没有错的事情上……浪费时间……
    • “错误”的 viewscoped 是有效地使 bean requestscoped 的可能原因
    猜你喜欢
    • 2023-03-22
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 2016-04-29
    • 2020-02-17
    • 2019-02-12
    • 2019-10-28
    相关资源
    最近更新 更多