Загрузка файла JSF 2.0 - PullRequest
       54

Загрузка файла JSF 2.0

32 голосов
/ 24 марта 2011

Я просматриваю несколько блогов, пытаясь найти способ загрузки файлов с использованием JSF 2.0. Но все решения меня смущают.Я хотел бы знать, что именно мне нужно, чтобы иметь возможность успешно загрузить файл (MP3, PDF, видео ... любой тип текста) и сохранить его в базе данных как @Lob.Это то, что я сделал до сих пор:

  • Я создал объект, который имеет атрибут типа byte [], и он также помечен аннотацией @Lob.

  • Я создал EJB-компонент, который представит сущность с методом, имеющим в качестве параметра byte [], и вставит его в базу данных с помощью класса EntityManager (метод persist).

  • Я создал страницу JSF с тегом ввода типа «файл» и кнопкой отправки

  • Я подготовил управляемый компонент для обмена информацией о файле с JSFстр.

Теперь я застрял и у меня много сомнений:

  • Что мне нужно сделать, чтобы передать файл из JSF вуправляемый бин, а затем преобразовать его в байт [] (чтобы можно было передать его в EJB)?

  • Как мне может помочь сервлет?

  • Нужен ли для этого сервлет?

  • Также я обнаружил, что в некоторых блогах упоминается что-то о сервлетах 3.0, но я неНе знаю, использует ли это моя рабочая среда, как можно, если я использую сервлеты 3.0 (я использую JEE6)?

Я никогда раньше не загружал файлы, и к тому же я не оченьзнаком с сервлетами.Я в замешательстве, кто-нибудь может дать мне несколько советов, пожалуйста?

Ответы [ 8 ]

70 голосов
/ 24 марта 2011

Прежде всего, этот (старый) вопрос и ответ предполагает JSF 2.0 / 2.1.Начиная с JSF 2.2 есть собственный компонент <h:inputFile> без необходимости использования сторонних библиотек компонентов.См. Также Как загрузить файл с использованием JSF 2.2.?Где находится сохраненный файл?


Самый простой способ - использовать Томагавк для JSF 2.0 .Он предлагает компонент <t:inputFileUpload>.

Вот пошаговое руководство:

  • Создайте пустой динамический веб-проект для Servlet 3.0 и JSF 2.0.web.xml должен соответствовать спецификации Servlet 3.0 и уже содержать сервлет JSF:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app 
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        id="YourProjectName" version="3.0">
    
        <display-name>Your Project Name</display-name>
    
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.xhtml</url-pattern>
        </servlet-mapping>
    
    </web-app>
    

    * faces-config.xml должен соответствовать спецификации JSF 2.0:

    <?xml version="1.0" encoding="UTF-8"?>
    <faces-config
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
        version="2.0">
    
    </faces-config>
    

  • Скачать Томагавк 1.1.10 для JSF 2.0 .Извлеките zip-файл, перейдите в папку /lib и скопируйте все файлы *.jar в свой /WEB-INF/lib.

    Это 18 файлов, из которых batik*.jar и xml*.jar не нужны для использования только компонента t:inputFileUpload.Вы можете оставить их в стороне.


  • Настройте фильтр расширений Томагавк в web.xml.Это тот, кто отвечает за обработку multipart/form-data запросов, которые необходимы для возможности отправки файлов по HTTP.

    <filter>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>MyFacesExtensionsFilter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    

    Обратите внимание, что <servlet-name> должен точно соответствовать <servlet-name> FacesServletкак вы определили в web.xml.


  • Создайте простой Facelet, upload.xhtml:

    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:t="http://myfaces.apache.org/tomahawk"
        xmlns:ui="http://java.sun.com/jsf/facelets">
        <h:head>
            <title>Tomahawk file upload demo</title>
        </h:head>
        <h:body>
            <h:form enctype="multipart/form-data">
                <t:inputFileUpload value="#{bean.uploadedFile}" />
                <h:commandButton value="submit" action="#{bean.submit}" />
                <h:messages />
            </h:form>
        </h:body> 
    </html>
    

    Обратите внимание на атрибут enctype="multipart/form-data" на<h:form>, это очень важно для возможности отправки файлов с HTTP.


  • Создание простого управляемого компонента, 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;
        }
    
    }
    

Так и должно быть.Откройте его по http://localhost:8080/projectname/upload.xhtml.

Что касается ваших конкретных вопросов:

что мне нужно сделать, чтобы передать файл из JSF в управляемый компонент и затем преобразовать его вбайт [] (чтобы можно было передать его в EJB)?

Ответ дан выше.

Как сервлетпомогите мне?

Умеет обрабатывать и контролировать HTTP запросы / ответы.В среде JSF FacesServlet уже выполняет всю работу.

Нужен ли для этого сервлет?

