<p:fileUpload>
Налаштування та усунення несправностей залежить від версії PrimeFaces.
Усі версії PrimeFaces
Наведені нижче вимоги стосуються всіх версій PrimeFaces:
enctype
Атрибутом <h:form>
повинен бути встановлений в multipart/form-data
. Якщо цього немає, завантаження ajax може просто працювати, але загальна поведінка браузера не визначена і залежить від складу форми та версії веб-браузера. Просто завжди вказуйте, щоб це було з безпечного боку.
Під час використання mode="advanced"
(тобто завантаження ajax, це за замовчуванням), тоді переконайтеся, що ви маєте <h:head>
в (головний) шаблон. Це забезпечить належне включення необхідних файлів JavaScript. Це не потрібно для mode="simple"
(не-ajax завантаження), але це порушить look'n'feel та функціональність усіх інших компонентів PrimeFaces, так що ви все одно не хочете пропускати це.
При використанні mode="simple"
(тобто не АЯКС завантаження), то Аякс повинен бути відключений на будь-яких PrimeFaces команди кнопки / посилання, ajax="false"
і ви повинні використовувати <p:fileUpload value>
з <p:commandButton action>
замість <p:fileUpload fileUploadListener>
(для PrimeFaces <= 7.x) або <p:fileUpload listener>
(для PrimeFaces> = 8.x)
Отже, якщо ви хочете (автоматичне) завантаження файлів із підтримкою ajax (пам'ятайте <h:head>
!):
<h:form enctype="multipart/form-data">
<p:fileUpload fileUploadListener="#{bean.upload}" auto="true" /> // for PrimeFaces >= 8.x this should be listener instead of fileUploadListener
</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
, і т.д., ігноруються в mode="simple"
. Тож зайве їх вказувати в такому випадку.
Також зауважте, що ви повинні прочитати вміст файлу негайно всередині вищезгаданих методів, а не в іншому методі bean, на який посилається пізніший HTTP-запит. Це пов’язано з тим, що вміст завантаженого файлу має масштаб запиту і, таким чином, недоступний у пізнішому / іншому HTTP-запиті. Будь-яка спроба прочитати його в наступному запиті, швидше за все, закінчиться java.io.FileNotFoundException
у тимчасовому файлі.
PrimeFaces 8.x
Конфігурація ідентична наведеній нижче інформації про версію 5.x, але якщо ваш слухач не викликається, перевірте, чи викликається атрибуту, listener
а ні (як у попередніх версіях 8.x)fileUploadListener
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>
<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 використовується файловий API. Вам потрібно використовувати UploadedFile#getInputStream()
замість цього. Див. Також Як вставити завантажене зображення з p: fileUpload як BLOB в MySQL?
Інша потенційна проблема з нативним API виявиться в тому випадку, коли компонент завантаження присутній у формі, в якій запускається інший "звичайний" запит ajax, який не обробляє компонент завантаження. Дивіться також Завантаження файлів не працює з AJAX у PrimeFaces 4.0 / JSF 2.2.x - javax.servlet.ServletException: Тип вмісту запиту не є багаточастинним / формою-даними .
Обидві проблеми також можна вирішити, перейшовши на Apache Commons FileUpload. Докладніше див. Розділ PrimeFaces 3.x.
PrimeFaces 3.x
Ця версія не підтримує завантаження нативного файлу JSF 2.2 / Servlet 3.0. Потрібно вручну встановити Apache Commons FileUpload і явно зареєструвати фільтр завантаження файлів у web.xml
.
Вам потрібні такі бібліотеки:
Вони повинні бути присутніми на уроці виконання веб-сайту. Використовуючи Maven, переконайтеся, що вони принаймні визначені під час виконання (також хороший обсяг компіляції за замовчуванням). Переносячи JAR вручну, переконайтеся, що вони потрапляють у /WEB-INF/lib
папку.
Детальну інформацію про реєстрацію фільтру для завантаження файлів можна знайти в розділі PrimeFaces 5.x тут, вище. У випадку, якщо ви використовуєте PrimeFaces 4+ та ви хочете явно використовувати Apache Commons FileUpload замість завантаження нативного файлу JSF 2.2 / Servlet 3.0, тоді вам потрібно поруч із згаданими бібліотеками та відфільтрувати також нижченаведений контекстний параметр у web.xml
:
<context-param>
<param-name>primefaces.UPLOADER</param-name>
<param-value>commons</param-value><!-- Allowed values: auto, native and commons. -->
</context-param>
Вирішення проблем
Якщо це все ще не працює, ось інші можливі причини, не пов’язані з конфігурацією PrimeFaces:
Тільки якщо ви використовуєте фільтр завантаження PrimeFaces файлу: Там інша Filter
в вашому веб - додаток , яке працює до того фільтра Завантажуйте PrimeFaces файл і вже поглинув тіло запиту, наприклад , шляхом виклику getParameter()
, getParameterMap()
, getReader()
, і так далі. Тіло запиту можна проаналізувати лише один раз. Якщо ви зателефонуєте один із цих методів, перш ніж фільтр завантаження файлів не виконає свою роботу, тоді фільтр завантаження файлів отримає порожнє тіло запиту.
Щоб виправити це, вам потрібно поставити <filter-mapping>
фільтр завантаження файлу перед іншим фільтром web.xml
. Якщо запит не є multipart/form-data
запитом, тоді фільтр завантаження файлів просто триватиме так, ніби нічого не сталося. Якщо ви використовуєте фільтри, які автоматично додаються, оскільки вони використовують анотації (наприклад, PrettyFaces), можливо, вам доведеться додати явне замовлення через web.xml. Див. Розділ Як визначити порядок виконання фільтра сервлетів за допомогою приміток у програмі WAR
Тільки якщо ви використовуєте фільтр завантаження файлів PrimeFaces: Filter
у вашому веб-сайті є ще один, який працює до фільтра завантаження файлів PrimeFaces і здійснив RequestDispatcher#forward()
дзвінок. Зазвичай це роблять фільтри для перезапису URL-адрес, такі як PrettyFaces . Це запускає FORWARD
диспетчер, але фільтри прослуховуються за замовчуванням REQUEST
лише для диспетчера.
Щоб виправити це, вам потрібно поставити фільтр завантаження файлів PrimeFaces перед фільтром переадресації, або перенастроїти фільтр завантаження файлів PrimeFaces, щоб він також прослухав FORWARD
диспетчера:
<filter-mapping>
<filter-name>primeFacesFileUploadFilter</filter-name>
<servlet-name>facesServlet</servlet-name>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Там в вкладеному <h:form>
. Це незаконне використання HTML та поведінку браузера не визначено. Більше ніж часто браузер не надсилатиме очікувані дані після надсилання. Переконайтесь, що ви не гніздитесь <h:form>
. Це повністю незалежно від форми enctype
. Тільки взагалі не гніздіть форми.
Якщо у вас все ще виникають проблеми, добре, налагодіть трафік HTTP. Відкрийте набір інструментів для розробників веб-браузера (натисніть F12 в Chrome / Firebug23 + / IE9 +) і перевірте розділ Net / Network. Якщо частина HTTP виглядає добре, тоді налагоджуйте код JSF. Поставте точку перерви FileUploadRenderer#decode()
і просувайтесь звідти.
Збереження завантаженого файлу
Після того, як ви нарешті змусили його працювати, наступне запитання, ймовірно, буде таким: "Як / де я зберігаю завантажений файл?". Ну, продовжуйте тут: Як зберегти завантажений файл у JSF .
web.xml
відповідно до Посібника користувача PrimeFaces. Ви все-таки це прочитали? Однак це не пояснює, чомуmode="simple"
працює для вас.