Marcos Sousa’s Blog

Blog sobre desenvolvimento de software
  • rss
  • Home
  • Sobre

Incompatibilidades do componente RichFaces: rich:fileUpload

Marcos Sousa | May 4, 2008

Estes últimos dias estive testando o componente “rich:fileUpload“. O componente é bastante interessante, porém é bastante sensível. Encontrei incompatibilidades com componentes do próprio richfaces, do myfaces e com o seam framework.

Até o momento verifiquei que usar o componente “rich:fileUpload” dentro do componente “rich:simpleTogglePanel”. Todos os testes que eu realizei ele não chama o evento definido em fileUploadListener. Até onde eu percebi me parece que o parâmetro que o “rich:fileUpload” usa para controlar o envio dos arquivos é perdido quando ele está dentro do “rich:simpleTogglePanel“.

Outro problema do componente é a incompatibilidade da versão 3.2.0 com o Seam Framework. Seguindo um comportamento semelhante ao do problema acima o evento definido no fileUploadListener não é chamado. Pelo que eu vi no JIRA havia problemas com o ciclo de vida do Seam, porém estes problemas já foram solucionados.

Havia também problemas com o envio de diversos arquivos ao mesmo tempo. Todos estes problemas também foram corrigidos.

A dica é: se você estiver usando o Seam Framework e o RichFaces 3.20 e pensar em usar o rich:fileUpload, atualize para as versões:
Seam 2.0.2 Cr1 (ou superior)
RichFaces 3.2.1 (Sugiro pegar a versão mais recente)
API
Implementação
User Interface

Comments
21 Comments »
Categories
Java, Java EE, Java Server Faces, Jboss Seam, RichFaces
Tags
incompatiblidades, Jboss Seam, Rich Faces, rich:fileUpload, rich:simpleTogglePanel, RichFaces, RichFaces 3.2, Seam Framework
Comments rss Comments rss
Trackback Trackback

Incompatibilidades MyFaces Tomahawk e RichFaces 3.2

Marcos Sousa | April 28, 2008

Quem usa os componentes do Myfaces Tomahawk e RichFaces em um mesmo projeto, poderá ter problemas ao atualizar a versão do RichFaces para a versão 3.2. O problema é que a versão 3.2 tem um componente de upload em ajax que requer algumas funcionalidades extras que foram adicionadas ao filtro do RichFaces. Porém estas configurações entram em conflito com as funcionalidades do Filtro de extensão do Myfaces.

Os conflitos gerados impedem o funcionamento apenas dos componentes de upload de ambos os casos. Isto porque ambos criam um objeto para adaptar a requisição que envolve envio de arquivos (enctype=”multipart/form-data”). Vi em alguns fóruns de discussão do RichFaces que a maneira de contornar o problema seria alterar a ordem de declaração dos filtros, porém para alguns tipos de requisições esta solução não resolve.

Uma forma de resolver a incompatibilidade é sobrescrever um dos dois filtros e anular a funcionalidade de upload, é uma solução temporária que irá anular o funcionamento do componente de uploads do filtro sobrescrito. O exemplo abaixo reimplementa o filtro do Tomahawk:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
package com.marcossousa.filters.myfaces;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.myfaces.renderkit.html.util.AddResource;
import org.apache.myfaces.renderkit.html.util.AddResourceFactory;
import org.apache.myfaces.webapp.filter.ExtensionsResponseWrapper;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Override para evitar problemas de inconsistência dos filtros do RichFaces e Tomahawk.
 */

public class ExtensionsFilter implements Filter {

    private Log log = LogFactory.getLog(ExtensionsFilter.class);

    private int _uploadMaxFileSize = 100 * 1024 * 1024; // 10 MB

    private int _uploadThresholdSize = 1 * 1024 * 1024; // 1 MB

    private String _uploadRepositoryPath = null; //standard temp directory

    private ServletContext _servletContext;

    public static final String DOFILTER_CALLED = "org.apache.myfaces.component.html.util.ExtensionFilter.doFilterCalled";

    /**
     * Init method for this filter
     */

