2012-10-31 57 views
3

我遇到了Java和Apache Wicket 1.5两个匿名类的封闭Java对象的身份已更改的问题!Wicket序列化问题与嵌套ModalWindow

在一个Wicket模态窗口中,我想创建第二个模态窗口(用于获取文本字符串提示),然后使用模型的AJAX刷新(字符串 - 整数对列表)更新原始模态窗口。

基本上我有两个匿名类在同一个方法中创建,但封闭实例的'this'指针在一个匿名类和另一个之间是不同的。

这似乎不像正常的预期的JVM行为,但我一直无法找到任何具体细节如何在Java规范中工作。

public class DropDownChoiceModal extends WebPage { 

    public String newTermResponse; 

    private void addAddTermModal() { 
     addTermModal = new ModalWindow("add_term_modal"); 
     addTermModal.setPageCreator(new ModalWindow.PageCreator() { 
      public Page createPage() { 
       PropertyModel pm = new PropertyModel<String>(DropDownChoiceModal.this, "newTermResponse"); 
       System.out.println ("propModel: " + System.identityHashCode(DropDownChoiceModal.this)); 
       return new TextInputModal(addTermModal, "What is the new term you wish to add?", pm); 
      } 
     }); 

     addTermModal.setWindowClosedCallback(new WindowClosedCallback() { 
     public void onClose(AjaxRequestTarget target) { 

      System.out.println ("propModel: " + System.identityHashCode(DropDownChoiceModal.this)); 
      System.out.println ("newTermResponse: " + DropDownChoiceModal.this.newTermResponse); 

      // If the value is set then use it 
      if (newTermAvailable()) { 

       // Add the new term to the model 
       model.add(new StringIntegerPair (newTermResponse, 0)); 

       System.out.println ("Update view: " + model.size()); 

       // Update the view 
       target.add(wmc); 
      } 
      System.out.println ("No new term"); 
     } 

     private boolean newTermAvailable() { 
      return (newTermResponse != null) && !newTermResponse.isEmpty(); 
     } 
    }); 

    add(addTermModal); 
    } 

对于TextInputModal类:

public class TextInputModal extends WebPage { 

public TextInputModal(final ModalWindow modal, String requestString, final IModel<?> model) { 
    Form<String> form = new Form<String>("form") { 
     public void onSubmit() { 
      System.out.println ("Submitted: " + System.identityHashCode(((PropertyModel)model).getTarget()) + "; " + model.getObject()); 
     } 
    }; 

    // Add the buttons 
    form.add(new AjaxButton("ok") { 
     public void onAfterSubmit(AjaxRequestTarget target, Form<?> form) { 
      System.out.println ("Submitted 2: " + System.identityHashCode(((PropertyModel)model).getTarget()) + "; " + model.getObject()); 
      modal.close(target); 
     } 
    }); 

    // Add the form 
    add(form); 
} 
} 

输出我得到:

propModel: 698650686 
Submitted: 698650686; fdsfds 
Submitted 2: 698650686; fdsfds 
propModel: 1447892364 
newTermResponse: null 
No new term 

为什么外围实例(DropDownChoiceModal.this)的身份匿名类之间改变任何想法1(新的ModalWindow.PageCreator(){})和匿名类2(新的WindowClosedCallback(){}),当它们在相同的方法(addAddTermModal())中创建?

在此先感谢...

奈杰尔

+1

也许是因为检票是免费序列化/反序列化要求之间的组件树。您可以通过添加一个'readResolve()'和一个'writeReplace()'方法来测试这个想法,该方法记录标识哈希代码。 – biziclop

+0

它在Java语言规范15.8.4中定义 - http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.8.4 –

+0

谢谢biziclop ...可能是有道理的...因为它在一个事件处理程序中,该对象在提交最上面的ModalWindow后被序列化和反序列化。 –

回答

0

非常感谢在上面的评论biziclop ......它看起来像在检票时重挫它是越来越序列化对象 - 在“newTermResponse的内容“在这个系列化期间,字符串在某处丢失。

我回到嵌套的例子ModalWindow在这里:

http://www.wicket-library.com/wicket-examples/ajax/modal-window

使用getPageReference作为代替PropertyModel解决了我的问题的例子所示()。

干杯,

奈杰尔

+0

一些更多的信息在这里:http://osdir.com/ml/users-wicket.apache.org/2009-05/msg00799.html –

+0

如果你没有一个页面,你不能使用PageReference,所以使用getSession() .setAttribute()和getSession()。getAttribute()在ModalWindow和父组件之间共享信息 –