查看范围:java.io.NotSerializableException:javax.faces.component.html.HtmlInputText [英] View scope: java.io.NotSerializableException: javax.faces.component.html.HtmlInputText

查看:97
本文介绍了查看范围:java.io.NotSerializableException:javax.faces.component.html.HtmlInputText的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

每次按钮从后备豆调用操作时都会出错. 仅适用于具有视图范围的bean,并且我还没有找到一种方法来解决该问题,而无需在代码中的其他模块上进行回归.

There is an error each time a button calls an action from the backing-bean. Only applies to beans with a view scope and I haven't found a way to fix it without regression over other modules in the code.

DefaultFacele E   Exiting serializeView - Could not serialize state: javax.faces.component.html.HtmlInputText 
java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)

或者:

com.ibm.ws.webcontainer.servlet.ServletWrapper service SRVE0014E: Uncaught service() exception 
root cause Faces Servlet: ServletException: /jspFiles/jsf/Deployments/editQueue.faces No saved view state could be found for the view identifier /jspFiles/jsf/Deployments/editQueue.faces 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:205) 
Caused by: javax.faces.application.ViewExpiredException: /jspFiles/jsf/Deployments/editQueue.faces No saved view state could be found for the view identifier:  /jspFiles/jsf/Deployments/editQueue.faces
    at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute (RestoreViewExecutor.java:128)

faces-config.xml

faces-config.xml

<managed-bean>
  <managed-bean-name>pc_EditQueue</managed-bean-name>
  <managed-bean-class>pagecode.jspFiles.jsf.deployments.EditQueue</managed-bean-class>
  <managed-bean-scope>view</managed-bean-scope>
  <managed-property>
    <property-name>queueDeploymentBean</property-name>
    <value>#{queueDeploymentBean}</value>
  </managed-property>
</managed-bean>

web.xml

<context-param>
  <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
  <param-value>server</param-value>
</context-param>
<context-param>
  <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
  <param-value>true</param-value>
</context-param>

bean:

@ManagedBean
@ViewScoped
public class EditQueue extends PageCodeBase implements Serializable {
  private static final long serialVersionUID = -1L;
  public String doButtonAddAction() {
    // calls manager (long)
    FacesUtil.setViewMapValue("queueDeploymentBean", queueDeploymentBean);
    return "";
}

我阅读了此

I read this suggestion to set SERIALIZE_STATE_IN_SESSION to false and indeed this solution works for this view scope bean. However this fix comes at a high cost: many existing modules in the application don't work anymore so I cannot use this fix there. Some of the regression observed are:

// returns null must be changed with FacesUtil.getSessionMapValue("userId"); 
getSessionScope().get("userId");`

// returns null must be changed with FacesUtil.getViewMapValue("linkerBean");
linkerBean = (Linker) getManagedBean("linkerBean");`

// NPE so must be changed with FacesContext.getCurrentInstance().addMessage(...)
getFacesContext().addMessage(...)`

所以我的问题是:

  1. 为什么即使bean实现了Serializable,也为什么会出现NotSerializableException?
  2. 是否有一种方法可以仅将SERIALIZE_STATE_IN_SESSION参数应用到一部分bean?
  3. 是否有另一种解决方案可以使我的视图范围bean正常工作(而不必将其更改为请求范围)?

  1. why the NotSerializableException even though the bean implements Serializable ?
  2. is there a way to apply the SERIALIZE_STATE_IN_SESSION param over only a subset of the beans or not ?
  3. is there another solution to have my view scope bean to work (without having to change them to request scope or else) ?

WebSphere 8.0.0.3, Java 1.6.0, JSF 2.0, RichFaces 4.2.3.Final

WebSphere 8.0.0.3, Java 1.6.0, JSF 2.0, RichFaces 4.2.3.Final

推荐答案

为什么即使bean实现了Serializable,也为什么会出现NotSerializableException?

不仅bean需要可序列化,而且它的所有属性(及其所有嵌套属性等)也必须可序列化.可以在异常消息中轻松找到有问题的不可序列化类的名称:

Not only the bean needs to be serializable, but all of its properties (and all their nested properties etc) must also be serializable. The name of the offending non-serializable class can easily be found in the exception message:

java.io.NotSerializableException: javax.faces.component.html.HtmlInputText
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184)

这表明您正在将<h:inputText>组件绑定到Bean上,如下所示:

This suggests that you're binding a <h:inputText> component to the bean like below:

<h:inputText binding="#{bean.fooInput}" ...>

private UIComponent fooInput;

当bean不在请求范围内时,这确实是非法的. UIComponent实例在请求范围内,不能在多个请求之间共享.此外,UIComponent实例不能不可可序列化.只是他们的状态,但是JSF会自己担心这一切.

This is indeed illegal when the bean is not in request scope. UIComponent instances are request scoped and may not be shared across multiple requests. Moreover, UIComponent instances are not serializable. Only their state is, but JSF will worry about that all by itself.

您必须删除fooInput属性,并且需要为该问题寻找其他解决方案,对于该问题,您错误地认为将组件绑定到视图作用域的Bean是正确的解决方案.

You must remove the fooInput property and you need to look for a different solution for the problem for which you incorrectly thought that binding the component to a view scoped bean would be the right solution.

  • 如果您打算在视图的其他位置访问它,例如#{bean.fooInput.value},然后将其绑定到Facelet范围,而无需bean属性:

  • If you intend to access it elsewhere in the view, e.g. #{bean.fooInput.value}, then just bind it to the Facelet scope without the need for a bean property:

<h:inputText binding="#{fooInput}" ...>

它可以通过#{fooInput.xxx}在同一视图的其他位置使用.

It'll be available elsewhere in the same view via #{fooInput.xxx}.

<h:inputText ... required="#{empty fooInput.value}" />


  • 如果您打算以编程方式在Bean中设置某些组件属性,例如fooInput.setStyleClass("someClass")fooInput.setDisabled(true),则应绑定视图中的特定属性而不是整个组件:


  • If you intend to set some component attribute programmatically inside the bean, e.g. fooInput.setStyleClass("someClass"), or fooInput.setDisabled(true), then you should be binding the specific attribute in the view instead of the whole component:

    <h:inputText ... styleClass="#{bean.styleClass}" />
    ...
    <h:inputText ... disabled="#{bean.disabled}" />
    


  • 如果您完全肯定出于某种原因需要在Bean中获得整个UIComponent实例,那么请在方法本地作用域中手动获取它,而不是对其进行绑定:


  • If you are absolutely positive that you need to get a hand of whole UIComponent instance in the bean for whatever reason, then manually grab it in method local scope instead of binding it:

    public void someMethod() {
        UIViewRoot view = FacesContext.getCurrentInstance().getViewRoot();
        UIComponent fooInput = view.findComponent("formId:fooInputId");
        // ...
    }
    

    但是最好提出一个问题或寻找答案,以不同的方式解决具体问题,而无需在后备bean中获取整个组件.

    But better ask a question or search for an answer how to solve the concrete problem differently without the need to grab a whole component in the backing bean.

    关于ViewExpiredException,这有不同的依据,

    As to the ViewExpiredException, this has different grounds which is further elaborated in javax.faces.application.ViewExpiredException: View could not be restored.

    这篇关于查看范围:java.io.NotSerializableException:javax.faces.component.html.HtmlInputText的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    相关文章
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