    public void init(FilterConfig filterConfig) {

        String param = filterConfig.getInitParameter("uploadMaxFileSize");

        _uploadMaxFileSize = resolveSize(param, _uploadMaxFileSize);

        param = filterConfig.getInitParameter("uploadThresholdSize");

        _uploadThresholdSize = resolveSize(param, _uploadThresholdSize);

        _uploadRepositoryPath = filterConfig.getInitParameter("uploadRepositoryPath");

        _servletContext = filterConfig.getServletContext();
    }

    private int resolveSize(String param, int defaultValue) {
        int numberParam = defaultValue;

        if (param != null) {
            param = param.toLowerCase();
            int factor = 1;
            String number = param;

            if (param.endsWith("g")) {
                factor = 1024 * 1024 * 1024;
                number = param.substring(0, param.length() - 1);
            } else if (param.endsWith("m")) {
                factor = 1024 * 1024;
                number = param.substring(0, param.length() - 1);
            } else if (param.endsWith("k")) {
                factor = 1024;
                number = param.substring(0, param.length() - 1);
            }

            numberParam = Integer.parseInt(number) * factor;
        }
        return numberParam;
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        if(request.getAttribute(DOFILTER_CALLED)!=null)
        {
            chain.doFilter(request, response);
            return;
        }

        request.setAttribute(DOFILTER_CALLED,"true");

        if (!(response instanceof HttpServletResponse)) {
            chain.doFilter(request, response);
            return;
        }

        HttpServletResponse httpResponse = (HttpServletResponse) response;
        HttpServletRequest httpRequest = (HttpServletRequest) request;

        HttpServletRequest extendedRequest = httpRequest;

        // Serve resources
        AddResource addResource;

        try
        {
            addResource=AddResourceFactory.getInstance(httpRequest);
            if( addResource.isResourceUri(_servletContext, httpRequest ) ){
                addResource.serveResource(_servletContext, httpRequest, httpResponse);
                return;
            }
        }
        catch(Throwable th)
        {
            log.error("Exception wile retrieving addResource",th);
            throw new ServletException(th);
        }

        try
        {
            addResource.responseStarted();
           
            if (addResource.requiresBuffer())
            {
                ExtensionsResponseWrapper extendedResponse = new ExtensionsResponseWrapper((HttpServletResponse) response);
       
                // Standard request
                chain.doFilter(extendedRequest, extendedResponse);
       
                extendedResponse.finishResponse();
       
                // write the javascript stuff for myfaces and headerInfo, if needed
                HttpServletResponse servletResponse = (HttpServletResponse)response;
       
                // only parse HTML responses
                if (extendedResponse.getContentType() != null && isValidContentType(extendedResponse.getContentType()))
                {
                    addResource.parseResponse(extendedRequest, extendedResponse.toString(),
                            servletResponse);
       
                    addResource.writeMyFacesJavascriptBeforeBodyEnd(extendedRequest,
                            servletResponse);
       
                    if( ! addResource.hasHeaderBeginInfos() ){
                        // writes the response if no header info is needed
                        addResource.writeResponse(extendedRequest, servletResponse);
                        return;
                    }
       
                    // Some headerInfo has to be added
                    addResource.writeWithFullHeader(extendedRequest, servletResponse);
       
                    // writes the response
                    addResource.writeResponse(extendedRequest, servletResponse);
                }
                else
                {

                    byte[] responseArray = extendedResponse.getBytes();

                    if(responseArray.length > 0)
                    {
                        // When not filtering due to not valid content-type, deliver the byte-array instead of a charset-converted string.
                        // Otherwise a binary stream gets corrupted.
                        servletResponse.getOutputStream().write(responseArray);
                    }
                }
            }
            else
            {
                chain.doFilter(extendedRequest, response);
            }
        }
        finally
        {
            addResource.responseFinished();        
        }
    }

    public boolean isValidContentType(String contentType)
    {
        return contentType.startsWith("text/html") ||
                contentType.startsWith("text/xml") ||
                contentType.startsWith("application/xhtml+xml") ||
                contentType.startsWith("application/xml");
    }

