【问题标题】:groovy upload file常规上传文件
【发布时间】:2015-06-17 04:46:50
【问题描述】:

我正在尝试为 grails/groovy 中的文件和视频编写上传器。 因此,每次用户填写新表单时,控制器都会上传文件并将文件名与其他字段一起保存到数据库中。所以,这里是保存过程:

def save = {
        def streamInstance = new Stream(params)
        if(request){
            MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
            CommonsMultipartFile uploadedFile = (CommonsMultipartFile)mpr.getFile("myFile");
            if(!uploadedFile.empty){
                println "helloworld"
                println "Class: ${uploadedFile.class}"
                println "Name: ${uploadedFile.name}"
                println "OriginalFileName: ${uploadedFile.originalFilename}"
                println "Size: ${uploadedFile.size}"
                println "ContentType: ${uploadedFile.contentType}"
                /*
                //def webRootDir = servletContext.getRealPath("/")
                //def userDir = new File(webRootDir, "/files/${session.user.login}")
                //userDir.mkdirs()
                uploadedFile.transferTo(new File("/Users/philipperibeiro/ctv/ctv/web-app/files"))
                streamInstance.file = uploadedFile.originalFilename
                */
            }
            else{
                flash.message = "file cannot be empty"
            }
        }
        if(!streamInstance.hasErrors() && streamInstance.save(flush : true)){
            flash.message = "${message(code: 'default.created.message', args : [message(code: 'stream.label', default:'Stream'), streamInstance.id])}"
            redirect(action : "show", id : streamInstance.id)
        }
        else{
            render(view : "create", model : [streamInstance : streamInstance])
        }
    }

我收到此错误: 错误 500:执行控制器 [ctv.StreamController] 的操作 [save] 导致异常:无法将具有类 'org.apache.catalina.core.ApplicationHttpRequest' 的对象 'org.apache.catalina.core.ApplicationHttpRequest@19f46c5d' 转换为类 ' org.springframework.web.multipart.MultipartHttpServletRequest' 小服务程序:grails URI:/ctv/grails/stream/save.dispatch 异常消息:无法将具有类“org.apache.catalina.core.ApplicationHttpRequest”的对象“org.apache.catalina.core.ApplicationHttpRequest@19f46c5d”转换为类“org.springframework.web.multipart.MultipartHttpServletRequest” 原因:无法将具有类 'org.apache.catalina.core.ApplicationHttpRequest' 的对象 'org.apache.catalina.core.ApplicationHttpRequest@19f46c5d' 转换为类 'org.springframework.web.multipart.MultipartHttpServletRequest' 类:流控制器 在线:[22] 代码片段:

谁能告诉我修理它的线索?

<%@ page import="ctv.Stream" %>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="layout" content="main" />
        <g:set var="entityName" value="${message(code: 'stream.label', default: 'Stream')}" />
        <title><g:message code="default.create.label" args="[entityName]" /></title>
        <jqfu:resources tmpl=”false” />
    </head>
    <body>
        <div class="nav">
            <span class="menuButton"><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></span>
            <span class="menuButton"><g:link class="list" action="list"><g:message code="default.list.label" args="[entityName]" /></g:link></span>
        </div>
        <div class="body">
            <h1><g:message code="default.create.label" args="[entityName]" /></h1>
            <g:if test="${flash.message}">
            <div class="message">${flash.message}</div>
            </g:if>
            <g:hasErrors bean="${streamInstance}">
            <div class="errors">
                <g:renderErrors bean="${streamInstance}" as="list" />
            </div>
            </g:hasErrors>
            <g:form action="save" >
                <div class="dialog">
                    <table>
                        <tbody>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="district"><g:message code="stream.district.label" default="District" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'district', 'errors')}">
                                    <g:select name="district.id" from="${ctv.District.list()}" optionKey="id" value="${streamInstance?.district?.id}"  />
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="dateAdded"><g:message code="stream.dateAdded.label" default="Date Added" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'dateAdded', 'errors')}">
                                    <g:datePicker name="dateAdded" precision="day" value="${streamInstance?.dateAdded}"  />
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="name"><g:message code="stream.name.label" default="Name" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'name', 'errors')}">
                                    <g:textField name="name" maxlength="30" value="${streamInstance?.name}" />
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="description"><g:message code="stream.description.label" default="Description" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'description', 'errors')}">
                                    <g:textField name="description" maxlength="100" value="${streamInstance?.description}" />
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="media"><g:message code="stream.media.label" default="Media" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'media', 'errors')}">
                                    <g:textField name="media" maxlength="30" value="${streamInstance?.media}" />
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="file"><g:message code="stream.file.label" default="File" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'file', 'errors')}">
                                    <!--g:textField name="file" maxlength="30" value="${streamInstance?.file}" />-->
                                    <g:form action="save"  enctype="multipart/form-data">
                                        <input type="file" name="myFile" />
                                    </g:form>
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="logo"><g:message code="stream.logo.label" default="Logo" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'logo', 'errors')}">
                                    <g:textField name="logo" value="${streamInstance?.logo}" />
                                </td>
                            </tr>

                            <tr class="prop">
                                <td valign="top" class="name">
                                    <label for="published"><g:message code="stream.published.label" default="Published" /></label>
                                </td>
                                <td valign="top" class="value ${hasErrors(bean: streamInstance, field: 'published', 'errors')}">
                                    <g:checkBox name="published" value="${streamInstance?.published}" />
                                </td>
                            </tr>

                        </tbody>
                    </table>
                </div>
                <div class="buttons">
                    <span class="button"><g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" /></span>
                </div>
            </g:form>
        </div>
    </body>
