问题
I've read that it is possible to get primefaces fileUpload to work with google appengine with a bit of tweaking. It requires apache fileupload and common io, so I added commons-fileupload-1.2.2.jar and commons-io-1.3.2.jar to my WEB-INF/lib folder.
Then following the instructions of primefaces, I added their servlet:
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>2147483647</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
The thresholdSize is put purposefully high because it is the number of bytes by which the file will be saved to disk rather than retain it in memory, and since no files can be saved using google appengine, it can never be an option.
The actual usage is as follows:
<h:form enctype="multipart/form-data">
<!-- Other text fields go here -->
<p:fileUpload fileUploadListener="#{tjBean.onHandleFileUpload}"
mode="advanced"
update=":toolbarForm:globalMessages"
sizeLimit="500000"
allowTypes="/(\.|\/)(txml)$/" />
<p:commandButton value="Okay" ajax="false" actionListener="#{tjBean.onSaveAction}" />
</h:form>
I've understood that the commandButton must not use ajax and that it must be a full page reload. It seems to let me upload the file without a hitch, but the actionListener never gets triggered. Submitting then the form with the commandButton triggers an exception:
java.lang.NoClassDefFoundError: Could not initialize class org.apache.commons.fileupload.disk.DiskFileItem
at org.apache.commons.fileupload.disk.DiskFileItemFactory.createItem(DiskFileItemFactory.java:199)
at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:361)
...
I'm not sure what I'm doing something wrong or I simply did not get the appropriate versions of the apache libraries to make this work properly. The version of primefaces that I'm using is 3.2. When I search for a solution to this problem, the common response is that google appengine doesn't like the fact that I'm trying to save a file to the disk, and the solution is simply to increase the threshold, but the threshold is as high as it can be, so it shouldn't even be attempting to save the file to disk.
I'd appreciate any help or suggestions, especially if the solution is glaringly obvious and I have yet to see it. Thanks in advance.
回答1:
Neil, you can't write to the disk (i.e. you can't use fileupload.disk on GAE).
App Engine filesystem is always read-only for you app. A couple alternatives you might consider are:
- Blobstore
- Google Cloud Storage
Also, check out this one: http://primefaces-rocks.appspot.com/ui/fileUploadSimple.jsf
回答2:
Fixed the problem by overriding DiskItem for Apache fileupload library 1.2.2.
Specifically, commented static String UID (which uses blacklisted class java.rmi.server.UID) and entire contents of write method (I'll set threshold high so it should never require to call it).
Obviously it's not the ideal solution, but it will work so long as I don't need to update file upload library, which I doubt I'll need to in the near future.
回答3:
@Neil
I'm sorry but I cannot comment. Can you tell me how you change the method
getTempFile() {
if (tempFile == null) {
File tempDir = repository;
if (tempDir == null) {
tempDir = new File(System.getProperty("java.io.tmpdir"));
}
String tempFileName = format("upload_%s_%s.tmp", UID, getUniqueId());
tempFile = new File(tempDir, tempFileName);
}
return tempFile;
}
What did you use instead of UID?
来源:https://stackoverflow.com/questions/10065313/getting-primefaces-pfileupload-to-work-under-google-appengine