Как получить байты (byte []) из загруженного файла в Grails - PullRequest
7 голосов
/ 24 января 2012

У меня есть такая форма загрузки (form.gsp):

<html>
<head>
    <title>Upload Image</title>
    <meta name="layout" content="main" />
</head>
    <body>  
        <g:uploadForm action ="upload">
            Photo: <input name="photos" type="file" />
            <g:submitButton name="upload" value="Upload" />
        </g:uploadForm>
    </body>
</html>

Я ожидаю, что пользователь загрузит любое изображение, и когда он нажимает на кнопку upload, мне нужен какой-то способ получить изображение в действии моего контроллера и передать его в представление:

def upload = { 
        byte[] photo = params.photos
            //other code goes here . . . .
    }

Это выдает ошибку:

Cannot cast object 'org.springframework.web.multipart.commons.CommonsMultipartFile@1b40272' with class 'org.springframework.web.multipart.commons.CommonsMultipartFile' to class 'byte'

Обратите внимание, что я не хочу, чтобы эти фотографии были сохранены в моей БД. Фактически, как только действие upload будет выполнено, я обработаю это изображение и покажу вывод в виде upload. Так что будет хорошо, если у меня будет решение для него.

Заранее спасибо.

Ответы [ 3 ]

11 голосов
/ 24 января 2012
def reqFile = request.getFile("photos")
InputStream file = reqFile.inputStream
byte[] bytes = file.bytes

Редактировать : изменил getBytes на байты, как это было предложено, и это лучший способ:)

9 голосов
/ 24 января 2012

Если вы хотите загрузить файл, а не сохранить его и отобразить его в <img> в другом представлении в следующем запросе, вы можете временно сохранить его в сеансе:

grails-app/controllers/UploadController.groovy:

def upload = {
    def file = request.getFile('file')

    session.file = [
        bytes: file.inputStream.bytes,
        contentType: file.contentType
    ]

    redirect action: 'elsewhere'
}

def elsewhere = { }

def image = {
    if (!session.file) {
        response.sendError(404)
        return
    }

    def file = session.file
    session.removeAttribute 'file'

    response.setHeader('Cache-Control', 'no-cache')
    response.contentType = file.contentType
    response.outputStream << file.bytes
    response.outputStream.flush()

}

grails-app/views/upload/form.gsp:

<g:uploadForm action="upload">
  <input type="file" name="file"/>
  <g:submitButton name="Upload"/>
</g:uploadForm>

grails-app/views/upload/elsewhere.gsp:

<img src="${createLink(controller: 'upload', action: 'image')}"/>

Файл будет доступен для одного запроса (так как мы удаляем его при отображении). Возможно, вам потребуется реализовать дополнительную очистку сеанса в случае ошибок.

Вы можете легко адаптировать это для хранения нескольких файлов (если вы пытаетесь выполнить несколько загрузок фотографий), но имейте в виду, что каждый файл занимает память.

Альтернативой использованию сеанса может быть передача файлов во временную папку на диске с помощью MultipartFile#transferTo(File) и отображение их оттуда.

5 голосов
/ 24 января 2012
byte[] photo=request.getFile("photos").bytes

и если вы хотите вернуться как изображение, сделайте:

response.contentType="image/png" //or whatever the format is...
response.outputStream << photo
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...