Caricamento file JSF 2.0

Sto cercando in giro alcuni blog, per cercare di trovare il modo di caricare i file usando JSF 2.0 ma tutte le soluzioni mi confondono. Vorrei sapere esattamente cosa devo fare per caricare correttamente un file (MP3, PDF, video … di qualsiasi tipo) e archiviarlo in un database come @Lob. Questo è quello che ho fatto finora:

Ora sono bloccato e ho molti dubbi:

  • Cosa devo fare per passare il file dal JSF al bean gestito e quindi trasformarlo in un byte [] (per poterlo gestire fino all’EJB)?

  • Come può un servitore aiutarmi?

  • Ho bisogno di un servlet per fare questo?

  • Inoltre ho scoperto che in alcuni blog menziona qualcosa sui servlet 3.0, ma non so se il mio ambiente di lavoro lo sta usando, come posso usare i servlet 3.0 (sto usando JEE6)?

Non ho mai caricato file prima e inoltre non ho molta familiarità con i servlet. Sono confuso, qualcuno potrebbe darmi qualche consiglio di partenza, per favore?

Prima di tutto, questa (vecchia) domanda e risposta presuppone JSF 2.0 / 2.1. Dal momento che JSF 2.2 componente senza la necessità di librerie di componenti di terze parti. Vedi anche Come caricare file usando JSF 2.2 ? Dov’è il file salvato?


Il modo più semplice sarebbe utilizzare Tomahawk per JSF 2.0 . Offre un componente .