ВJSF среда, FacesServlet является обязательным.Но это уже предусмотрено API, вам не нужно писать его самостоятельно.Однако, чтобы иметь возможность загружать файлы из базы данных, определенно полезен другой сервлет.Вы можете найти базовый пример здесь: Сервлет для обслуживания статического контента .

Также я обнаружил, что в каком-то блоге упоминается что-то о сервлетах 3.0, но я не знаюесли моя рабочая среда использует его, как, если я использую сервлеты 3.0 (я использую JEE6)?

Если вы используете контейнер Servlet 3.0, такой как Glassfish 3, JBoss AS 6, Tomcat 7 и т. Д. И web.xml объявлен как Servlet 3.0, тогда вы определенно используете Servlet 3.0.Сервлет 3.0 является частью Java EE 6.

8 голосов
/ 06 февраля 2014

Для полноты картины я просто хочу предоставить полностью функциональный автономный пример того, как это делается с JSF 2.2, либо с не-Ajax и Ajax-запросами . Имейте в виду, что JSF 2.2 использует разные пространства имен, и вам необходимо работать с контейнером Servlet 3.0 (как Tomcat 7.0.x, JBoss AS 6.x и 7.x и GlassFish 3.x).

fileUpload.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core">
<h:head />
<h:body>
    <h:form enctype="multipart/form-data">
        <h:inputFile value="#{uploadBean.file}" />
        <h:commandButton value="Post Upload" action="#{uploadBean.upload}" />
    </h:form>
    <h:form enctype="multipart/form-data">
        <h:inputFile value="#{uploadBean.file}" />
        <h:commandButton value="Ajax Upload">
            <f:ajax listener="#{uploadBean.upload}" execute="@form"
                render="countOutput" />
        </h:commandButton>
    <!-- Counts the uploaded items -->
    <h:outputText id="countOutput"
        value="Files uploaded #{uploadBean.filesUploaded}" />
    </h:form>
</h:body>
</html>

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

Смотри также:

3 голосов
/ 24 марта 2011

Я бы рекомендовал использовать такую ​​библиотеку, как Томагавк <t:inputFileUpload> или PrimeFaces <p:fileUpload>.

BalusC также имеет хороший пост в блоге о Загрузка файлов с помощью JSF 2.0 и Servlet 3.0.

2 голосов
/ 20 июня 2013

В JSF 2.2 вы можете легко загрузить файл, используя тег, без использования commons-io или фильтра. Этот тег поддерживает как обычный, так и AJAX процесс.

Нормальный:

    <h:inputFile id="file"  value="#{fileUploadBean.uploadedFile}"/> 
    <h:commandButton id="button" action="#{fileUploadBean.sumbit()}" value="Upload"/>

Ajax:

    <h:inputFile id="file" value="#{fileUploadBean.uploadedFile}"/> 
    <h:commandButton id="button" value="submit">
      <f:ajax execute="@all" render="@all" onevent="statusUpdate"/>
    </h:commandButton>

Создайте свой управляемый компонент следующим образом:

  @Named
  @RequestScoped
  public class FileUploadBean {

   private Part uploadedFile;

  }
2 голосов
/ 08 января 2013

Сообщение в блоге BalusC: Загрузка файлов с помощью JSF 2.0 и Servlet 3.0 - это то, что спасло меня, потому что у меня были проблемы с использованием тега RichFaces 4 fileUpload с Spring WebFlow.

Стоит изменить BalusCкод для использования MultipartResolver Spring - вам не нужно его MultipartMap из другого поста в блоге .

Я добился этого, изменив метод decode в FileRenderer следующим образом:

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

A UploadedFile - это простой сериализуемый POJO, используемый для возврата результатов к компоненту поддержки.

0 голосов
/ 10 июля 2013

Вы должны добавить commons-fileupload-1.2.1.jar в наш проект Путь сборки

1.Настроить файл web.xml:

Web.xml

    <filter>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>PrimeFaces FileUpload Filter</filter-name>
        <servlet-name>Faces Servlet</servlet-name>
    </filter-mapping>
    <mime-mapping>        
        <extension>png</extension>
        <mime-type>image/png</mime-type>
    </mime-mapping>

2.Создать файл 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 (xhtml)

   <h:form enctype="multipart/form-data"> 
         <p:fileUpload fileUploadListener="#{fileUploadBean.file}" sizeLimit="100000" allowTypes="/(\.|\/)(gif|jpe?g|png|bmp)$/"/>
        </h:form>
0 голосов
/ 24 марта 2011

IceFaces2.0 имеет один, http://wiki.icefaces.org/display/ICE/FileEntry Еще не пытался его реализовать, но в загрузке есть примеры приложений, и он работает под Tomcat 6 (сервлет 2.5, поэтому не JEE6)

0 голосов
/ 24 марта 2011

Возможно, самый простой способ - использовать тег inputFileUpload, который вы можете найти в MyFaces:

http://myfaces.apache.org/

...