복붙노트

[SPRING] ViewScoped Bean이 NotSerializableException을 발생시킵니다.

SPRING

ViewScoped Bean이 NotSerializableException을 발생시킵니다.

안녕하세요, 저는 ViewScoped Bean을 사용하고 있습니다. 문제는 그것을 호출 할 때 NotSerializableException이 발생한다는 것입니다.

이것은 내 Managed Bean의 코드입니다.

@ManagedBean(name="demandesBean")
@ViewScoped
public class DemandesBean implements Serializable {
    private static final long serialVersionUID = 1L;

    @ManagedProperty(value="#{demandeService}")
    private DemandeService demandeService; //A Spring Service

    @ManagedProperty(value="#{loginBean}")
    private LoginBean loginBean;

    private DemandeVO newDemande;

    @PostConstruct
    public void initData() {
        newDemande = new DemandeVO();
    }

    public void doAjouterDemande(ActionListener event) {
        demandeService.createDemande(newDemande, loginBean.getUsername());
        newDemande = new DemandeVO();
    }

    public List<DemandeVO> getListDemande() {
        return demandeService.getAllDemandesByUser(loginBean.getUsername());
    }

    public DemandeService getDemandeService() {
        return demandeService;
    }

    public void setDemandeService(DemandeService demandeService) {
        this.demandeService = demandeService;
    }

    public LoginBean getLoginBean() {
        return loginBean;
    }

    public void setLoginBean(LoginBean loginBean) {
        this.loginBean = loginBean;
    }

    public DemandeVO getNewDemande() {
        return newDemande;
    }

    public void setNewDemande(DemandeVO newDemande) {
        this.newDemande = newDemande;
    }
}

나는 다음과 같은 예외를 받았다.

GRAVE: Exiting serializeView - Could not serialize state: com.bull.congesJBPM.serviceImpl.DemandeServiceImpl
java.io.NotSerializableException: com.bull.congesJBPM.serviceImpl.DemandeServiceImpl

이 문제에 대한 모든 수정 ?? 도와주세요 !

해결법

  1. ==============================

    1.또 다른 문제는 MyFaces가 상태가 서버에 저장되는 경우에도 (기본값) 상태의 serialization을 기본적으로 수행한다는 것입니다. 이것은 차례로 뷰 범위의 뒷받침 빈을 직렬화 할 수 있어야합니다.

    또 다른 문제는 MyFaces가 상태가 서버에 저장되는 경우에도 (기본값) 상태의 serialization을 기본적으로 수행한다는 것입니다. 이것은 차례로 뷰 범위의 뒷받침 빈을 직렬화 할 수 있어야합니다.

    이 접근 방식의 장점은 역사가 진정한 역사라는 것입니다. 뒤로 버튼을 사용하여 이전보기 버전으로 돌아 가면 그 시점에 정확한 백킹 빈 버전을 실제로 얻을 수 있습니다.

    단점은 서비스 주입을 중단하는 것 (이 문제와 관련이 없으며 주요 성능 저하)입니다. EJB 서비스를 주입 할 때 똑같은 문제가 발생합니다.

    이 동작을 비활성화하려면 web.xml에 넣을 수있는 컨텍스트 매개 변수가 있습니다.

    <context-param>
        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    

    http://wiki.apache.org/myfaces/Performance를 참조하십시오.

    덧붙여서, Mojarra는 비슷한 설정을 가지고 있지만 기본값은 false입니다.

  2. ==============================

    2.@ ManagedProperty 주석 (ManagedBean 초기화에서 실행 됨)에서 EL을 통해 Spring 빈을 주입하는 대신에 다음과 같이 EL을 평가하는 빈을 얻는다. 실행 시간.

    @ ManagedProperty 주석 (ManagedBean 초기화에서 실행 됨)에서 EL을 통해 Spring 빈을 주입하는 대신에 다음과 같이 EL을 평가하는 빈을 얻는다. 실행 시간.

    이 방식을 사용하면 JSF 빈은 다음과 같이 보일 것이다.

    @ManagedBean(name="demandesBean")
    @ViewScoped
    public class DemandesBean implements Serializable {
        private static final long serialVersionUID = 1L;
    
        private static DemandeService demandeService() {
            return SpringJSFUtil.getBean("demandeService");
        }
    
        // ... 
        public void doAjouterDemande(ActionListener event) {
            demandeService().createDemande(newDemande, loginBean.getUsername());
            newDemande = new DemandeVO();
        }
        // ...
    

    그리고 여기에 사용 된 유틸리티 클래스 인 SpringJSFUtil.java가 있습니다.

    import javax.faces.context.FacesContext;
    
    public class SpringJSFUtil {
    
        public static <T> T getBean(String beanName) {
            if (beanName == null) {
                return null;
            }
            return getValue("#{" + beanName + "}");
        }
    
        @SuppressWarnings("unchecked")
        private static <T> T getValue(String expression) {
            FacesContext context = FacesContext.getCurrentInstance();
            return (T) context.getApplication().evaluateExpressionGet(context,
                    expression, Object.class);
        }
    }
    

    이렇게하면 Spring bean 속성 (EL 평가를 몇 번 수행하는 대신에)이 필요 없으므로 처음부터 속성을 갖는 직렬화 문제를 피할 수 있습니다.

  3. ==============================

    3.ViewScoped 빈의 모든 것은 ViewState에 저장됩니다. 세션에서 ViewState 직렬화를 끌 수 있지만 세션 자체는 직렬화 될 수 있으며 문제는 다른 위치에서 발생합니다.

    ViewScoped 빈의 모든 것은 ViewState에 저장됩니다. 세션에서 ViewState 직렬화를 끌 수 있지만 세션 자체는 직렬화 될 수 있으며 문제는 다른 위치에서 발생합니다.

    Spring을 사용하는 솔루션은 Serializable Proxy를 사용한다.

    <aop:scoped-proxy proxy-target-class="true"/>
    

    스프링 빈은 프록시로 포장되어 직렬화가 가능하며 래핑 된 참조는 일시적이므로 비 직렬화 후에 스프링 컨텍스트에서 다시 읽습니다.

    그것은 기술적으로 elias 대답과 유사합니다. 오직 여러분 만이 bean마다 코드를 직접 작성할 필요는 없습니다. 당신은 aop을 사용합니다.

    당신은 내 질문을 볼 수 있습니다 : 더 많은 맥락에서 JSF 빈과 직렬화 문제.

  4. from https://stackoverflow.com/questions/3851561/viewscoped-bean-cause-notserializableexception by cc-by-sa and MIT license