2012-01-24 23 views
7

Ho una forma di upload come questo (form.gsp):Come ottenere byte (byte []) da un file caricato in Grails

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

mi aspetto all'utente di caricare qualsiasi immagine, e quando si fa clic su il pulsante upload, ho bisogno di un modo per ottenere l'immagine nella mia azione di controllo e lo passò alla vista:

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

Questo genera un errore:

Cannot cast object '[email protected]b40272' with class 'org.springframework.web.multipart.commons.CommonsMultipartFile' to class 'byte' 

Nota che non voglio che queste foto vengano salvate sul mio DB. In realtà una volta eseguita l'azione , elaborerò con quell'immagine e mostrerò l'output nella vista . Quindi andrà bene se avrò una soluzione per questo.

Grazie in anticipo.

risposta

8

Se si desidera caricare il file, non memorizzarlo e visualizzarlo in un <img> su un'altra vista nella richiesta successiva, è possibile memorizzarlo temporaneamente nel sessione:

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')}"/> 

Il file sarà disponibile per una singola richiesta (poiché la rimuoviamo quando viene visualizzata). Potrebbe essere necessario implementare un po 'di pulizia della sessione aggiuntiva per i casi di errore.

Si potrebbe facilmente adattarlo per trattenere più file (se si sta tentando di mettere in scena una serie di caricamenti di foto), ma tenere presente che ogni file sta occupando memoria.

Un'alternativa all'utilizzo della sessione consiste nel trasferire i file in un percorso temporaneo su disco utilizzando MultipartFile#transferTo(File) e visualizzarli da lì.

+0

Questo sembra fantastico ma quando visualizzo 'elsewhere.gsp' non riesco a vedere alcuna immagine! –

+0

Hmm, interessante. Il codice sopra ha funzionato per me, alla lettera. Che cosa dice la pagina è la fonte dell'immagine? Forse è possibile aggiungere alcune registrazioni per facilitare il debug. –

+0

Spiacente funzionava, ho fatto un refuso nel nome del controller: grazie per la tua roba :) –

9
def reqFile = request.getFile("photos") 
InputStream file = reqFile.inputStream 
byte[] bytes = file.bytes 

Edit: ha cambiato le getBytes a byte come suggerito e come è un modo migliore Groovy :)

+2

+1 e l'ultima riga può essere solo 'byte [] byte = file.bytes' –

+0

tutto funziona correttamente! ma se voglio visualizzare l'immagine che l'utente ha caricato su una vista, come posso farlo? –

+0

puoi scrivere i tuoi byte su response.outputStream –

5
byte[] photo=request.getFile("photos").bytes 

e se si vuole tornare come immagine fare:

response.contentType="image/png" //or whatever the format is... 
response.outputStream << photo 
Problemi correlati