«Не удалось десериализовать объект из байта []» при загрузке файла, когда в Wicket 7 открыты несколько вкладок - PullRequest
0 голосов
/ 18 апреля 2019

У нас есть большое приложение для калитки, в котором есть досадная ошибка. У нас есть форма с полем загрузки файла, и по большей части она работает нормально. Единственный раз, когда это не удается, это когда пользователь открыл несколько вкладок браузера. Затем мы получаем следующее исключение (один раз для каждой открытой вкладки):

java.lang.RuntimeException: Could not deserialize object from byte[]
    at org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:143)
    at org.apache.wicket.pageStore.AbstractPageStore.deserializePage(AbstractPageStore.java:152)
    at org.apache.wicket.pageStore.AbstractCachingPageStore.getPage(AbstractCachingPageStore.java:67)
    at com.sw.system4.ui.RemovablePageManagerProvider$1.getPage(RemovablePageManagerProvider.java:51)
    at org.apache.wicket.page.PageStoreManager$SessionEntry.getPage(PageStoreManager.java:231)
    at org.apache.wicket.page.PageStoreManager$PersistentRequestAdapter.getPage(PageStoreManager.java:393)
    at org.apache.wicket.page.AbstractPageManager.getPage(AbstractPageManager.java:82)
    at org.apache.wicket.page.PageManagerDecorator.getPage(PageManagerDecorator.java:50)
    at org.apache.wicket.page.PageAccessSynchronizer$2.getPage(PageAccessSynchronizer.java:246)
    at org.apache.wicket.DefaultMapperContext.getPageInstance(DefaultMapperContext.java:113)
    at org.apache.wicket.core.request.handler.PageProvider.getStoredPage(PageProvider.java:299)
    at org.apache.wicket.core.request.handler.PageProvider.isNewPageInstance(PageProvider.java:211)
    at org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.checkExpiration(AbstractBookmarkableMapper.java:335)
    at org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.processListener(AbstractBookmarkableMapper.java:309)
    at org.apache.wicket.core.request.mapper.AbstractBookmarkableMapper.mapRequest(AbstractBookmarkableMapper.java:369)
    at org.apache.wicket.request.mapper.CompoundRequestMapper.mapRequest(CompoundRequestMapper.java:147)
    at org.apache.wicket.request.cycle.RequestCycle.resolveRequestHandler(RequestCycle.java:189)
    at org.apache.wicket.request.cycle.RequestCycle.processRequest(RequestCycle.java:219)
    at org.apache.wicket.request.cycle.RequestCycle.processRequestAndDetach(RequestCycle.java:293)
    at org.apache.wicket.protocol.http.WicketFilter.processRequestCycle(WicketFilter.java:261)
    at org.apache.wicket.protocol.http.WicketFilter.processRequest(WicketFilter.java:203)
    at org.apache.wicket.protocol.http.WicketFilter.doFilter(WicketFilter.java:284)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2517)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2506)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.io.FileNotFoundException: C:\Program Files\Apache Software Foundation\Tomcat 7.0\temp\upload_d17f019a_9bfa_48c5_bc2c_6fc0bf74d233_00004982.tmp (The system cannot find the file specified)
    at java.io.FileInputStream.open0(Native Method)
    at java.io.FileInputStream.open(Unknown Source)
    at java.io.FileInputStream.(Unknown Source)
    at org.apache.commons.fileupload.disk.DiskFileItem.readObject(DiskFileItem.java:684)
    at sun.reflect.GeneratedMethodAccessor4472.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at java.io.ObjectStreamClass.invokeReadObject(Unknown Source)
    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.defaultReadFields(Unknown Source)

    ... lots of read lines snipped

    at java.io.ObjectInputStream.readSerialData(Unknown Source)
    at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
    at java.io.ObjectInputStream.readObject0(Unknown Source)
    at java.io.ObjectInputStream.readObject(Unknown Source)
    at org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:126)

FileUploadField находится в форме, которая является частью большей страницы, поэтому пользователь выбирает файл и загружает его с помощью кнопки отправки ajax, прежде чем двигаться дальше.

Form<?> uploadForm = new Form<Void>( "uploadForm" );
uploadForm.setMultiPart( true );
add( uploadForm );

IModel<List<FileUpload>> filesModel = Model.ofList( new ArrayList<>() );

uploadForm.add( new FileUploadField( "uploadField", filesModel) );

uploadForm.add( new AjaxBeforeSubmitLink( "loadLink" ) {

  private static final long serialVersionUID = 1L;

  @Override
  protected void onSubmit( AjaxRequestTarget target, Form<?> form ) {
    List<? extends FileUpload> files = filesModel.getObject();

    if ( l_files != null && !l_files.isEmpty() ) {
      callEntryModel.getObject().getVendorQuoteData().getFileUploads().addAll( files );
    }

    target.add( getUploadedFilesLabel() );
    target.add( getClearFilesLink() );

    onUpdateContractQuoteData( target );
  }
});

Панель загрузки является частью страницы в стиле «хлебных крошек» с использованием BreadCrumbPanels из расширений калитки. Часть загрузки находится на панели, которая затем заменяется следующей панелью в крошке. Именно на этой панели, когда они пытаются сделать что-либо, что приводит к вызову ajax, возникает ошибка.

Из того, что я могу сказать, есть какая-то функция хеширования клиентского запроса для определения имени временного файла для загрузки, который отличается для разных вкладок? У кого-нибудь еще была такая проблема, я не могу найти где-либо ссылки на нее.

Мы используем Java 8 / Wicket 7.10

Заранее спасибо

1 Ответ

1 голос
/ 18 апреля 2019

Кажется, на вашей странице есть ссылка на объект FileItem.

Wicket пытается десериализовать страницу из своего хранилища страниц и во время этого процесса пытается загрузить org.apache.commons.fileupload.disk.DiskFileItem, для которого больше нет файла поддержки.

Wicket FileUploadField имеет переходный поле - List<FileUpload>. Но поскольку он временный, он вообще не будет сериализован. Позже, когда будет вызван public List<FileUpload> getFileUploads(), это поле будет null, и Wicket будет использовать commons-fileupload API для его загрузки снова .

Мне кажется, что ваше приложение где-то хранит ссылку на DiskFileItem и поэтому сериализуется / десериализуется.

Вы можете использовать Wicket IObjectChecker , чтобы найти, где на него ссылаются. См. SessionChecker и DifferentPageChecker, чтобы узнать, как реализовать пользовательскую проверку.

...