J'ai écrit une classe transformateur qui prend un HttpServletRequest et le transforme en un autre type qui contient un pointeur vers le InputStream de la requête servlet. (L'idée est d'abstraire le protocole de transport entrant de la gestion de la requête, donc je pourrais également écrire un transformateur similaire à partir du FTP, par exemple.)
Maintenant, j'essaie d'écrire un test unitaire pour cela, et j'ai des problèmes. J'ai réussi à trouver le bon modèle de base pour créer une requête HTTP multipart valide (en utilisant les classes Spring MockMultipartHttpServletRequest et MockMultipartFile), mais maintenant j'obtiens une NullPointerException dans la méthode initialize()
de ma classe UploadRequest
. Je suppose que le problème est que d'une manière ou d'une autre le flux à l'intérieur de MockMultipartHttpServletRequest n'est pas initialisé correctement, mais je ne peux pas comprendre ce que je devrais faire différemment.
Toute suggestion serait grandement appréciée!
Voici la trace de la pile :
java.lang.NullPointerException
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:976)
at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:886)
at java.io.InputStream.read(InputStream.java:82)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:96)
at org.apache.commons.fileupload.util.Streams.copy(Streams.java:66)
at org.apache.commons.fileupload.MultipartStream.readBodyData(MultipartStream.java:592)
at org.apache.commons.fileupload.MultipartStream.discardBodyData(MultipartStream.java:618)
at org.apache.commons.fileupload.MultipartStream.skipPreamble(MultipartStream.java:637)
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.findNextItem(FileUploadBase.java:984)
at org.apache.commons.fileupload.FileUploadBase$FileItemIteratorImpl.(FileUploadBase.java:965)
at org.apache.commons.fileupload.FileUploadBase.getItemIterator(FileUploadBase.java:331)
at org.apache.commons.fileupload.servlet.ServletFileUpload.getItemIterator(ServletFileUpload.java:148)
at com.ooyala.UploadRequest.initialize(UploadRequest.java:51)
at com.ooyala.UploadRequestTest.testCreateFromServletRequest(UploadRequestTest.java:57)
Voici une version abrégée de ma classe transformateur :
public class UploadRequest {
private Map params;
private InputStream strIn;
private Logger Log = Logger.getLogger(UploadRequest.class.getName());
public UploadRequest()
{
params = new HashMap();
}
public void initialize(HttpServletRequest sRequest,
ServletFileUpload upload)
throws IOException, FileUploadException
{
Enumeration paramNames = sRequest.getParameterNames();
while (paramNames.hasMoreElements()) {
String pName = paramNames.nextElement();
params.put(pName, sRequest.getParameter(pName));
}
params.put("request_uri", sRequest.getRequestURI());
FileItemIterator iter = upload.getItemIterator(sRequest);
while (iter.hasNext()) {
FileItemStream item = iter.next();
try {
if (!item.isFormField()) {
// Skip form fields
params.put("original_file_name", item.getName());
strIn = item.openStream();
}
} catch (IOException ex) {
Log.severe("File uploading exception: " + ex.getMessage());
throw ex;
}
}
}
Et voici le test unitaire :
import org.springframework.mock.web.MockMultipartHttpServletRequest;
import org.springframework.mock.web.MockMultipartFile;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
// etc.... autres imports
@RunWith(JMock.class)
public class UploadRequestTest {
private UploadRequest upRequest;
@Before
public void setUp()
{
context.setImposteriser(ClassImposteriser.INSTANCE);
upRequest = new UploadRequest();
}
@Test
public void testCreateFromServletRequest()
throws IOException, FileUploadException
{
String text_contents = "hello world";
MockMultipartHttpServletRequest sRequest =
new MockMultipartHttpServletRequest();
sRequest.setMethod("POST");
String boundary = generateBoundary();
String contentType = "multipart/form-data; boundary="+boundary;
sRequest.setContentType(contentType);
sRequest.setRequestURI("/foo");
sRequest.addParameter("test_param","test_value");
sRequest.addFile(
new MockMultipartFile("file1","test_upload.txt","text/plain",
text_contents.getBytes()));
ServletFileUpload upload = new ServletFileUpload();
assertTrue(upload.isMultipartContent(sRequest));
upRequest.initialize(sRequest, upload);
}
}