Как использовать PrimeFaces p: 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.

1073   8  

8 ответов:

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

все версии PrimeFaces

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

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

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

если вы, однако, еще не используете JSF 2.2, и вы не можете его обновить (должно быть легко, когда уже на совместимом контейнере Servlet 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>

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


PrimeFaces 4.x

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

есть только потенциальная проблема в получении загруженный контент UploadedFile#getContents(). Это вернет null когда используется собственный API вместо Apache Commons FileUpload. Тебе нужно использовать 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.

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

они должны присутствовать в пути к классам времени выполнения веб-приложения. При использовании 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 в вашем веб-приложении, которое работает до фильтр загрузки файла PrimeFaces и уже использовал тело запроса, например, вызывая getParameter(),getParameterMap(),getReader() и так далее. Тело запроса может быть получена только один раз. Когда вы вызываете один из этих методов до того, как фильтр загрузки файла выполнит свою работу, фильтр загрузки файла получит пустое тело запроса.

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

  2. только если вы используете PrimeFaces фильтр загрузки файлов: есть еще один Filter в вашем веб-приложении, которое работает до фильтр загрузки файла 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 был непропорционально установлен

<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 представление открытого класса реализует сериализуемый {

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), который вызвал конфликты для загрузки файлов.

см. Primefaces jQuery conflict

Comments

    Ничего не найдено.