Glassfish 4,JSF 2.2和PrimeFaces FileUploadEvent不能一起工作 [英] Glassfish 4, JSF 2.2 and PrimeFaces FileUploadEvent not working together

查看:400
本文介绍了Glassfish 4,JSF 2.2和PrimeFaces FileUploadEvent不能一起工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

升级到GlassFish 4和JSF 2.2后,FileUploadEvent停止工作。在JSF 2.1中,它没有任何问题。除了文件上传以外,一切正常。

  GlassFish 4 
JSF 2.2
PrimeFaces 3.4.2和3.5
Commons io版本:2.4
Commons fileupload版本:1.3

控制器端

  public void handleFileUpload(FileUploadEvent event){
System.out.println(HandleFileUpload);
byte [] file = event.getFile()。getContents();
newFieldset.setData(file);
FacesMessage msg = new FacesMessage(Succesful,event.getFile()。getFileName()+is uploaded。);
FacesContext.getCurrentInstance()。addMessage(null,msg);

$ / code>

查看

 < h:form enctype =multipart / form-data> 
< p:fieldset legend =创建新的提要toggleable =truecollapsed =true>
< p:fileUpload fileUploadListener =#{adminHomeController.handleFileUpload}style =margin-top:20px;
mode =advanced
update =messages
sizeLimit =1000000
multiple =false
allowTypes =/(\。| \\ ?\\ /)(GIF | JPE G | PNG)$ //>
< p:inputText label =Baslikstyle =margin-top:20px; required =truevalue =#{adminHomeController.newFieldset.legend}/>
< p:editor style =margin-top:20px;
value =#{adminHomeController.newFieldset.content}/>
< p:commandButton style =margin-top:20px; =#{msg ['common.save']}update =messagesicon =ui-icon-diskactionListener =#{adminHomeController.saveFieldset()}/>
< / p:fieldset>
< p:growl id =messagesshowDetail =true/>
< / h:表格>


解决方案

我终于弄明白了。 Commons-fileuploads方法 parseRequest(httpServletRequest)尝试读取请求的inputStream。由于容器已经读取,所以它是空的。那么可以做些什么来解决这个问题呢?答案比我原本想象的要复杂一点。首先,您需要自己的FileUploadFilter,它看起来像这样:
$ b $ pre $ public class FileUploadFilter implements Filter
{
private final Logger LOGGER = LoggerFactory.getLogger(FileUploadFilter.class);
$ b $ * b $ b *(非Javadoc)
*
* @javax.servlet.Filter#init(javax.servlet.FilterConfig)
* /
@Override
public void init(FilterConfig filterConfig)throws ServletException
{
}
$ b $ * b $ b *(非Javadoc )
*
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse,javax.servlet.FilterChain)
* /
@Override $ b $ public void doFilter(ServletRequest request,ServletResponse response,FilterChain filterChain)throws IOException,ServletException
{
HttpServletRequest httpServletRequest =(HttpServletRequest)请求;
boolean isMultipart =(httpServletRequest.getContentType()== null)? false:httpServletRequest.getContentType()。toLowerCase()。startsWith(multipart /);

if(isMultipart)
{
MultipartRequest multipartRequest = new MultipartRequest(httpServletRequest);
$ b LOGGER.info(文件上传请求成功解析,继续使用包装多部分请求的过滤器链);

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


$ b $ * b $ b *(非Javadoc)
*
*参见javax.servlet.Filter#destroy( )
* /
@Override
public void destroy()
{
LOGGER.info(破坏UploadFilter);

下一步:在web.xml中注册这个过滤器并删除/替换Primefaces过滤。这应该看起来像这样:

 < filter> 
< filter-name> FileUpload Filter< / filter-name>
< filter-class>< YourPackage> .FileUploadFilter< / filter-class>
< / filter>
< filter-mapping>
< filter-name> FileUpload Filter< / filter-name>
< servlet-name> Faces Servlet< / servlet-name>
< / filter-mapping>

不幸的是,这不是。您将需要自己的MultipartRequest,因为您必须自己组装FileItem的列表。但是停止。我们必须使用与FileItem不兼容的javax.servlet.Part类。所以我写了一个新的班级,桥接这两个。你可以在这里找到这个课程: http://pastebin.com/JcfAYjey



最后一块难题是提到的将PartItem和FileUploadFilter连接起来的MultipartRequest。我从Primefaces-Repository中选择了这个类,并根据需要进行了更改(请参阅 http://pastebin.com/Vc5h2rmJ)。

那么你需要做什么:
1.创建三个类FileUploadFilter,MultipartRequest和PartItem
2.在你的web.xml文件
中注册FileUploadFilter 3.享用!

请注意:这并不是一个解决所有问题的解决方案,这只是您在进一步实施中可能采取的一个方向。例如MultipartRequest只能用于内容类型为 image / * 的零件。

随意更改代码;)希望它有帮助!



编辑:我忘了提到一个重要的步骤。你还需要你自己的FileIUploadRenderer。实现的一个Primefaces使用 instanceof 检查来查找MultipartRequest。由于您现在正在使用不同的导入,导入必须更改。剩下的班级可以保持不变( http://pastebin.com/rDUkPqf6 )。不要忘了在faces-config.xml中注册它:

 < render-kit> 
<渲染器>
< component-family> org.primefaces.component< / component-family>
< renderer-type> org.primefaces.component.FileUploadRenderer< / renderer-type>
< renderer-class>< YourPackage> .FileUploadRenderer< / renderer-class>
< /渲染器>
< / render-kit>


After upgrading to GlassFish 4 and JSF 2.2 Primefaces FileUploadEvent stop working. With JSF 2.1 it was working with no problem. Everything is working fine except file uploading. Is there something that I am missing?

    GlassFish 4
    JSF 2.2
    PrimeFaces 3.4.2 and 3.5
    Commons io version: 2.4
    Commons fileupload version: 1.3

Controller side

public void handleFileUpload(FileUploadEvent event) {
    System.out.println("HandleFileUpload");
    byte[] file = event.getFile().getContents();
    newFieldset.setData(file);
    FacesMessage msg = new FacesMessage("Succesful", event.getFile().getFileName() + " is uploaded.");
    FacesContext.getCurrentInstance().addMessage(null, msg);
}

View

<h:form enctype="multipart/form-data">
            <p:fieldset legend="Create new feed" toggleable="true" collapsed="true" >
                <p:fileUpload fileUploadListener="#{adminHomeController.handleFileUpload}" style="margin-top: 20px;"
                              mode="advanced" 
                              update="messages"
                              sizeLimit="1000000" 
                              multiple="false" 
                              allowTypes="/(\.|\/)(gif|jpe?g|png)$/"/>
                <p:inputText label="Baslik" style="margin-top: 20px;" required="true" value="#{adminHomeController.newFieldset.legend}"  /> 
                <p:editor style="margin-top: 20px;"
                          value="#{adminHomeController.newFieldset.content}" />
                <p:commandButton style="margin-top: 20px;" value="#{msg['common.save']}" update="messages" icon="ui-icon-disk" actionListener="#{adminHomeController.saveFieldset()}"/>
            </p:fieldset>
            <p:growl id="messages" showDetail="true"/>
        </h:form>

解决方案

I was finally able to figure it out. Commons-fileuploads method parseRequest(httpServletRequest) tries to read the request's inputStream. Since the container already read it, it is empty. So what can be done to solve this? The answer is a bit more complicated than I initially thought it would be. First you will need your own FileUploadFilter which could look like this:

public class FileUploadFilter implements Filter 
{
private final static Logger LOGGER = LoggerFactory.getLogger(FileUploadFilter.class);

/*
 * (non-Javadoc)
 * 
 * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
 */
@Override
public void init(FilterConfig filterConfig) throws ServletException 
{
}

/*
 * (non-Javadoc)
 * 
 * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
 * javax.servlet.ServletResponse, javax.servlet.FilterChain)
 */
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException 
{
    HttpServletRequest httpServletRequest = (HttpServletRequest) request;
    boolean isMultipart = (httpServletRequest.getContentType() == null) ? false : httpServletRequest.getContentType().toLowerCase().startsWith("multipart/");

    if (isMultipart) 
    {
        MultipartRequest multipartRequest = new MultipartRequest(httpServletRequest);

        LOGGER.info("File upload request parsed succesfully, continuing with filter chain with a wrapped multipart request");

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

/*
 * (non-Javadoc)
 * 
 * @see javax.servlet.Filter#destroy()
 */
@Override
public void destroy() 
{
    LOGGER.info("Destroying UploadFilter");
}

Next: Register this filter in your web.xml and remove/replace the Primefaces filter. This should look something like this:

  <filter>
    <filter-name>FileUpload Filter</filter-name>
    <filter-class><YourPackage>.FileUploadFilter</filter-class>
  </filter>
  <filter-mapping>
     <filter-name>FileUpload Filter</filter-name>
     <servlet-name>Faces Servlet</servlet-name>
  </filter-mapping>

Unfortunately thats not it. You will need your own MultipartRequest since you have to assemble the list of FileItems by yourself. But Stop. We have to work with the javax.servlet.Part classes which are not compatible with the FileItem. So i wrote a new class which bridges these two. You can find this class here: http://pastebin.com/JcfAYjey

The last piece of the puzzle is the mentioned MultipartRequest which links the PartItem and the FileUploadFilter. I took this class from the Primefaces-Repository and changed it according to out needs (see http://pastebin.com/Vc5h2rmJ). The difference is between lines 47 and 57.

So what do you have to do: 1. Create the three classes FileUploadFilter, MultipartRequest and PartItem 2. Register the FileUploadFilter in your web.xml 3. Enjoy!

PLEASE NOTE: This is not intended as a solve-all-problems solution but a merely a direction you may take in further implementations. The MultipartRequest for example will only work for parts with content-type image/*. You may need to change this.

Feel free to change the code ;) Hope it helps!

EDIT: I forgot to mention one important step. You will additionally need your Own FileIUploadRenderer. The one Primefaces implemented uses an instanceof check to find the MultipartRequest. Since you are now using a different one the import has to be changed. The rest of the class can stay the same (http://pastebin.com/rDUkPqf6). Don't forget to register it inside of your faces-config.xml :

<render-kit>
   <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.FileUploadRenderer</renderer-type>
        <renderer-class><YourPackage>.FileUploadRenderer</renderer-class>
     </renderer>
</render-kit>

这篇关于Glassfish 4,JSF 2.2和PrimeFaces FileUploadEvent不能一起工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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