Как использовать на основе схемы PrimeFaces Р:fileupload с? Метод прослушивателя никогда не вызывается или UploadedFile равен null / выдает ошибку / не используется

Я пытаюсь загрузить файл с помощью PrimeFaces, но fileUploadListener метод не вызывается после завершения загрузки.

вот вид:

<h:form>
    <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload}"
        mode="advanced" 
        update="messages"
        sizeLimit="100000" 
        allowTypes="/(.|/)(gif|jpe?g|png)$/"/>

    <p:growl id="messages" showDetail="true"/>
</h:form>

и фасоли:

@ManagedBean
@RequestScoped
public class FileUploadController {

    public void handleFileUpload(FileUploadEvent event) {
        FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

}

я поставил точку останова на методе, но он никогда не вызывается. При использовании mode="simple" и ajax="false", он вызывается, но я хочу, чтобы он работал в расширенном режиме. Я использую Netbeans и Glassfish 3.1.

8 ответов


как настроить и устранить неполадки <p:fileUpload> зависит от версии PrimeFaces.

все версии PrimeFaces

приведенные ниже требования применяются ко всем версиям PrimeFaces:

  1. на на <h:form> необходимо указать multipart/form-data. Когда это отсутствует, загрузка ajax может просто работать, но общее поведение браузера не определено и зависит от состава формы и WebBrowser make/version. Просто всегда уточняйте на всякий случай.

  2. при использовании mode="advanced" (т. е. загрузка ajax, это значение по умолчанию), затем убедитесь, что у вас есть <h:head> в шаблоне (master). Это гарантирует, что необходимые файлы JavaScript будут правильно включены. Это не требуется для mode="simple" (не-ajax upload), но это нарушит look'n'Feel и функциональность всех других компонентов PrimeFaces, поэтому вы все равно не хотите пропустить это.

