在Google App Engine上使用PrimeFaces 4.0和jsf 2.2上传文件 [英] Uploading files with PrimeFaces 4.0 , and jsf 2.2 on google app engine

查看:118
本文介绍了在Google App Engine上使用PrimeFaces 4.0和jsf 2.2上传文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用: -primefaces 4.0 -jsf mojarra 2.2 -google应用引擎(servlet API 2.5) 和此解决方案(获取Primefaces p:fileUpload在Google Appengine下可以正常工作)对我没有帮助,因为我的primefaces版本更高.当我在下面将我的表单与p:commandButton一起使用时:

I'm using: -primefaces 4.0 -jsf mojarra 2.2 -google app engine (servlet api 2.5) and this solution (Getting primefaces p:fileUpload to work under google appengine) doesn't help me because my version of primefaces is higher. There is exception when I'm using my form below with p:commandButton:

java.lang.NoSuchMethodError: javax.servlet.http.HttpServletRequest.getPart(Ljava/lang/String;)Ljavax/servlet/http/Part;
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:60)
at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:37)
at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:44)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:831)
at javax.faces.component.UIInput.decode(UIInput.java:771)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1225)
at javax.faces.component.UIInput.processDecodes(UIInput.java:676)
at javax.faces.component.UIForm.processDecodes(UIForm.java:225)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1220)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:929)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646)
....

这是因为google不支持servlet api 3.0.我真的现在找不到解决方案.不能选择运行primefaces 3.5,因为该项目与JSF 2.2兼容,而2.2与primefaces 3.5不兼容.

and this is because google don't support servlet api 3.0. I realy can't find a solution for now. Running primefaces 3.5 is not a option because the project is with JSF 2.2 and 2.2 is not compatible with primefaces 3.5.

该主题的一条可用评论:如何使用PrimeFaces p:fileUpload?永远不会调用侦听器方法或UploadedFile为空

One usable comment from this topic: How to use PrimeFaces p:fileUpload? Listener method is never invoked or UploadedFile is null

更新:由于PrimeFaces 4.x与JSF 2.2和Servlet 3.0结合使用时,不再需要过滤器.将使用Servlet 3.0/JSF 2.2本机API代替Apache Commons FileUpload.但是,其他规则仍然适用,并且由于可能的原因,您可以刮擦#1和#2.

Update: since PrimeFaces 4.x, when used in combination with JSF 2.2 and Servlet 3.0, the filter is not necessary anymore. The Servlet 3.0 / JSF 2.2 native API will be used instead of Apache Commons FileUpload. Other rules however still apply and from the possible causes you can scratch #1 and #2.

我的表单:

<h:form enctype="multipart/form-data">
<p:fileUpload id="filePhoto" fileUploadListener="#{atlasCasesMB.handleFileUpload}" mode="advanced" dragDropSupport="false"  
    update=":messages" sizeLimit="614400" fileLimit="3" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
</h:form>

这种形式的fileUploadListener不会被调用.

In this form fileUploadListener is not invoked.

我尝试使用以下主题的解决方案:使primefaces p:fileUpload在Google Appengine下工作修改DiskFileItem),但显然这无济于事,因为JSF 2.2使用本机API而不是Apache Commons FileUpload.

I've tried to use the solution from this topic: Getting primefaces p:fileUpload to work under google appengine modify the DiskFileItem), but obviously this cannot help because JSF 2.2 uses native API instead of Apache Commons FileUpload.

    <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>

有什么建议吗? (降级primefaces和jsf是不可行的,因为该项目处于最后阶段)

Any suggestions? (Downgrading primefaces and jsf is not an option because the project is in final stage)

我尝试过的解决方案是使用以下方法强制Primeface使用apache通用文件上传(commons-fileupload-1.3.jar):

The solution ,that I tried, is to force primefaces to use apache common file upload (commons-fileupload-1.3.jar) using this:

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

然后我使用了过滤器:

<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>

这里重要的是将thresholdSize设置得太大,以至于某些apache通用类(我忘记了哪个)中的write方法不会被调用.最后,从primefaces 4.0源文件中添加过滤器FileUploadFilter: http://www.primefaces.org/downloads. html

important here is to set thresholdSize so big that write method in some of the apache common classes(I forgot which) is not invoked. And finally add the filter FileUploadFilter from primefaces 4.0 source files: http://www.primefaces.org/downloads.html

到目前为止,我曾经使用过的所有资源:

All sources that I used to get to this point:

http://davebarber.blog.com/2010/10/15/jsf-2-0-on-google-app-engine/

PrimeFaces 4.0 FileUpload可与Mojarra 2.2一起使用,但不能与MyFaces 2.2一起使用

如何使用PrimeFaces p:fileUpload?永远不会调用侦听器方法或UploadedFile为空

>获取primitives p:fileUpload在Google Appengine下工作

这会触发:

java.lang.verifyerror inconsistent stackmap frames at branch target

推荐答案

为防止质素使用其本机文件上传,请添加以下参数.

To prevent primefaces to use its native file upload, add the following parameter.

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

然后我使用了过滤器:

<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>

这里重要的是将thresholdSize设置得太大,以至于某些apache通用类(我忘记了哪一个)中的write方法没有被调用.最后,从修改的primefaces 4.0添加过滤器FileUploadFilter:

important here is to set thresholdSize so big that write method in some of the apache common classes(I forgot which) is not invoked. And finally add the filter FileUploadFilter from primefaces 4.0 modified:

package org.primefaces.webapp.filter;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.gmr.web.multipart.GFileItemFactory;
import org.primefaces.webapp.MultipartRequest;

public class FileUploadFilter implements Filter {

    private final static Logger logger = Logger.getLogger(FileUploadFilter.class.getName());

    private final static String THRESHOLD_SIZE_PARAM = "thresholdSize";

    private final static String UPLOAD_DIRECTORY_PARAM = "uploadDirectory";

    private String thresholdSize;

    private String uploadDir;

    public void init(FilterConfig filterConfig) throws ServletException {
        thresholdSize = filterConfig.getInitParameter(THRESHOLD_SIZE_PARAM);
        uploadDir = filterConfig.getInitParameter(UPLOAD_DIRECTORY_PARAM);

        logger.warning("init:uploadDir=" + uploadDir + "; thresholdSize=" + thresholdSize);
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        boolean isMultipart = ServletFileUpload.isMultipartContent(httpServletRequest);

        if (isMultipart) {
                logger.warning("Parsing file upload request");

            // start change
            FileItemFactory diskFileItemFactory = new GFileItemFactory();
            /*
             * if(thresholdSize != null) { diskFileItemFactory.setSizeThreshold(Integer.valueOf(thresholdSize)); } if(uploadDir != null) { diskFileItemFactory.setRepository(new File(uploadDir)); }
             */
            // end change

            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
            MultipartRequest multipartRequest = new MultipartRequest(httpServletRequest, servletFileUpload);

            if (logger.isLoggable(Level.FINE))
                logger.fine("File upload request parsed succesfully, continuing with filter chain with a wrapped multipart request");

            filterChain.doFilter(multipartRequest, response);
        } else {
            filterChain.doFilter(request, response);
        }
    }

    public void destroy() {
        if (logger.isLoggable(Level.FINE))
            logger.fine("Destroying FileUploadFilter");
    }

}

表格:

<h:form >
<p:fileUpload id="filePhoto" fileUploadListener="#{atlasCasesMB.handleFileUpload}" mode="advanced" dragDropSupport="false"
                    update=":messages" sizeLimit="614400" fileLimit="3" allowTypes="/(\.|\/)(gif|jpe?g|png)$/" />
                <br />
<p:commandButton value="#{bundle['save']}" actionListener="#{atlasCasesMB.saveCase}"  process="@form" />
</h:form>

文件上传处理程序:

public void handleFileUpload(FileUploadEvent event) {
        log.warning("handleFileUpload(FileUploadEvent event)");
        UploadedFile uploadedFile = event.getFile();
        photosArr.add(uploadedFile.getContents());
        //photos.add(new File(uploadedFile.getFileName()));
        FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");  
        FacesContext.getCurrentInstance().addMessage(null, msg);
    }

字节数组照片列表:

private List<byte[]> photosArr;

图书馆:

  • commons-fileupload-1.3.jar
  • commons-io-2.4.jar
  • gmultipart-0.2.jar
  • portlet-2.0.jar
  • primefaces-4.0.jar

DiskFileItem: 注释UID和写入方法内部

DiskFileItem: comment UID and inside of write method

和ViewScoped Bean

and ViewScoped Bean

有第二种方法可以做到这一点: 使用分段请求球衣:

there is second way to do this: using multipart request to jersey:

<p:dialog id="upladPhotoDialog" widgetVar="upladPhotoDlg" header="#{bundle['uploading.photos']}" >
    <form action="rest/case" method="post" enctype="multipart/form-data">
        <p>#{bundle['upload.photo.select.images.to.upload']}</p>
    <br />
    <input id="photo1" type="file" name="photo1" />
    <br />
    <input id="photo2" type="file" name="photo2" />
    <br />
    <input id="photo3" type="file" name="photo3" />
    <br />
    <input id="caseId" type="text" name="caseId" style="display:none" value="#{atlasCasesMB.savedCaseId}" />
    <br />
    <input id="btn-post" class="active btn" type="submit" value="Send" />
</form>

@POST
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    public void insertPhotoForCase (
            @FormDataParam("photo1") InputStream photoIS1,
            @FormDataParam("photo2") InputStream photoIS2,
            @FormDataParam("photo3") InputStream photoIS3,
            @FormDataParam("caseId") String caseId , @Context HttpServletRequest httpRequest , @Context HttpServletResponse httpResponse) {
        try {
            DataService<Case> das = new CaseDataService();
            Case caze = das.find(Integer.parseInt(caseId));
            byte[] photoBytes = IOUtils.toByteArray(photoIS1);
            if(photoBytes.length != 0 ){
                sendPhotoToBlob (createPhoto(caze).getId() ,photoBytes);
            }
            photoBytes = IOUtils.toByteArray(photoIS2);
            if(photoBytes.length != 0 ){
                sendPhotoToBlob (createPhoto(caze).getId() ,photoBytes);
            }
            photoBytes = IOUtils.toByteArray(photoIS3);
            if(photoBytes.length != 0 ){
                sendPhotoToBlob (createPhoto(caze).getId() ,photoBytes);
            }
            //currentResponse.sendRedirect("/atlascases.xhtml");
            _context.getRequestDispatcher("/atlascases.xhtml").forward(httpRequest, httpResponse);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

src文件夹中的

file:jersey-multipart-config.properties,内部文本:

file:jersey-multipart-config.properties in src folder with text inside:

bufferThreshold = -1

在web.xml中

    <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>com.smartinteractive.medimaging.service</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

这篇关于在Google App Engine上使用PrimeFaces 4.0和jsf 2.2上传文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