Spring MockMvc multipart reading in zip file IOException: Stream closed -
i want test multipart controller reads zip file in , goes through of entries. here's controller method it:
@requestmapping(value = "/content/general-import", method = requestmethod.post) public modelandview handlegeneralupload( @requestparam("file") multipartfile file) throws ioexception { string signature = "retailer_group:*|channel:*|locale:de-at|industry:5499"; log.info("processing file archive: {} signature: {}.", file.getname(), signature); modelandview mav = new modelandview(); mav.setviewname("contentupload"); if (!file.isempty()) { byte[] bytes = file.getbytes(); zipinputstream zis = new zipinputstream(new bytearrayinputstream(bytes)); zipentry entry = null; while ((entry = zis.getnextentry()) != null) { // process each file, based on , whether directory etc. if (!entry.isdirectory()) { // if entry file, extract log.debug("processing entry: {}",entry.getname()); int length = (int) entry.getsize(); content contenttosave = null; if(entry.getname().contains("gif")) { contenttosave = content.makeimage(entry.getname(), content.gif, signature, getbytesfrom(zis, "gif")); } else if (entry.getname().contains("png")) { contenttosave = content.makeimage(entry.getname(), content.png, signature, getbytesfrom(zis, "png")); } else if (entry.getname().contains("jpeg")) { contenttosave = content.makeimage(entry.getname(), content.jpeg, signature, getbytesfrom(zis, "jpeg")); } else if (entry.getname().contains("json")) { contenttosave = content.makefile(entry.getname(), content.json, signature, getstringfrom(zis, length)); } else if (entry.getname().contains("js")) { contenttosave = content.makefile(entry.getname(), content.js, signature, getstringfrom(zis, length)); } else if (entry.getname().contains("css")) { contenttosave = content.makefile(entry.getname(), content.css, signature, getstringfrom(zis, length)); } content contentaleadythere = contentservice.fetch(entry.getname()); if(contentaleadythere != null) { log.warn("replacing file: {} uploaded version.", contenttosave.getname()); } contentservice.put(contenttosave); log.info("persisted file: {} uploaded version.", contenttosave.getname()); } } mav.addobject("form", uploadviewmodel.make("/content/general-import", "updated content file")); return mav; } else { mav.addobject("form", uploadviewmodel.make("/content/general-import", "could not update content file")); return mav; } }
now associated test follows:
@test public void testprocessinggeneralupload() throws exception {
resource template = wac.getresource("classpath:lc_content/content.zip"); mockmultipartfile firstfile = new mockmultipartfile( "file", "filename.zip", mediatype.application_octet_stream_value, template.getinputstream()); mvcresult mvcresult = mockmvc.perform(mockmvcrequestbuilders.fileupload("/content/general-import") .file(firstfile)) .andexpect(status().isok()) .andexpect(view().name("contentupload")) .andexpect(model().attributeexists("form")).andreturn(); // processing assertions modelmap modelmap = mvcresult.getmodelandview().getmodelmap(); object object = modelmap.get("form"); assertthat(object, is(not(nullvalue()))); assertthat(object, is(instanceof(uploadviewmodel.class))); uploadviewmodel addmodel = (uploadviewmodel) object; assertthat(addmodel.getmessage(), is(notnullvalue())); assertthat(addmodel.getposturl(), is(notnullvalue())); assertthat(addmodel.getposturl(), is("/content/general-import")); assertthat(addmodel.getmessage(), is("updated content file")); // persistence assertions
}
the error is:
java.io.ioexception: stream closed @ java.util.zip.zipinputstream.ensureopen(zipinputstream.java:67) @ java.util.zip.zipinputstream.getnextentry(zipinputstream.java:116) @ com.touchcorp.touchpoint.resource.mvc.contentuploadresource.handlegeneralupload(contentuploadresource.java:221) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ org.springframework.web.method.support.invocablehandlermethod.invoke(invocablehandlermethod.java:215) @ org.springframework.web.method.support.invocablehandlermethod.invokeforrequest(invocablehandlermethod.java:132) @ org.springframework.web.servlet.mvc.method.annotation.servletinvocablehandlermethod.invokeandhandle(servletinvocablehandlermethod.java:104) @ org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter.invokehandlemethod(requestmappinghandleradapter.java:749) @ org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter.handleinternal(requestmappinghandleradapter.java:689) @ org.springframework.web.servlet.mvc.method.abstracthandlermethodadapter.handle(abstracthandlermethodadapter.java:83) @ org.springframework.web.servlet.dispatcherservlet.dodispatch(dispatcherservlet.java:938) @ org.springframework.web.servlet.dispatcherservlet.doservice(dispatcherservlet.java:870) @ org.springframework.web.servlet.frameworkservlet.processrequest(frameworkservlet.java:961) @ org.springframework.web.servlet.frameworkservlet.dopost(frameworkservlet.java:863) @ javax.servlet.http.httpservlet.service(httpservlet.java:646) @ org.springframework.web.servlet.frameworkservlet.service(frameworkservlet.java:837) @ org.springframework.test.web.servlet.testdispatcherservlet.service(testdispatcherservlet.java:62) @ javax.servlet.http.httpservlet.service(httpservlet.java:727) @ org.springframework.mock.web.mockfilterchain$servletfilterproxy.dofilter(mockfilterchain.java:170) @ org.springframework.mock.web.mockfilterchain.dofilter(mockfilterchain.java:137) @ org.springframework.test.web.servlet.mockmvc.perform(mockmvc.java:141) @ com.touchcorp.touchpoint.resource.mvc.contentuploadresourceunittest.testprocessinggeneralupload(contentuploadresourceunittest.java:190) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ sun.reflect.delegatingmethodaccessorimpl.invoke(delegatingmethodaccessorimpl.java:43) @ org.junit.runners.model.frameworkmethod$1.runreflectivecall(frameworkmethod.java:47) @ org.junit.internal.runners.model.reflectivecallable.run(reflectivecallable.java:12) @ org.junit.runners.model.frameworkmethod.invokeexplosively(frameworkmethod.java:44) @ org.junit.internal.runners.statements.invokemethod.evaluate(invokemethod.java:17) @ org.junit.internal.runners.statements.runbefores.evaluate(runbefores.java:26) @ org.springframework.test.context.junit4.statements.runbeforetestmethodcallbacks.evaluate(runbeforetestmethodcallbacks.java:74) @ org.springframework.test.context.junit4.statements.runaftertestmethodcallbacks.evaluate(runaftertestmethodcallbacks.java:83) @ org.springframework.test.context.junit4.statements.springrepeat.evaluate(springrepeat.java:72) @ org.springframework.test.context.junit4.springjunit4classrunner.runchild(springjunit4classrunner.java:232) @ org.springframework.test.context.junit4.springjunit4classrunner.runchild(springjunit4classrunner.java:89) @ org.junit.runners.parentrunner$3.run(parentrunner.java:238) @ org.junit.runners.parentrunner$1.schedule(parentrunner.java:63) @ org.junit.runners.parentrunner.runchildren(parentrunner.java:236) @ org.junit.runners.parentrunner.access$000(parentrunner.java:53) @ org.junit.runners.parentrunner$2.evaluate(parentrunner.java:229) @ org.springframework.test.context.junit4.statements.runbeforetestclasscallbacks.evaluate(runbeforetestclasscallbacks.java:61) @ org.springframework.test.context.junit4.statements.runaftertestclasscallbacks.evaluate(runaftertestclasscallbacks.java:71) @ org.junit.runners.parentrunner.run(parentrunner.java:309) @ org.springframework.test.context.junit4.springjunit4classrunner.run(springjunit4classrunner.java:175) @ org.junit.runner.junitcore.run(junitcore.java:160) @ com.intellij.junit4.junit4ideatestrunner.startrunnerwithargs(junit4ideatestrunner.java:74) @ com.intellij.rt.execution.junit.junitstarter.preparestreamsandstart(junitstarter.java:211) @ com.intellij.rt.execution.junit.junitstarter.main(junitstarter.java:67) @ sun.reflect.nativemethodaccessorimpl.invoke0(native method) @ sun.reflect.nativemethodaccessorimpl.invoke(nativemethodaccessorimpl.java:62) @ com.intellij.rt.execution.application.appmain.main(appmain.java:120)
what seems issue can't seem construct mockmultipartfile in right state. guess 1 work around refactor of processing logic separate method , test out-of-container, i'd rather keep logic in 1 place. can tell me how instantiate mockmultipartfile can read content.zip?
found answer, needed replace line:
mockmultipartfile firstfile = new mockmultipartfile( "file", "filename.zip", mediatype.application_octet_stream_value, template.getinputstream());
with:
mockmultipartfile firstfile = new mockmultipartfile( "file", "filename.zip", mediatype.application_octet_stream_value, new zipinputstream(template.getinputstream()));
although, have new problem: file empty, in other words: file.isempty() in controller returns true.
edit
and has answer, replaced line again with:
mockmultipartfile firstfile = new mockmultipartfile( "file", "content.zip", mediatype.application_octet_stream_value, extractfile(template.getfile()));
where extractfile is:
private byte[] extractfile(file zipfile) throws ioexception { zipinputstream zipin = new zipinputstream(new fileinputstream(zipfile)); system.out.println("length of file: " + zipfile.length()); byte[] output = null; try { byte[] data = new byte[(int)zipfile.length()]; zipin.read(data); zipin.close(); output = data; } catch (ioexception e) { e.printstacktrace(); } return output; }
it seems need read in data stream in order bytes filled. still not solved, see: how go spring mvc multipartfile zipinputstream discussion on that.
Comments
Post a Comment