当前位置: 首页 > 知识库问答 >
问题:

在google app engine上用PrimeFaces4.0和JSF2.2上传文件

戚英逸
2023-03-14
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 API3.0。我真的现在找不到解决办法。运行PrimeFaces3.5不是一个选项,因为该项目使用JSF2.2,而2.2与PrimeFaces3.5不兼容。

这个主题的一个有用的评论:如何使用PrimeFaces p:FileUpload?从未调用侦听器方法或UploadedFile为空

更新:自从PrimeFaces4.x之后,当与JSF2.2和Servlet3.0结合使用时,过滤器就不再是必需的了。将使用Servlet3.0/JSF2.2本机API,而不是Apache Commons FileUpload。然而,其他规则仍然适用,从可能的原因来看,您可以擦掉#1和#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>
    <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使用apache公共文件上传(commons-fileupload-1.3.jar),方法如下:

<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方法。最后从PrimeFaces4.0源文件中添加FileUploadFilter:http://www.primefaces.org/downloads.html

这将激发:

java.lang.verifyerror inconsistent stackmap frames at branch target

共有1个答案

彭洲
2023-03-14

若要防止primefaces使用其本机文件上载,请添加以下参数。

<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方法。最后添加PrimeFaces4.0修改后的过滤器FileUploadFilter:

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

DiskFileItem:注释UID和write方法内部

和视图Bean

还有第二种方法:使用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();
        }
    }

文件:jersey-multipart-config.properties(位于src文件夹中,其中包含文本:

bufferThreshold = -1
    <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>
 类似资料:
  • 我想将文件从一台服务器上传到另一台FTP服务器,以下是我的上传文件代码,但它抛出错误为: 远程服务器返回错误:(550)文件不可用(例如,找不到文件,无法访问)。 这是我的代码: 你能告诉我哪里出了问题吗?

  • 问题内容: 看来我还没有清楚地传达出我的问题。我需要发送一个文件(使用AJAX),并且需要使用Nginx HttpUploadProgressModule 获取文件的上传进度。我需要一个很好的解决方案。我已经尝试过使用jquery.uploadprogress插件,但是我发现自己不得不重写其中的大部分内容,以使其在所有浏览器中都能正常工作并使用AJAX发送文件。 我所需要的只是执行此操作的代码,它

  • 本文向大家介绍PHP实现文件上传和多文件上传,包括了PHP实现文件上传和多文件上传的使用技巧和注意事项,需要的朋友参考一下 在PHP程序开发中,文件上传是一个使用非常普遍的功能,也是PHP程序员的必备技能之一。值得高兴的是,在PHP中实现文件上传功能要比在Java、C#等语言中简单得多。下面我们结合具体的代码实例来详细介绍如何通过PHP实现文件上传和多文件上传功能。 要使用PHP实现文件上传功能,

  • 我是android应用程序开发的新手,试图开发一个web视图应用程序,但似乎无法让文件上传工作。。。请帮忙 这是我的网页视图代码 公共类WebActive扩展了活动{ } 所以我在wv下添加了这个代码。setWebChromeClient//未记录的魔术方法覆盖//br>//如果您尝试在此处放置@override,Eclipse将对您发誓//Android 3.0 public void open

  • 我正在尝试使用多部分实体方法上传文件。但它失败,错误说{“错误”:“文件参数值'无'无效”} 我的代码是: File File = new File(" C:/Users/SST-06/Desktop/new . txt "); 我的实体文件包含所有提到的参数。 -hkYO-pblk 0 uqlxjtvklrbkosxz 7 mye-8 wbvbvanx Content-Disposition:f

  • 问题内容: 我希望在用户使用$ .ajax在输入文件中选择文件时异步上传文件。但是接收调用返回索引的PHP未定义。jQuery代码是下一个: 以及调用该调用的php: 谢谢 问题答案: 您无法使用AJAX上传文件,但可以使用,因此不必刷新当前页面。 很多人都对插件束手无策,但您可以轻松完成此操作,并具有AJAX请求的所有功能。 不必使用AJAX函数,而是将表单提交到具有事件处理程序的隐藏文件中,以