I am trying to unit test an upload call but I get this error for the following code:
@MultipartConfig(maxFileSize = 3145728)
class WebServlet extends ScalatraServlet with FileUploadSupport {
override def isSizeConstraintException(e: Exception) = e match {
case se: ServletException if se.getMessage.contains("exceeds max filesize") ||
se.getMessage.startsWith("Request exceeds maxRequestSize") => true
case _ => false
}
error {
case e: SizeConstraintExceededException => RequestEntityTooLarge("too much!")
}
post("/uploadscript") {
val privateParam = try {params("private") != null && params("private").equals("true") } catch { case _ => false }
println("privateParam = " + privateParam)
val file = fileParams("file")
println(s"The size of the file is ${file.size}")
}
The error is:
java.lang.IllegalStateException: No multipart config for servlet
at org.eclipse.jetty.server.Request.getParts(Request.java:2064) ~[jetty-server-8.1.10.v20130312.jar:8.1.10.v20130312]
at org.scalatra.servlet.FileUploadSupport$class.getParts(FileUploadSupport.scala:133) ~[scalatra_2.10-2.2.1.jar:2.2.1]
at org.scalatra.servlet.FileUploadSupport$class.extractMultipartParams(FileUploadSupport.scala:108) ~[scalatra_2.10-2.2.1.jar:2.2.1]
at org.scalatra.servlet.FileUploadSupport$class.handle(FileUploadSupport.scala:79) ~[scalatra_2.10-2.2.1.jar:2.2.1]
at com.ui.WebServlet.handle(WebServlet.scala:32) ~[classes/:na]
And this is my unit test, and the first one succeeds, so it is finding my webservice:
class WebServletSpecification extends MutableScalatraSpec {
addServlet(classOf[WebServlet], "/*")
"GET /hello" should {
"return status 200" in {
get("/hello/testcomputer") {
status must_== 200
}
}
}
"POST /uploadscript" should {
"return status 200" in {
val scriptfile = "testfile"
val scriptname = "basescript"
post("/uploadscript", Map("private" -> "true"), Map("file" -> new File(scriptfile))) {
status must_== 200
}
}
}
}
I am running this inside of Eclipse and I am not certain what is going on.
It works fine with using HttpPost
and MultipartEntity
so it seems to be a problem with Eclipse or how the scalatra specification framework works.
Any idea what may be going wrong?
I don't have a separate web.xml.
I am only using jetty 8.1.10, as seen from what I use in build.sbt:
"org.eclipse.jetty" % "jetty-webapp" % "8.1.10.v20130312" % "container"
,
The error java.lang.IllegalStateException: No multipart config for servlet only happens if the app has called Request.getParts () but there is either no @MultipartConfig annotation on the servlet nor the equivalent <multipart-config> element in web.xml.
The annotation is detected by registering a jetty Decorator, which will introspect the Servlet to find the MultipartConfig annotation when the servlet instance is being commissioned.
The error you are getting is because the Servlet you in, that initiated the HttpServletRequest.getParts () call, doesn't have a Multipart Configuration (a requirement of the Servlet spec to be able to use that method). The next step (if the error didn't occur) would be to open the InputStream and start the processing of the multipart content.
By Steve Claridge on 2017-06-21. If you are creating a Java Servlet and you are getting the Unable to process parts as no multi-part configuration has been provided IllegalStateException error then you need to add the @MultipartConfig annotation to your class definition.
This is the solution I found when using ServletContextHandler and not WebAppContext. From here : https://bugs.eclipse.org/bugs/show_bug.cgi?id=395000
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import javax.servlet.MultipartConfigElement;
public class WebServer {
protected Server server;
public static void main(String[] args) throws Exception {
int port = 8080;
Server server = new Server(port);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
ServletHolder fileUploadServletHolder = new ServletHolder(new FileUploadServlet());
fileUploadServletHolder.getRegistration().setMultipartConfig(new MultipartConfigElement("data/tmp"));
context.addServlet(fileUploadServletHolder, "/fileUpload");
server.setHandler(context);
server.start();
server.join();
}
}
In case anyone else is looking for this in Jetty 9:
Add this to the request.handle( ... )
MultipartConfigElement multipartConfigElement = new MultipartConfigElement((String)null);
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, multipartConfigElement);
The @MultipartConfig
is a Servlet spec 3.0 annotation.
You'll need to add the appropriate artifacts and configuration to support annotation in your Jetty environment.
You'll want the jetty-annotations
and jetty-plus
artifacts.
Then you'll want to setup the test server with the appropriate configurations.
like this...
(I don't know the Scala specifics here, sorry)
package com.company.foo;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.FragmentConfiguration;
import org.eclipse.jetty.webapp.MetaInfConfiguration;
import org.eclipse.jetty.webapp.TagLibConfiguration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
import org.eclipse.jetty.webapp.WebXmlConfiguration;
public class EmbedMe {
public static void main(String[] args) throws Exception {
int port = 8080;
Server server = new Server(port);
String wardir = "target/sample-webapp-1-SNAPSHOT";
WebAppContext context = new WebAppContext();
context.setResourceBase(wardir);
context.setDescriptor(wardir + "WEB-INF/web.xml");
context.setConfigurations(new Configuration[] {
new AnnotationConfiguration(), new WebXmlConfiguration(),
new WebInfConfiguration(), new TagLibConfiguration(),
new PlusConfiguration(), new MetaInfConfiguration(),
new FragmentConfiguration(), new EnvConfiguration() });
context.setContextPath("/");
context.setParentLoaderPriority(true);
server.setHandler(context);
server.start();
server.join();
}
}
This is from the https://github.com/jetty-project/embedded-servlet-3.0 example project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With