    /**
     * Destroy method for this filter
     */

    public void destroy() {
        // NoOp
    }
}

Porém, uma forma eficaz de resolver o problema é a criação de um parâmetro para identificar qual componente de upload está sendo usado e o filtro trataria a criação ou não do objeto de adaptação  o que acabaria com as incompatibilidades. Já fiz a requisição do JIRA, agora é aguardar as correções.

Comments
12 Comments »
Categories
Java, Java EE, Java Server Faces
Tags
Filter, incompatiblidades, MyFaces, Rich Faces, rich:inputUpload, RichFaces, RichFaces 3.2, t:inputUpload, Tomahawk
Comments rss Comments rss
Trackback Trackback

Núvens de tags

Agile Agile Conference Facelets GET Hibernate incompatiblidades Itext Java Java EE Java Magazine Java Server Faces JavaServer Faces Java Vídeo Magazine Jboss jboss-seam-itext Jboss Developer Studio Jboss Seam JDBC type: 7 JPA JSF linux mare marébh maré de agilidade Microsoft No Dialect mapping for JDBC type: 7 Page Actions PostGreSQL RHDS rich:fileUpload RichFaces Rich Faces RichFaces 3.2 Scrum Seam-gen Seam Framework Seam PDF Spring Spring Framework TDD URL Rewrite URL User Friendly Variable Resolver Vídeo Aula XP

Meus últimos tweets

  • @acarlos1000 This site should help you: http://www.mandarintools.com/numbers.html ;) 3 days ago
  • My new toys. Now I have cool things to read. #epicwin http://yfrog.com/mwub1zj 1 week ago
  • rs RT @gisahcorrea: geralmente, acho que estar na TPM é um saco. mas daí eu olho pro tamanho que meus peitos ficam e penso "é, vale a pena." 2 weeks ago
  • Bom livro grátis escrito por quem fez o Prawn e o Ruport, para quem já sabe Ruby http://rubybestpractices.com/ (via @lucabastos) 2 weeks ago
  • Parabéns!!! RT @rodrigoy: Aha... just bought http://kanbansket.ch domain! #KanbanSketch #ProjetoAgileBrazil #Switzerland 2 weeks ago
  • @pac_man Parabéns pelo projeto, o delay é muito pequeno! Menor que o da NET! 2 weeks ago
  • Algumas fotos do mini-curso de rails ontem na Una http://tinyurl.com/25vjen4 #railsuna 2 weeks ago
  • @danielvlopes Desenvolver em rails o ajuda a se tornar um desenvolvedor melhor #railsuna http://yfrog.com/3mafappj 2 weeks ago
  • ;) @joaovitor Pegadinha do malandro em Ruby http://gist.github.com/470707 #railsuna se alguém escrever algo assim na sua equipe dá um pedala 2 weeks ago
  • Django 1.2 template application for appengine: http://tinyurl.com/36nuqzz 2 weeks ago

Anúcios

Categorias

  • .net
  • Agile
  • Agile Conference 2009
  • Artigos
  • Atualidades
  • c++
  • cinema
  • Django
  • DRY
  • Eventos
  • Flex
  • Formula 1
  • Hibernate
  • IDE
  • Inutilidades
  • Java
  • Java EE
  • Java Server Faces
  • Jboss Seam
  • linux
  • Mac OS
  • Microsoft
  • Open-source
  • Palestras
  • Python
  • RAD
  • RIA
  • RichFaces
  • Scrum
  • Software Livre
  • Spring
  • Spring Annotations
  • TDD
  • Testes
  • Uncategorized
  • Vídeo Aulas

Links recomendados

  • AJ Soluções
  • Ary Júnior
  • Erko Bridee
  • Fragmental
  • Fragmental TW
  • Guilherme Chapiewski
  • Handerson Frota
  • Jeveaux
  • Juliano Carniel
  • Onipresente
  • Passes de Letra
  • PortalJava.com
  • Rafael Carneiro
  • Rafael Pontes

DevMedia Post’s

Get Adobe Flash playerPlugin by wpburn.com wordpress themes
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox