구성 및 문제 해결 방법 <p:fileUpload>
은 PrimeFaces 버전에 따라 다릅니다.
모든 PrimeFaces 버전
아래 요구 사항은 모든 PrimeFaces 버전에 적용됩니다.
의 enctype
속성 <h:form>
을로 설정해야 multipart/form-data
합니다. 이것이 없으면 ajax 업로드가 작동 할 수 있지만 일반적인 브라우저 동작은 지정되지 않으며 양식 구성 및 웹 브라우저 만들기 / 버전에 따라 다릅니다. 항상 안전한쪽에 있도록 지정하십시오.
사용할 때 mode="advanced"
(즉, ajax 업로드, 이것이 기본값), <h:head>
(마스터) 템플릿에 있는지 확인하십시오 . 이렇게하면 필요한 JavaScript 파일이 제대로 포함됩니다. 이것은 mode="simple"
(AJAX가 아닌 업로드)에는 필요하지 않지만 다른 모든 PrimeFaces 구성 요소의 모양과 기능이 깨질 수 있으므로 어쨌든 놓치고 싶지 않습니다.
사용하는 경우 mode="simple"
(즉, ajax가 아닌 업로드) PrimeFaces 명령 단추 / 링크에서를 사용하여 ajax를 비활성화해야하며 (PrimeFaces <= 7.x의 경우) 또는 (PrimeFaces> = 8.x의 경우) 대신 with ajax="false"
를 사용해야합니다.<p:fileUpload value>
<p:commandButton action>
<p:fileUpload fileUploadListener>
<p:fileUpload listener>
따라서 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"
. 따라서 이러한 경우 지정할 필요가 없습니다.
또한 나중에 HTTP 요청에 의해 호출 된 다른 Bean 메소드가 아니라 위에 언급 된 메소드 내에서 즉시 파일 내용을 읽어야합니다 . 이는 업로드 된 파일 내용이 요청 범위이므로 이후 / 다른 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를 올바르게 설치하고 구성하는 방법이 명확하지 않은 경우 Maven을 통해 JSF 라이브러리를 올바르게 설치하고 구성하는 방법을 참조하십시오. 그리고 우리의 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 FileUpload 대신 네이티브 API를 사용할 때 반환 됩니다. UploadedFile#getInputStream()
대신 사용해야 합니다. p : fileUpload에서 업로드 된 이미지를 MySQL에서 BLOB로 삽입하는 방법 도 참조하십시오 .
네이티브 API의 또 다른 잠재적 인 문제는 업로드 구성 요소를 처리하지 않는 다른 "일반"ajax 요청이 실행되는 양식에 업로드 구성 요소가있는 경우입니다. PrimeFaces 4.0 / JSF 2.2.x-javax.servlet.ServletException : The request content-type is not a multipart / form-data에서 파일 업로드가 AJAX에서 작동하지 않음을 참조하십시오 .
두 문제 모두 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+를 사용하고 JSF 2.2 / Servlet 3.0 기본 파일 업로드 대신 Apache Commons FileUpload를 명시 적으로 사용하려는 경우 언급 된 라이브러리 옆에 다음 컨텍스트 매개 변수도 필터링해야합니다 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()
호출. 일반적으로 PrettyFaces 와 같은 URL 재 작성 필터 가이를 수행합니다. 이는 FORWARD
디스패처를 트리거 하지만 필터는 기본적으로 REQUEST
디스패처에서만 수신 합니다.
이 문제를 해결하려면 전달 필터 앞에 PrimeFaces 파일 업로드 필터 를 배치하거나 FORWARD
디스패처에서도 수신하도록 PrimeFaces 파일 업로드 필터를 재구성해야합니다 .
<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 트래픽을 디버그하십시오. 웹 브라우저의 개발자 도구 모음을 열고 (Chrome / Firebug23 + / IE9 +에서 F12 누르기) Net / Network 섹션을 확인합니다. HTTP 부분이 괜찮아 보이면 JSF 코드를 디버그하십시오. 중단 점을 설정 FileUploadRenderer#decode()
하고 거기에서 진행하십시오.
업로드 된 파일 저장
마침내 작동하게 된 후 다음 질문은 아마도 "업로드 된 파일을 어떻게 / 어디에 저장합니까?"와 같을 것입니다. 음, 계속 여기 : 업로드 된 파일을 JSF에 저장하는 방법 .
web.xml
PrimeFaces 사용자 가이드 에 따라 PrimeFaces 업로드 필터를 등록하지 않았기 때문일 수 있습니다 . 어쨌든 읽어 봤어? 그러나 그것은 왜mode="simple"
당신에게 효과가 있는지 설명하지 않습니다 .