Comments (17)
"org.eclipse.jetty.multipartConfig" does not work when the spark-java application is converted to web app war file deployed in Tomcat.
from spark.
Yes that's true, queryParams will not work in case of multipart/form-data.
Solution: Actually you can get all the form data using the same idiom req.raw().getPart(<form-element-name>)
.
Let me illustrate this with an example:
I had the following form in HTML:
<form method="POST" enctype="multipart/form-data" action="/upload">
File to upload: <input type="file" name="file"><br />
Name: <input type="text" name="name"><br /><br />
<input type="submit" value="Upload"> Press here to upload the file!
</form>
I could get the input file using the method suggested by @briannesbitt , but I was not sure how to get the text-input name
.
But that is also encoded as a part, and can be retrieved using req.raw().getPart("name")
. This will return a Part
, from which you can get the input-stream using getInputStream()
, and then get the String
out of this stream by whatever method you like (though Apache Common's IOUtils provides a very convenient method [IOUtils.toString
](https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#toString%28java.io.InputStream, java.nio.charset.Charset%29) to get string from an input-stream).
The entire code that I used to process the form is thus:
Spark.post("/upload",(req,res)->{
if (req.raw().getAttribute("org.eclipse.jetty.multipartConfig") == null) {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
req.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
}
Part file = req.raw().getPart("file");
Part name = req.raw().getPart("name");
String filename = file.getSubmittedFileName();
if(name.getSize() > 0){
try{
filename = IOUtils.toString(name.getInputStream(), StandardCharsets.UTF_8);
} catch(Exception e){
e.printStackTrace();
}
}
Path filePath = Paths.get(".",filename);
Files.copy(file.getInputStream(),filePath);
return "Done!";
});
Hope this helped!
from spark.
I was using multipart request to post files to the server. To dump all uploaded files to the "upload" directory, I used Solution A at http://stackoverflow.com/questions/3337056/convenient-way-to-parse-incoming-multipart-form-data-parameters-in-a-servlet (the O'Reilly COS multipart parser), as following:
post(new Route("/upload") {
@Override
public String h(Request request, Response response) throws Exception {
final File upload = new File("upload");
if (!upload.exists() && !upload.mkdirs()) {
throw new RuntimeException("Failed to create directory " + upload.getAbsolutePath());
}
// this dumps all files contained in the multipart request to target directory.
final MultipartRequest req = new MultipartRequest(request.raw(), upload.getAbsolutePath());
halt(200);
return null;
}
});
from spark.
Thanks a ton, I ended up doing the same thing (thanks to your issue already opened) :-)
👍 for upload-related yak shaving!
from spark.
Apache commons-fileupload comes to the rescue! This example was written using spark 2.1
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<FileItem> 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();
String fileName = item.getName();
item.write(new File(dir, fileName));
halt(200);
return null;
});
from spark.
@shauvik thanks! That worked great for me.
from spark.
With spark 2.2 you could just do
if (req.raw().getAttribute("org.eclipse.multipartConfig") == null) {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
req.raw().setAttribute("org.eclipse.multipartConfig", multipartConfigElement);
}
Part part = req.raw().getPart(name);
With spark 2.3 it upgraded the jetty dependency so its now:
if (req.raw().getAttribute("org.eclipse.jetty.multipartConfig") == null) {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
req.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
}
Part part = req.raw().getPart(name);
Once you have a Part
you can access its input stream to get the bytes uploaded.
from spark.
Closing this, but will create a new issue about adding uploads to docs.
from spark.
hello! I want to process both forminput and multipart simultaneously how can I do it?
while using multipart/form-data request.queryParams is not working...
from spark.
Hi all,
I am using like this but still it gives me
javax.servlet.ServletException: Content-Type != multipart/form-data
post("/api/:username/videos/new", (req, res) ->{
if (req.raw().getAttribute("org.eclipse.jetty.multipartConfig") == null) {
//MultipartConfigElement multipartConfigElement = new MultipartConfigElement("/tmp");
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(System.getProperty("java.io.tmpdir"));
req.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
}
String username = req.params(":username");
//InputStream inputStream = req.raw().getPart("file").getInputStream();
Part uploadFile = req.raw().getPart("file");
});
from spark.
are you using enctype="multipart/form-data"
in the form HTML?
from spark.
thanks to all for opening this wonderful module and to all commentator.
but still I have one more problem based on this topic ....please help me..
here is the code and comment in code explain the problem...thanks in advance.
public class controller{
/* constructor
connect to Db */
abstract class FreemarkerBasedRoute extends Route {
final Template template;
protected FreemarkerBasedRoute(final String path, final String templateName) throws IOException {
super(path);
template = cfg.getTemplate(templateName);
}
.
.
main(){
get(new FreemarkerBasedRoute("/userHome/:name", "home.ftl") {
@Override
protected void doHandle(Request request, Response response, Writer writer) throws IOException, TemplateException {
SimpleHash root = new SimpleHash();
String name = request.params(":name"); // problem is here**
System.out.println("name:"+name);
root.put("name", name);
template.process(root, writer);
}
});
}
}
a href="/userHome/biren" >open /a // after clicking this link control goes to home.ftl
home.ftl
html
.
.
< img src="img.jpg" height="400" width="400" />
/html
console output:
name:biren //yup this is actual param**
name:img.jpg //but what is this?? src part of img tag!.**
from spark.
nope i'm using postman to test as of now, front-end is still in progress
from spark.
@vickey290 you some how need to ensure that the form data is encoded as multi part to able to use ^ req.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement)
and the exception javax.servlet.ServletException: Content-Type != multipart/form-data
basically says the same.
from spark.
Hello, I am trying to upload file using spark 2.2, java 8. Using the next Code:
https://groups.google.com/forum/#!msg/sparkjava/fjO64BP1UQw/CsxdNVz7qrAJ
post("/upload", "multipart/form-data", (request, response) -> {
//- Servlet 3.x config
String location = "/aaa/bbb"; // the directory location where files will be stored
long maxFileSize = 100000000; // the maximum size allowed for uploaded files
long maxRequestSize = 100000000; // the maximum size allowed for multipart/form-data requests
int fileSizeThreshold = 1024; // the size threshold after which files will be written to disk
MultipartConfigElement multipartConfigElement = new MultipartConfigElement(location, maxFileSize, maxRequestSize, fileSizeThreshold);
request.raw().setAttribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
//-/
Collection<Part> parts = request.raw().getParts();
for(Part part : parts) {
System.out.println("Name:");
System.out.println(part.getName());
System.out.println("Size: ");
System.out.println(part.getSize());
System.out.println("Filename:");
System.out.println(part.getSubmittedFileName());
}
String fName = request.raw().getPart("upfile").getSubmittedFileName();
System.out.println("Title: "+request.raw().getParameter("title"));
System.out.println("File: "+fName);
Part uploadedFile = request.raw().getPart("upfile");
Path out = Paths.get("/aaa/bbb/"+fName);
try (final InputStream in = uploadedFile.getInputStream()) {
Files.copy(in, out);
uploadedFile.delete();
}
// cleanup
multipartConfigElement = null;
parts = null;
uploadedFile = null;
return "OK";
});
I have the next problems:
- The interface part of servlet does not recognized the method getSubmittedFileName() , it generate the compile error can not find symbol.
- I delete the lines where this method is used, but when I tried to use post, the log show me:
IllegalStateException: No multipart config for servlet
I have no Idea what happen, please help me
thanks friends, excuse me if my english is not the best.
from spark.
@louiedecastro could you please explain your Tomcat issue? Maybe an error log and/or a code snippet from where your are using the request attribute.
I'm currently deploying an war file on Tomcat and uploading files to my application (using Spark 2.6.0) and everything is working fine here.
from spark.
I'm having a similar problem. I'm also using Tomcat!
This is my code
if (req.attribute("org.eclipse.jetty.multipartConfig") == null) {
final MultipartConfigElement multipartConfigElement = new MultipartConfigElement(FOTO_LOC);
req.attribute("org.eclipse.jetty.multipartConfig", multipartConfigElement);
}
try {
Collection<Part> parts = req.raw().getParts();
for(Part part : parts) {
System.out.println("Name:");
System.out.println(part.getName());
System.out.println("Size: ");
System.out.println(part.getSize());
System.out.println("Filename:");
System.out.println(part.getSubmittedFileName());
}
} catch (Exception ex) {
ex.printStackTrace();
}
And this is what it outputs when I try to post a file:
java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
at org.apache.catalina.connector.Request.parseParts(Request.java:2788)
at org.apache.catalina.connector.Request.getParts(Request.java:2754)
at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1098)
at javax.servlet.http.HttpServletRequestWrapper.getParts(HttpServletRequestWrapper.java:356)
at com.ciarama.integrator.routes.ComentarioRoutes.lambda$0(ComentarioRoutes.java:22)
at spark.RouteImpl$1.handle(RouteImpl.java:72)
at spark.http.matching.Routes.execute(Routes.java:61)
at spark.http.matching.MatcherFilter.doFilter(MatcherFilter.java:134)
at spark.servlet.SparkFilter.doFilter(SparkFilter.java:174)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:668)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:748)
The error occurs at Collection<Part> parts = req.raw().getParts();
I looked everywhere, changed some tomcat configs like allowCasualMultipartParsing
, but nothing works. This issue has stagnated my project, I have a deadline!
from spark.
Related Issues (20)
- Spark Java - strange behavior when uploading files HOT 1
- Information + announcement + request :: I have made a Java 17 compatible version that runs on jetty 11 jars HOT 3
- Response body not possible (null) if HTTP status code is 304 (not modified). HOT 2
- Exception in thread "main" java.lang.NoClassDefFoundError: spark/Route HOT 1
- Spark refusing to work inside docker container running ubuntu HOT 1
- How to start server HOT 1
- Why did you name the project spark , causing conflict with apache spark HOT 2
- NullPointerException in response.header(String, int) HOT 1
- How to hide Server details in the Response header ? HOT 1
- Is the Spark Java framework compatible with Java 17 HOT 4
- Why should we always have Content-Type been set ? HOT 1
- Redirect of POST request is getting as GET request which cause issue HOT 1
- Unable to serve static file using Spark Java HOT 2
- Streaming back dynamically-generated content
- Proper way to serve the same static file for multiple routes in the context of a single page application
- Adding route is not thread safe
- How can I turn off all these LOGS ?
- Job aborted due to stage failure
- Plans for upgrading to newer Java?
- Is the project Dead? HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from spark.