java.lang.NullPointerException durante la creazione DiskFileItem
-
29-09-2019 - |
Domanda
Sto cercando di scrivere un test di unità per la gestione di un controller file caricare con molla 3. Ora, se io mando l'immagine sopra al mio metodo di servizio attraverso il controller tutto funziona bene. Ma quando si fa un'unità dritto test Sto ottenendo un'eccezione di puntatore nullo.
Sembra che la proprietà "dfos" all'interno del DiskFilteItem
è nullo quando istanziata manualmente ma viene compilata quando il recupero di un MultipartFile
dal controllore.
File file = new File("//Users//test//Downloads//testimage.jpg");
log.info("found file: " +file.exists());
log.info("file size: " +file.length());
String fieldName = "field";
String contentType = "image/jpeg";
boolean isFormField = false;
String fileName = "testimage.jpg";
int sizeThreshold = 10240;
DiskFileItemFactory factory = new DiskFileItemFactory();
DiskFileItemFactory factory = new DiskFileItemFactory();
// throws null pointer
FileItem fi = factory.createItem(fieldName,contentType,isFormField,fileName);
// so does this one
DiskFileItem item = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, file);
MultipartFile f = new CommonsMultipartFile(item);
mi sento come mi manca qualcosa di stupido nel mio setup. Il mio file pom contiene le seguenti dipendenze.
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.0</version>
</dependency>
Questo codice genera la traccia seguente stack di
java.lang.NullPointerException at org.apache.commons.fileupload.disk.DiskFileItem.getSize(DiskFileItem.java:316) at org.springframework.web.multipart.commons.CommonsMultipartFile.(CommonsMultipartFile.java:60) at ImgurClientTest.testUploadImage(ImgurClientTest.java:58) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180) at org.junit.runner.JUnitCore.run(JUnitCore.java:157) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
Soluzione
mi sono imbattuto nello stesso problema. Il problema è che DiskFileItem.getSize()
è temporalmente accoppiato con DiskFileItem.getOutputStream()
dal fatto che un campo interno è inizializzato in getOutputStream
e utilizzato in getSize
.
La soluzione è quella di fare
final File TEST_FILE = new File("src/test/resources/test.jpg");
final DiskFileItem diskFileItem = new DiskFileItem("file", "image/jpeg", true, TEST_FILE.getName(), 100000000, TEST_FILE.getParentFile());
diskFileItem.getOutputStream();
prima di passare diskFileItem
al costruttore di CommonsMultipartFile
.
Altri suggerimenti
Che cosa significa questa parte di questa voce di registro?
log.info("found file: " +file.exists());
log.info("file size: " +file.length());
Ma penso che il problema potrebbe essere a causa di questo:
File file = new File("//Users//test//Downloads//");
E sembra che sta puntando a una directory invece di un file, quindi forse è per questo che si stanno ottenendo un NullPointerException
quando si vuole ottenere la dimensione di DiskFileItem
E se nessuna delle soluzioni di cui sopra lavorare per voi come è successo per me :) semplicemente fosso il DiskFileItem e utilizzare il soffietto soluzione:
final File fileToUpload = new File("src/test/resources/files/test.txt");
final MultiValueMap<String, Object> request = new LinkedMultiValueMap<String, Object>();
request.add("file", new FileSystemResource(fileToUpload.getAbsolutePath()));
Anche se non del tutto legato alla domanda. Ho incontrato la stessa eccezione durante la distribuzione del codice di caricamento file a GAE. Ho modificato il codice di systempuntoout da qui utilizzando apache fileupload su GAE (che utilizza i flussi di parte comuni apache) che poi hanno lavorato bene.
new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, file);
si traduce in un valore null
. Sguardo nel docs per vedere cosa c'è sbagliata o forse si passa un po 'di null
come parametri