spark java: comment gérer les entrées multipart / form-data?

J’utilise spark pour développer une application web; le problème se produit lorsque je veux télécharger un fichier:

public final class SparkTesting { public static void main(final Ssortingng... args) { Spark.staticFileLocation("/site"); Spark.port(8080); Spark.post("/upload", (request, response) -> { final Part uploadedFile = request.raw().getPart("uploadedFile"); final Path path = Paths.get("/tmp/meh"); try (final InputStream in = uploadedFile.getInputStream()) { Files.copy(in, path); } response.redirect("/"); return "OK"; }); } } 

Mais je reçois cette erreur:

 [qtp509057984-36] ERROR spark.webserver.MatcherFilter - java.lang.IllegalStateException: No multipart config for servlet at org.eclipse.jetty.server.Request.getPart(Request.java:2039) at javax.servlet.http.HttpServletRequestWrapper.getPart(HttpServletRequestWrapper.java:361) at com.github.fge.grappa.debugger.web.SparkTesting.lambda$main$0(SparkTesting.java:20) at com.github.fge.grappa.debugger.web.SparkTesting$$Lambda$1/920011586.handle(Unknown Source) at spark.SparkBase$1.handle(SparkBase.java:264) at spark.webserver.MatcherFilter.doFilter(MatcherFilter.java:154) at spark.webserver.JettyHandler.doHandle(JettyHandler.java:60) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:179) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136) at org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) at org.eclipse.jetty.server.Server.handle(Server.java:451) at org.eclipse.jetty.server.HttpChannel.run(HttpChannel.java:252) at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:266) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:240) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:596) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:527) at java.lang.Thread.run(Thread.java:745) 

Et même si j’essaie de spécifier explicitement le type, comme dans:

 Spark.post("/upload", "multipart/form-data", etc etc) 

ça va encore échouer.

Je pourrais probablement trouver une bibliothèque pour parsingr des données multipart / form, saisir tout le contenu et juste m’parsingr moi-même, mais ce serait un gaspillage.

Puis-je configurer spark pour gérer ce cas?

La réponse fournie par Kai Yao est correcte, sauf que lorsque vous utilisez:

 request.raw().setAtsortingbute("org.eclipse.multipartConfig", multipartConfigElement); 

utilisez ceci à la place:

 request.raw().setAtsortingbute("org.eclipse.jetty.multipartConfig", multipartConfigElement); 

En ajoutant quelques lignes de code pour append la configuration multipart, vous pouvez gérer des données multipart / form sans une bibliothèque externe:

 public Object handle(Request request, Response response) { MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/tmp"); request.raw().setAtsortingbute("org.eclipse.multipartConfig", multipartConfigElement); .... Part file = request.raw().getPart("file"); //file is name of the upload form } 

Source: http://deniz.dizman.org/file-uploads-using-spark-java-micro-framework/

J’ai utilisé apache commons-fileupload pour gérer cela.

 post("/upload", (req, res) -> { final File upload = new File("upload"); if (!upload.exists() && !upload.mkdirs()) { throw new RuntimeException("Failed to create directory " + upload.getAbsolutePath()); } // apache commons-fileupload to handle file upload DiskFileItemFactory factory = new DiskFileItemFactory(); factory.setRepository(upload); ServletFileUpload fileUpload = new ServletFileUpload(factory); List items = fileUpload.parseRequest(req.raw()); // image is the field name that we want to save FileItem item = items.stream() .filter(e -> "image".equals(e.getFieldName())) .findFirst().get(); Ssortingng fileName = item.getName(); item.write(new File(dir, fileName)); halt(200); return null; }); 

Voir https://github.com/perwendel/spark/issues/26#issuecomment-95077039.

J’ai trouvé un exemple complet ici: https://github.com/tipsy/spark-file-upload/blob/master/src/main/java/UploadExample.java

 import spark.*; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.nio.file.*; import static spark.Spark.*; import static spark.debug.DebugScreen.*; public class UploadExample { public static void main(Ssortingng[] args) { enableDebugScreen(); File uploadDir = new File("upload"); uploadDir.mkdir(); // create the upload directory if it doesn't exist staticFiles.externalLocation("upload"); get("/", (req, res) -> "
" // note the enctype + " " // make sure to call getPart using the same "name" in the post + " " + "
" ); post("/", (req, res) -> { Path tempFile = Files.createTempFile(uploadDir.toPath(), "", ""); req.atsortingbute("org.eclipse.jetty.multipartConfig", new MultipartConfigElement("/temp")); try (InputStream input = req.raw().getPart("uploaded_file").getInputStream()) { // getPart needs to use same "name" as input field in form Files.copy(input, tempFile, StandardCopyOption.REPLACE_EXISTING); } logInfo(req, tempFile); return "

You uploaded this image:

"; }); } // methods used for logging private static void logInfo(Request req, Path tempFile) throws IOException, ServletException { System.out.println("Uploaded file '" + getFileName(req.raw().getPart("uploaded_file")) + "' saved as '" + tempFile.toAbsolutePath() + "'"); } private static Ssortingng getFileName(Part part) { for (Ssortingng cd : part.getHeader("content-disposition").split(";")) { if (cd.sortingm().startsWith("filename")) { return cd.subssortingng(cd.indexOf('=') + 1).sortingm().replace("\"", ""); } } return null; } }

Veuillez noter que dans cet exemple, pour parcourir tous les fichiers, utilisez javax.servlet.http.HttpServletRequest#getParts . Dans cet exemple également, au lieu d’parsingr le nom de fichier, vous pouvez simplement l’obtenir à l’aide de javax.servlet.http.Part#getSubmittedFileName . Et n’oubliez pas de fermer le stream que vous recevez. Et supprimez également le fichier à l’aide de javax.servlet.http.Part#delete si nécessaire