Groovy загрузить файл - PullRequest
       5

Groovy загрузить файл

3 голосов
/ 18 марта 2012

Я пытаюсь написать загрузчик для файлов и видео в 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: Выполнение действия [save] контроллера [ctv.StreamController] вызвало исключение: невозможно преобразовать объект 'org.apache.catalina.core.ApplicationHttpRequest@19f46c5d' с классом 'org.apache.catalina.core.ApplicationHttpRequest' в класс ' org.springframework.web.multipart.MultipartHttpServletRequest» Сервлет: грааль URI: /ctv/grails/stream/save.dispatch Сообщение об исключении: Невозможно привести объект 'org.apache.catalina.core.ApplicationHttpRequest@19f46c5d' с классом 'org.apache.catalina.core.ApplicationHttpRequest' в класс 'org.springframework.web.multipart.MultipartHttpServletqu Причина: Невозможно привести объект 'org.apache.catalina.core.ApplicationHttpRequest@19f46c5d' с классом 'org.apache.catalina.core.ApplicationHttpRequest' в класс 'org.springframework.web.multipart.MestpartHttpServletqu Класс: StreamController На линии: [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>

Ответы [ 4 ]

7 голосов
/ 18 марта 2012

Причина сообщения об ошибке

Проблема с вашим кодом в том, что вы приводите объект запроса к неправильному классу. Это часть сообщения об ошибке, которое говорит вам следующее:

Невозможно привести объект 'org.apache.catalina.core.ApplicationHttpRequest@19f46c5d' с классом 'org.apache.catalina.core.ApplicationHttpRequest' к классу 'org.springframework.web.multipart.MultipartHttpServletqu

Итак, у вас есть 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">
1 голос
/ 18 марта 2012

Я думаю, что вы, возможно, слишком усложняете это.Все, что мы делаем, это

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

Вы также захотите проверить mimeType.

0 голосов
/ 20 октября 2012

Вы получаете исключение

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

, поскольку вы не добавили enctype

форма должна выглядеть следующим образом:

<form action="action_name" method="POST" enctype="multipart/form-data">
0 голосов
/ 20 марта 2012

Другой способ использовать плагин для загрузки файлов Grails. См. Дополнительную информацию здесь http://grails.org/plugin/file-uploader. Он имеет надежный интерфейс и предоставляет широкие возможности, чтобы сделать действительно приятную часть вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...