2

動的フォーム フィールドを jsf フォームに追加しようとしています。しかし、単純なコードに従ってもエラーが発生します。

test.xhtml

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head></h:head>
<body>
<h:form id="form" binding="#{testBean.form}" />
<h:commandButton value="submit" action="#{testBean.submit}" />
</body>
</html>

フィールド.java

パッケージエンティティ;

パブリック クラス フィールド {

private String name;

public Field() {
    // TODO Auto-generated constructor stub
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

}

testBean.java

package beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;
import javax.faces.application.Application;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIInput;
import javax.faces.component.html.HtmlForm;
import javax.faces.component.html.HtmlInputText;
import javax.faces.context.FacesContext;

import Entity.*;

@ManagedBean
@ViewScoped
public class testBean implements Serializable{

    private static final long serialVersionUID = 770513161289990805L;
    private HtmlForm form = new HtmlForm();

    private List<Field> fields=new ArrayList<Field>(); 
    private Map<String, Object> values; 

    private Field field1 = new Field();
    private Field field2 = new Field();

    public testBean() {

        field1.setName("aaa");
        field2.setName("bbb");
        fields.add(field1);
        fields.add(field2);

        values = new HashMap<String, Object>();

    }

    private ValueExpression createValueExpression(String binding, Class clazz) {
        final ValueExpression ve = getExpressionFactory()
                .createValueExpression(getELContext(), binding, String.class);

        return ve;
    }

    public static ELContext getELContext() {

        return FacesContext.getCurrentInstance().getELContext();
    }

    public static ExpressionFactory getExpressionFactory() {

        return getApplication().getExpressionFactory();
    }

    public static Application getApplication() {

        return FacesContext.getCurrentInstance().getApplication();
    }

    @SuppressWarnings("el-syntax")
    public HtmlForm getForm() {
        if (form == null) {

            form = new HtmlForm();

            for (Field field : fields) {
                UIInput input = new HtmlInputText();
                input.setId(field.getName()); // Must be unique!
                String v = "#{testBean.values['" + field.getName() + "']}";
                input.setValueExpression("value",
                        createValueExpression(v, String.class));
                form.getChildren().add(input);

            }

        }
        return form;
    }

    public void setForm(HtmlForm form) {
        this.form = form;
    }

    public List<Field> getFields() {
        return fields;
    }

    public void setFields(List<Field> fields) {
        this.fields = fields;
    }

    public Map<String, Object> getValues() {
        return values;
    }

    public void setValues(Map<String, Object> values) {
        this.values = values;
    }

    public void submit() {
        System.out.println("Worked :)");
    }

}

上記の私のコードでは、「java.io.NotSerializableException: Entity.Field」エラーが発生します。

java.io.NotSerializableException: Entity.Field
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.util.HashMap.writeObject(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeArray(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.util.HashMap.writeObject(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    com.sun.faces.renderkit.ClientSideStateHelper.doWriteState(ClientSideStateHelper.java:325)
    com.sun.faces.renderkit.ClientSideStateHelper.writeState(ClientSideStateHelper.java:173)
    com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122)
    com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:166)
    com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:419)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.12 logs.

Field クラスを Serializable にすると、再びエラーが発生します。

HTTP Status 500 -

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.io.NotSerializableException: javax.faces.component.html.HtmlForm
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.util.HashMap.writeObject(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.defaultWriteFields(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeArray(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    java.util.HashMap.writeObject(Unknown Source)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    java.lang.reflect.Method.invoke(Unknown Source)
    java.io.ObjectStreamClass.invokeWriteObject(Unknown Source)
    java.io.ObjectOutputStream.writeSerialData(Unknown Source)
    java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source)
    java.io.ObjectOutputStream.writeObject0(Unknown Source)
    java.io.ObjectOutputStream.writeObject(Unknown Source)
    com.sun.faces.renderkit.ClientSideStateHelper.doWriteState(ClientSideStateHelper.java:325)
    com.sun.faces.renderkit.ClientSideStateHelper.writeState(ClientSideStateHelper.java:173)
    com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122)
    com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:166)
    com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
    com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:419)
    com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
    com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
    com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
    javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.12 logs.

Apache Tomcat/7.0.12

私の単純なコードの何が問題になっていますか? 前もって感謝します

4

1 に答える 1

1

Bean がビュー スコープに配置されます。ビュー スコープの Bean は、HTTP セッションに格納されます。HTTP セッションに保存されるオブジェクトはSerializable、そのすべてのプロパティを含めて である必要があります。ただし、のような UI コンポーネントHtmlFormは、その状態が要求ベースの変更に敏感であるという単純な理由でシリアライズできません。シリアライズ可能である場合、デシリアライズ後に破損/非同期状態が発生する可能性があります。

基本的に、Bean をリクエスト スコープに入れる必要があります。

ただし、このアプローチ全体は複雑すぎて欠陥があります。使用しないでください<h:form binding>。むしろ<h:dataTable>(または<ui:repeat>あなたが望むように)を使用してください。完全なキックオフの例は、この回答にあります: JSF コンポーネントを動的に追加する方法

于 2012-10-11T13:27:21.003 に答える