  3. при использовании mode="simple" (т. е. загрузка без ajax), тогда ajax должен быть отключен на любых командных кнопках/ссылках PrimeFaces по ajax="false", и вы должны использовать <p:fileUpload value> С <p:commandButton action> вместо <p:fileUpload fileUploadListener>.

Итак, если вы хотите (авто) загрузить файл с поддержкой ajax (имейте в виду <h:head>!):

<h:form enctype="multipart/form-data">
    <p:fileUpload fileUploadListener="#{bean.upload}" auto="true" />
</h:form>
public void upload(FileUploadEvent event) {
    UploadedFile uploadedFile = event.getFile();
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    byte[] contents = uploadedFile.getContents(); // Or getInputStream()
    // ... Save it, now!
}

или, если вы хотите загрузить файл без ajax:

<h:form enctype="multipart/form-data">
    <p:fileUpload mode="simple" value="#{bean.uploadedFile}" />
    <p:commandButton value="Upload" action="#{bean.upload}" ajax="false" />
</h:form>
private UploadedFile uploadedFile; // +getter+setter

public void upload() {
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    byte[] contents = uploadedFile.getContents(); // Or getInputStream()
    // ... Save it, now!
}

обратите внимание, что атрибуты, связанные с ajax, такие как auto, allowTypes, update, onstart, oncomplete, etcигнорировать на mode="simple". Так что нет необходимости уточнять их в таком случае.

Также обратите внимание, что вы должны немедленно прочитайте содержимое файла внутри вышеупомянутых методов, а не в другом методе bean, вызванном более поздним HTTP-запросом. Это связано с тем, что содержимое загруженного файла является областью запроса и, следовательно, недоступно в более позднем/другом HTTP-запросе. Любая попытка прочитать его в более позднем запросе, скорее всего, закончится с java.io.FileNotFoundException во временном файле.


на основе схемы PrimeFaces 5.x

это не требует дополнительной настройки, если вы используете JSF 2.2 и ваш faces-config.xml также объявлено соответствует версии JSF 2.2. Фильтр загрузки файлов PrimeFaces вам вообще не нужен. Если вам неясно, как правильно установить и настроить JSF в зависимости от используемого целевого сервера, перейдите к как правильно установить и настроить библиотеки JSF через Maven? и раздел "Установка JSF" нашей страницы JSF wiki.

если вы, однако, еще не используете JSF 2.2, и вы не можете его обновить (должно быть легко, когда уже на сервлете 3.0 совместимый контейнер), то вам нужно вручную зарегистрировать ниже фильтр загрузки файлов PrimeFaces в web.xml (он будет анализировать запрос нескольких частей и заполнять карту параметров регулярного запроса, чтобы FacesServlet можете продолжать работать как обычно):

<filter>
    <filter-name>primeFacesFileUploadFilter</filter-name>
    <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>primeFacesFileUploadFilter</filter-name>
    <servlet-name>facesServlet</servlet-name>
</filter-mapping>

на <servlet-name> значение facesServlet должно точно соответствовать значению в <servlet> вход javax.faces.webapp.FacesServlet в том же web.xml. Так что если это например Faces Servlet, затем вам нужно отредактировать его соответствующим образом, чтобы соответствовать.


на основе схемы PrimeFaces 4.x

та же история, что и PrimeFaces 5.x применяется на 4.X, а также.

существует только потенциальная проблема в получении загруженного содержимого файла UploadedFile#getContents(). Это вернется null когда вместо Apache Commons FileUpload используется собственный API. Тебе нужно использовать UploadedFile#getInputStream() вместо. См. также как вставить загруженное изображение из p: fileUpload как BLOB в MySQL?

еще одна потенциальная проблема с собственным API будет проявляться, когда компонент загрузки присутствует в форме, на которой запускается другой "обычный" запрос ajax, который не обрабатывает компонент загрузки. См. также загрузка файлов не работает с AJAX в PrimeFaces 4.0 / JSF 2.2.x-javax.сервлет.ServletException: тип содержимого запроса не является multipart / form-data.

обе проблемы также могут быть решены путем переключения на Apache Commons FileUpload. Посмотреть На Основе Схемы PrimeFaces 3.X Раздел для деталей.


на основе схемы PrimeFaces 3.x

эта версия не поддерживает загрузку собственного файла JSF 2.2 / Servlet 3.0. Вам необходимо вручную установить Apache Commons FileUpload и явно зарегистрировать фильтр загрузки файлов в web.xml.

вам нужно следующее библиотеки:

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

детали регистрации фильтра загрузки файлов можно найти в PrimeFaces 5.раздел X здесь выше. Если вы используете PrimeFaces 4+, и вы хотите явно использовать Apache Commons FileUpload вместо загрузки собственного файла JSF 2.2 / Servlet 3.0, вам нужно рядом с указанными библиотеками и фильтровать также приведенный ниже контекст param в web.xml:

<context-param>
    <param-name>primefaces.UPLOADER</param-name>
    <param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
</context-param>

устранение неисправностей

если он все еще не работает, вот еще одна возможная причина, не связанная с конфигурацией PrimeFaces:

  1. только если вы используете PrimeFaces фильтр загрузки файлов: есть еще Filter в вашем webapp, который работает до фильтр загрузки файла PrimeFaces и уже потребил тело запроса, например, вызывая getParameter(), getParameterMap(), getReader() и так далее. Тело запроса может быть получена только один раз. Когда вы вызываете один из этих методов до того, как фильтр загрузки файла выполнит свою работу, фильтр загрузки файла получит пустое тело запроса.

    чтобы исправить это, вам нужно будет поставить <filter-mapping> загрузки файла фильтр до другой фильтр в web.xml. Если запрос не является multipart/form-data запрос, затем фильтр загрузки файла будет просто продолжаться, как будто ничего не произошло. Если вы используете фильтры, которые автоматически добавляются, потому что они используют аннотации (например, PrettyFaces), вам может потребоваться добавить явный порядок через интернет.XML. См.как определить порядок выполнения фильтра сервлетов с помощью аннотаций в WAR

