Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No multipartconfig for servlet error from Jetty using scalatra

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"

,

like image 389
James Black Avatar asked Aug 02 '13 15:08

James Black


People also ask

What is Java IllegalStateException-no multipart config for servlet?

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.

How to find the multipartconfig annotation in a servlet?

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.

Why HTTPServlet getparts () is not working?

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.

How to fix unable to process parts error in servlet?

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.


3 Answers

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();
    }
}
like image 106
Quentin Avatar answered Oct 05 '22 20:10

Quentin


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);
like image 25
Richard Avatar answered Oct 05 '22 19:10

Richard


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.

like image 38
Joakim Erdfelt Avatar answered Oct 05 '22 19:10

Joakim Erdfelt