Ecco un tutorial passo-passo:

  • Creare un progetto Web dinamico vuoto per Servlet 3.0 e JSF 2.0. Il web.xml deve soddisfare le specifiche Servlet 3.0 e contenere già il servlet JSF:

     < ?xml version="1.0" encoding="UTF-8"?>  Your Project Name  Faces Servlet javax.faces.webapp.FacesServlet 1   Faces Servlet *.xhtml   

    Il faces-config.xml deve soddisfare le specifiche JSF 2.0:

     < ?xml version="1.0" encoding="UTF-8"?>   

  • Scarica Tomahawk 1.1.10 per JSF 2.0 . Estrai il file zip, vai alla cartella /lib e copia tutti i file *.jar nel tuo /WEB-INF/lib .

    Sono 18 file, di cui batik*.jar e xml*.jar non sono necessari per utilizzare da solo il componente t:inputFileUpload . Potresti lasciarli via.


  • Configura il filtro delle estensioni Tomahawk in web.xml . È il responsabile della gestione delle richieste multipart/form-data che è necessario per poter inviare file su HTTP.

      MyFacesExtensionsFilter org.apache.myfaces.webapp.filter.ExtensionsFilter   MyFacesExtensionsFilter Faces Servlet  

    Nota che deve corrispondere esattamente al di FacesServlet come hai definito in web.xml .


  • Crea un semplice Facelet, upload.xhtml :

     < !DOCTYPE html>   Tomahawk file upload demo          

    Nota l’ enctype="multipart/form-data" su , questo è molto importante per poter inviare file con HTTP.


  • Crea un bean gestito semplice, com.example.Bean :

     package com.example; import java.io.IOException; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.context.FacesContext; import org.apache.commons.io.FilenameUtils; import org.apache.myfaces.custom.fileupload.UploadedFile; @ManagedBean @RequestScoped public class Bean { private UploadedFile uploadedFile; public void submit() throws IOException { String fileName = FilenameUtils.getName(uploadedFile.getName()); String contentType = uploadedFile.getContentType(); byte[] bytes = uploadedFile.getBytes(); // Now you can save bytes in DB (and also content type?) FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(String.format("File '%s' of type '%s' successfully uploaded!", fileName, contentType))); } public UploadedFile getUploadedFile() { return uploadedFile; } public void setUploadedFile(UploadedFile uploadedFile) { this.uploadedFile = uploadedFile; } } 

Questo dovrebbe essere. Aprilo tramite http: // localhost: 8080 / projectname / upload.xhtml .

Per quanto riguarda le tue domande concrete:

cosa devo fare per passare il file dal JSF al bean gestito e quindi trasformarlo in un byte [] (per poterlo gestire fino all’EJB)?

Questo è risposto sopra.

Come può un servitore aiutarmi?

È in grado di elaborare e controllare richieste / risposte HTTP. In un ambiente JSF, FacesServlet fa già tutto il lavoro.

Ho bisogno di un servlet per fare questo?

In un ambiente JSF, FacesServlet è obbligatorio. Ma è già fornito dall’API, non è necessario scriverne uno da solo. Tuttavia, per poter scaricare file da un database, un altro servlet è sicuramente utile. Qui puoi trovare un esempio di base: Servlet per servire il contenuto statico .

Inoltre ho trovato che in alcuni blog menziona qualcosa sui servlet 3.0, ma non so se il mio ambiente di lavoro lo sta usando, come posso fare se sto usando i servlet 3.0 (sto usando JEE6)?

Se stai usando un contenitore Servlet 3.0 come Glassfish 3, JBoss AS 6, Tomcat 7, ecc. E il web.xml è dichiarato come Servlet 3.0, allora stai sicuramente utilizzando Servlet 3.0. Servlet 3.0 fa parte di Java EE 6.

Per completezza, voglio solo fornire un esempio autonomo completamente funzionale di come questo viene fatto con JSF 2.2, con richieste non Ajax e Ajax . Tieni presente che JSF 2.2 utilizza diversi spazi dei nomi e devi lavorare con un contenitore Servlet 3.0 (come Tomcat 7.0.x, JBoss AS 6.xe 7.xe GlassFish 3.x sono).

fileUpload.xhtml

                  

UploadBean.java:

 @ManagedBean @ViewScoped public class UploadBean { private int filesUploaded = 0; //javax.servlet.http.Part (Servlet 3.0 API) private Part file; private String fileContent; /** * Just prints out file content */ public void upload() { try { fileContent = new Scanner(file.getInputStream()) .useDelimiter("\\A").next(); System.out.println(fileContent + " uploaded"); filesUploaded++; } catch (IOException e) { e.printStackTrace(); } } public int getFilesUploaded() { return filesUploaded; } public Part getFile() { return file; } public void setFile(Part file) { this.file = file; } } 

Guarda anche:

  • JSF 2.2: caricamento file con h: inputFile

Vorrei raccomandare l’uso di una libreria come Tomahawk o PrimeFaces .

BalusC ha anche un bel post sul blog sul caricamento di file con JSF 2.0 e Servlet 3.0.

In JSF 2.2 puoi facilmente caricare file usando tag senza usare commons-io o filter. Questo tag supporta sia processi normali che ajax.

Normale:

    

Ajax:

      

Progetta il bean gestito come segue:

  @Named @RequestScoped public class FileUploadBean { private Part uploadedFile; } 

Il post sul blog di BalusC: il caricamento di file con JSF 2.0 e Servlet 3.0 è ciò che mi ha salvato, perché ho avuto problemi nell’esecuzione di RichFaces 4 fileUpload tag con Spring WebFlow.

Vale la pena di modificare il codice di BalusC per utilizzare Spring’s MultipartResolver – non è necessario il suo MultipartMap da un altro post del blog .

L’ho raggiunto modificando un metodo di decode in FileRenderer questo modo:

  UploadedFile ret = null; Object req = context.getExternalContext().getRequest(); if (req instanceof MultipartHttpServletRequest) { MultipartFile file = ((MultipartHttpServletRequest)req).getFile(clientId); File temp = null; try { temp = File.createTempFile("_UPLOAD_", null); file.transferTo(temp); String name = new File(file.getOriginalFilename()).getName(); ret = new UploadedFile(temp, name); } catch (IOException e) { throw new RuntimeException("Could not create temp file.", e); } } else { throw new IllegalStateException("Request is not multipart. Use spring's multipart resolver."); } // If no file is specified, set empty String to trigger validators. ((UIInput) component).setSubmittedValue( ret == null ? EMPTY_STRING : ret); 

Un UploadedFile è un semplice POJO serializzabile utilizzato per restituire i risultati al bean di supporto.

Il modo più semplice è probabilmente utilizzare il tag inputFileUpload che puoi trovare in MyFaces:

http://myfaces.apache.org/

IceFaces2.0 ne ha uno, http://wiki.icefaces.org/display/ICE/FileEntry Non ho ancora provato a implementarlo, ma il download ha app di esempio e funziona con Tomcat 6 (servlet 2.5, quindi non JEE6)

È necessario aggiungere commons-fileupload-1.2.1.jar nel nostro percorso di creazione del progetto

1. Configurare il file web.xml:

 Web.xml  PrimeFaces FileUpload Filter org.primefaces.webapp.filter.FileUploadFilter   PrimeFaces FileUpload Filter Faces Servlet   png image/png  

2. Crea ManagedBean

  @ManagedBean @SessionScoped public class FileUploadBean implements Serializable{ public FileUpload (){ } private StreamedContent file; public void loadFile(FileUploadEvent event) throws IOException, InterruptedException { InputStream input = new ByteArrayInputStream(event.getFile().getContents()); file= new DefaultStreamedContent(input, "image/jpg"); } } 

3.jsf file (xhtml)