</html>

【问题讨论】:

    标签: grails groovy


    【解决方案1】:

    错误信息的原因

    您的代码的问题是您将请求对象转换为错误的类。这是错误消息中告诉您的部分:

    无法将具有类“org.apache.catalina.core.ApplicationHttpRequest”的对象“org.apache.catalina.core.ApplicationHttpRequest@19f46c5d”转换为类“org.springframework.web.multipart.MultipartHttpServletRequest”

    所以你有一个 org.apache.catalina.core.ApplicationHttpRequest 并且你试图将它转换为一个 org.springframework.web.multipart.MultipartHttpServletRequest 这是无法完成的。

    groovy(写在 grails 上)的美妙之处在于它是动态类型的。所以无论如何,大部分的选角都是多余的!

    尝试替换这两行

    MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
    CommonsMultipartFile uploadedFile = (CommonsMultipartFile)mpr.getFile("myFile");
    

    有了这个:

    def uploadedFile = request.getFile( "myFile" )
    

    但这并不能解决您的问题!它只会更改您收到的错误消息:'(

    问题的根源,我们是如何得到错误的请求类的?

    考虑一下为什么您的演员表请求类型错误,您可能忘记在表单操作中包含 enctype="multipart/form-data"。它应该看起来像这样:

    <g:form action="save" method="post" enctype="multipart/form-data"> ... </g:form>
    

    只是改变这个可能会解决你的问题,但我肯定也会删除铸件。

    更新:真实(?)答案

    在 HTML(和 GSP 用于制作 HTML)中,您不能有嵌套表单。一种形式不能在另一种形式中。您的 GSP 有两种形式,第一种如下所示:

    <g:form action="save">
    

    第二个(里面的)是这样的

    <g:form action="save" enctype="multipart/form-data">
    

    所以你需要完全去掉里面的那个,并确保外面的(唯一剩下的)看起来像这样:

    <g:form action="save" method="post" enctype="multipart/form-data">
    

    【讨论】:

    • 我确实按照你的建议修改了我的代码,并将其添加到表单中:
      错误 500:执行控制器 [ctv.StreamController] 的操作 [save] 导致异常:groovy.lang.MissingMethodException:没有方法签名:org. apache.catalina.core.ApplicationHttpRequest.getFile() 适用于参数类型:(java.lang.String) 值:[myFile] 可能的解决方案:getXML()、getAt(java.lang.String)、getAt(java.lang .String)、getLocale()、getInfo()、recycle() Servlet:grails
    • 角色问题出在request.getFile()
    • @philippe 好的,直接在if (request) { 行之后试试这个println "Request class: ${request.class}"。它会告诉我们请求是什么类,我们可以从那里开始。
    • 请求类:类 org.apache.catalina.core.ApplicationHttpRequest
    • @philippe 您是在上传文件时收到此错误,还是仅在尝试查看页面时收到此错误?另外,请将 GSP 代码包含在您的问题中,因为它可能有助于我们找到问题。
    【解决方案2】:

    我认为您可能过于复杂了。我们所做的只是

    def image = request.getFile('image') // image is the parameter name 
    def imageBytes = image.getBytes()
    

    您还需要检查 mimeType。

    【讨论】:

    • def image = request.getFile('image') 整个问题出在 request.getFile('name')
    【解决方案3】:

    另一种使用 Grails 文件上传插件的方式。在此处查看更多信息http://grails.org/plugin/file-uploader。它具有强大的界面并提供丰富的功能,可以让您的应用成为真正出色的一部分。

    【讨论】:

      【解决方案4】:

      你得到了异常

      groovy.lang.MissingMethodException:  No signature of method: 
        org.apache.catalina.core.ApplicationHttpRequest.getFile()
      

      因为你还没有添加enctype

      表格应该看起来像

      <form action="action_name" method="POST" enctype="multipart/form-data">
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-27
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        • 2011-06-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多