2012-10-11 4 views
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> 

Field.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 :)"); 
    } 

} 

내 코드는 위의 "Entity.Field java.io.NotSerializableException"를 제공합니다.

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 

간단한 코드에는 어떤 것이 있습니까? 미리 감사드립니다.

답변

1

빈은 뷰 범위에 넣습니다. 보기 범위 Bean은 HTTP 세션에 저장됩니다. HTTP 세션에 저장된 객체는 모든 속성을 포함하여 Serializable이어야합니다. 그러나 HtmlForm과 같은 UI 구성 요소는 해당 상태가 요청 기반 변경에 민감하기 때문에 직렬화 될 수있는 간단한 이유만으로 직렬화 할 수 없습니다. 직렬화가 가능한 경우 직렬화 해제 후에 손상되거나 동기화되지 않은 상태가 될 수 있습니다.

기본적으로 콩을 요청 범위에 넣어야합니다.

그러나이 전체 접근법은 복잡하고 결함이 있습니다. <h:form binding>을 사용하지 마십시오. 오히려 <h:dataTable> (또는 <ui:repeat>)을 사용하십시오. 이 답변에서 완전한 시작 예제를 찾을 수 있습니다 : How to dynamically add JSF components

+0

감사합니다. Balusc, 귀하의 팁으로 코딩 생활이 더 쉬워졌습니다. – nsumer

관련 문제