  2. только если вы используете PrimeFaces фильтр загрузки файлов: есть еще Filter в вашем webapp, который работает до фильтр загрузки файлов PrimeFaces и выполнил RequestDispatcher#forward() звонок. Обычно URL переписывают фильтры, такие как PrettyFaces сделать это. Это вызывает FORWARD диспетчер, но фильтры прослушивают по умолчанию на


Вы тоже используете prettyfaces? Затем установите диспетчер вперед:

<filter-mapping>
   <filter-name>PrimeFaces FileUpload Filter</filter-name>
   <servlet-name>Faces Servlet</servlet-name>
   <dispatcher>FORWARD</dispatcher>
</filter-mapping>

один момент я заметил с Primefaces 3.4 и Netbeans 7.2:

удалите параметры автоматического заполнения Netbeans для функции handleFileUpload т. е. (событие), иначе событие может быть null.

<h:form>
    <p:fileUpload fileUploadListener="#{fileUploadController.handleFileUpload(event)}"
        mode="advanced" 
        update="messages"
        sizeLimit="100000" 
        allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>

    <p:growl id="messages" showDetail="true"/>
</h:form>

похоже на javax.сталкиваться.SEPARATOR_CHAR не должен быть равен _


У меня была такая же проблема с primefaces 5.3, и я прошел через все точки, описанные BalusC, без результата. Я последовал его совету по отладке FileUploadRenderer#decode () и обнаружил, что мой веб.XML был unproperly набор

<context-param>
  <param-name>primefaces.UPLOADER</param-name>
  <param-value>auto|native|commons</param-value>
</context-param>

значение param должно быть 1 из этих 3 значений, но не все из них!! весь контекст-param раздел может быть удален, и по умолчанию будет авто


бобовые.в XHTML

    <h:form enctype="multipart/form-data">    
<p:outputLabel value="Choose your file" for="submissionFile" />
                <p:fileUpload id="submissionFile"
                    value="#{bean.file}"
                    fileUploadListener="#{bean.uploadFile}" mode="advanced"
                    auto="true" dragDropSupport="false" update="messages"
                    sizeLimit="100000" fileLimit="1" allowTypes="/(\.|\/)(pdf)$/" />

</h:form>

бобовые.java

@ManagedBean

@ViewScoped public class Submission реализует сериализуемый {

private UploadedFile file;

//Gets
//Sets

public void uploadFasta(FileUploadEvent event) throws FileNotFoundException, IOException, InterruptedException {

    String content = IOUtils.toString(event.getFile().getInputstream(), "UTF-8");

    String filePath = PATH + "resources/submissions/" + nameOfMyFile + ".pdf";

    MyFileWriter.writeFile(filePath, content);

    FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,
            event.getFile().getFileName() + " is uploaded.", null);
    FacesContext.getCurrentInstance().addMessage(null, message);

}

}

web.в XML

    <servlet-mapping>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<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>

ни одно из предложений здесь не было полезно для меня. Поэтому мне пришлось отлаживать primefaces и найти причину проблемы:

java.lang.IllegalStateException: No multipart config for servlet fileUpload

затем я добавил раздел в сервлет моих лиц в интернете.XML. Так что Исправлена проблема:

<servlet>
    <servlet-name>main</servlet-name>

        <servlet-class>org.apache.myfaces.webapp.MyFacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
        <multipart-config>
            <location>/tmp</location>
            <max-file-size>20848820</max-file-size>
            <max-request-size>418018841</max-request-size>
            <file-size-threshold>1048576</file-size-threshold>
        </multipart-config>
    </servlet>

У меня была та же проблема, из-за того, что у меня была вся конфигурация, описанная в этом посте, но в моем случае это было потому, что у меня было два импорта jquery (один из них был запросом primefaces), который вызвал конфликты для загрузки файлов.

см. конфликт jQuery Primefaces