【问题标题】:File upload working under Jetty but not under Tomcat文件上传在 Jetty 下工作,但在 Tomcat 下不工作
【发布时间】:2014-07-05 02:24:34
【问题描述】:

我有一个带有 spring 的 web 应用程序,我在其中进行一些文件上传。在 Eclipse 下,使用 Jetty(maven 插件)可以完美运行。但是当我在 Tomcat 下部署应用程序时,它没有,我得到以下异常:

org.springframework.web.bind.MissingServletRequestParameterException: Required org.springframework.web.multipart.MultipartFile parameter 'file' is not present
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter$ServletHandlerMethodInvoker.raiseMissingParameterException(AnnotationMethodHandlerAdapter.java:545)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveRequestParam(HandlerMethodInvoker.java:336)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.resolveHandlerArguments(HandlerMethodInvoker.java:207)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:132)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:326)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:313)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)

这是我的表格:

<form method="post" action="../admin/import.html" id="import"
    enctype="multipart/form-data">
    <div id="importInmates" align="center">
        <input type="file" name="file" id="file"
            data-dojo-type="dijit.form.Button"
            label="<fmt:message key='import.file' />" />
        <button data-dojo-type="dijit.form.Button" id="importInmates"
            type="submit">
            <fmt:message key="import.import" />
        </button>
    </div>
    <input type="hidden" name="importType" value="inmates" />
</form>

这里是拦截方法:

    @RequestMapping(value = IMPORT_PAGE, method = RequestMethod.POST)
public String recieveFile(@RequestParam("importType") String importType,
        @RequestParam("file") MultipartFile multipartFile, final HttpSession session)
{
    if (multipartFile.getSize() < 0)
    {
        LOGGER.debug("No file has been uploaded");
        return "redirect:.." + IMPORT_PAGE;
    }

    File file = new File("tmp");

    try
    {
        multipartFile.transferTo(file);
        BufferedReader lec = new BufferedReader(new FileReader(file));

        LOGGER.debug(lec.readLine());
        lec.close();

    }
    catch (Exception e)
    {
        LOGGER.error("An exception occured while reading " + importType + " file", e);
    }

    return "redirect:.." + IMPORT_PAGE;
}

我添加了以下 bean:

<bean id="multipartResolver"
    class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="100000000"></property>
</bean>

在 applicationContext.xml 和 mvc-servlet.xml 中,即使我认为只有后者很重要。

任何帮助将不胜感激。

谢谢。

【问题讨论】:

  • 那里看起来有很多春天的魔法。看起来 Tomcat 与此无关。
  • 那么为什么它在 Jetty 下像一个魅力一样工作?
  • 我不知道。但这是一个 Spring 异常,它抱怨 Spring 配置显然不正确。为什么不给这个问题加上“Spring”标签?
  • 可能是因为我认为tomcat是这个问题的原因。但是感谢您添加标签。
  • 但为什么它在一种情况下有效,而在另一种情况下无效?

标签: java spring jsp tomcat maven-jetty-plugin


【解决方案1】:

感谢@Bart,我找到了以下简单的解决方案:

在拦截方法中,使用 @ModelAttribute 代替 @RequestParam :

@RequestMapping(value = IMPORT_PAGE, method = RequestMethod.POST)
public String recieveFile(@RequestParam("importType") String importType,
        @ModelAttribute("file") UploadedFile uploadedFile, final HttpSession session)
{
    MultipartFile multipartFile = uploadedFile.getFile();

UploadedFile 是以下类:

public class UploadedFile
{
    private String type;

    private MultipartFile file;

    public String getType()
    {
        return type;
    }

    public void setType(String type)
    {
        this.type = type;
    }

    public void setFile(MultipartFile file)
    {
        this.file = file;
    }

    public MultipartFile getFile()
    {
        return file;
    }
}

它正在工作!

感谢大家的帮助。

【讨论】:

    【解决方案2】:

    使用@RequestPart 代替@RequestParam

    来源:

    可用于关联“multipart/form-data”请求的部分的注解 带有方法参数。支持的方法参数类型包括 {@link MultipartFile} 结合 Spring 的 {@link MultipartResolver} 抽象, {@code javax.servlet.http.Part} 结合 Servlet 3.0 多部分请求, 否则对于任何其他方法参数,该部分的内容通过 {@link HttpMessageConverter} 考虑到“Content-Type”标头 请求部分。这类似于 @{@link RequestBody} 所做的解决 基于非多部分常规请求内容的参数。

    注意@{@link RequestParam}注解也可以用来关联 “multipart/form-data”请求的一部分,其方法参数支持相同 方法参数类型。主要区别在于,当方法参数不是 String, @{@link RequestParam} 依赖于通过注册的类型转换 {@link Converter} 或 {@link PropertyEditor} 而 @{@link RequestPart} 依赖 在 {@link HttpMessageConverter} 上考虑到“Content-Type”标头 请求部分。 @{@link RequestParam} 很可能与名称-值形式一起使用 字段,而 @{@link RequestPart} 可能与包含更多内容的部分一起使用 复杂的内容(例如 JSON、XML)。

    【讨论】:

    • 感谢@Bart 的回复,我尝试使用 RequestPart 但它包含在 spring 3.1 中,而我使用的是 2.5.6。所以我昨晚经历了一个依赖配置的噩梦来升级到更高版本的spring,但由于其他令人惊讶的错误我无法做到,所以我回到了2.5.6。现在,有没有办法通过 tomcat 配置启用/禁用文件上传?
    • Tomcat 不会进行任何文件上传,除非您使用 Servlet-3.0 注释或影响文件上传的 web.xml 指令。如果你想在 Spring 中禁用文件上传,我帮不了你。 (对不起!)
    猜你喜欢
    • 2011-09-05
    • 2013-01-22
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    相关资源
    最近更新 更多