使用Scalatra时,Jetty出现“没有servlet的multipartconfig”错误

9

我正在尝试对上传调用进行单元测试,但是以下代码出现了错误:

@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}")
  }

错误信息如下:
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]

这是我的单元测试,第一个测试通过了,说明它找到了我的 Web 服务:

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
      }
    }
  }
}

我正在Eclipse中运行这个程序,但是我不确定出了什么问题。

使用HttpPostMultipartEntity时一切正常,因此这似乎是Eclipse或scalatra规范框架的问题。

你有什么想法吗?

我没有单独的web.xml文件。

我只使用jetty 8.1.10,如在build.sbt中所示:

"org.eclipse.jetty" % "jetty-webapp" % "8.1.10.v20130312" % "container"

,

3个回答

9

如果其他人也在寻找Jetty 9中的解决方法:

将以下内容添加到request.handle(...)函数中

MultipartConfigElement multipartConfigElement = new MultipartConfigElement((String)null);
request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, multipartConfigElement);

这对我来说甚至无法编译,__MULTIPART_CONFIG_ELEMENT是未知字段。 - SRedouane
我刚刚检查了一下(我也讨厌过时的网络内容:)),我的Jetty版本是这样的: org.eclipse.jetty jetty-server 9.3.8.v20160314 - Richard
对于编译,Request 在 9.2 中是 org.eclipse.jetty.server.Request(但这对我来说并没有解决问题,现在我遇到了 java.io.IOException: Incomplete parts) - Terry Horner
谢谢,这在将Jetty从8.4升级到9.2后非常有效。 - Vincent Gerris

9

当使用ServletContextHandler而不是WebAppContext时,我找到的解决方案如下:从这里开始: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();
    }
}

2
@MultipartConfig 是一个Servlet规范3.0的注解。您需要添加适当的构件和配置来支持Jetty环境中的注解。
您需要使用 jetty-annotationsjetty-plus 构件。
然后,您需要设置测试服务器以进行适当的配置。
像这样... (我不知道Scala的具体情况,抱歉)
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();
    }
}

这是来自https://github.com/jetty-project/embedded-servlet-3.0示例项目。

谢谢。正如我所提到的,当我使用sbt(简单构建工具)启动它时,它可以正常工作,因为我可以通过使用访问Web服务器的junit测试来确定。但是,当我尝试使用specs2时,我认为这是由于在Eclipse中运行,它并没有起作用。我不想对此单元测试进行程序更改,而是要理解为什么它不能正常工作。 - James Black

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接