Marcos Sousa’s Blog

Blog sobre desenvolvimento de software
  • rss
  • Home
  • Sobre

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.

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

« Tags JSTL em Facelets funcionam? Vídeo Aula Jboss Seam: Seam Gen parte 3 »

13 Responses to “Incompatibilidades MyFaces Tomahawk e RichFaces 3.2”

  1. Wesley says:
    June 27, 2009 at 2:11 am

    Estou com esse mesmo problema. Tenho um projeto MyFaces + RichFaces e não consigo usar o upload do rich faces, gostaria de mais detalhes de como resolver esse problema.

    Reply
  2. Marcos Sousa says:
    June 27, 2009 at 2:23 am

    @Wesley

    Não teve muito segredo não cara, peguei o código fonte do ExtesionFilter e removi o código que ele tratava de uploads. Claro que esta situação o componente de upload do Myfaces não funcionará. :)

    Reply
  3. Wesley says:
    June 27, 2009 at 12:38 pm

    Certinho Marcos,

    Agora está funcionando aqui obrigado pela dica.

    Reply
  4. Luiz Fraga says:
    August 4, 2009 at 11:48 am

    Estou com esse problema tb. Marcos, vc removeu na configuração do web.xml? Como poderia sobrepor o filtro do myfaces?

    Reply
  5. Luiz Fraga says:
    August 4, 2009 at 2:18 pm

    Já solucionado. É só atualizar as dependências com as novas versões. E comentar no web.xml o filtro do ExtensionsFilter.

    org.apache.myfaces.core
    myfaces-api
    1.2.7
    compile

    org.apache.myfaces.core
    myfaces-impl
    1.2.7
    compile

    org.apache.myfaces.tomahawk
    tomahawk
    1.1.9
    runtime

    javax.servlet
    jstl

    Reply
  6. Marcos Sousa says:
    August 4, 2009 at 2:37 pm

    @Luiz Fraga,

    Parabéns cara! No meu caso eu desativei o filtro.

    Reply
  7. Ticco says:
    October 26, 2009 at 4:03 pm

    Não consegui nem configurar o Web.xml para funcionar o Richfaces com o Tomahawk. Alguma boa alma poderia postar um exemplo?

    Reply
  8. Marcos Sousa says:
    November 7, 2009 at 10:28 am

    Oi Ticco,

    Vou mandar o arquivo com exemplo no seu e-mail.

    ;)

    Reply
    • Rafael Bomfim says:
      February 19, 2010 at 2:00 pm

      Marcos,

      Estou com o mesmo problema, eu gostaria de fazer da seguinte forma: “peguei o código fonte do ExtesionFilter e removi o código que ele tratava de uploads”.

      Mas como não sabia nem por onde começar, eu fiz da seguinte forma: “É só atualizar as dependências com as novas versões. E comentar no web.xml o filtro do ExtensionsFilter”

      Até aqui BLZ!!
      Comentando funcionou, mas será que isso não vai dar conflito em outros lugares?
      Comentando o ExtensionsFilter os componentes do tomahawk vão continuar funcionando?
      Teria como deixar os filters do richfaces e do myfaces ativos e invalidar somente o upload do tomahawk?

      Valeu pelas respostas!

      Reply
  9. Rafael Bomfim says:
    February 19, 2010 at 2:16 pm

    Respondendo 2 de minhas 3 perguntas:

    P: Comentando funcionou, mas será que isso não vai dar conflito em outros lugares?
    R: Sim. Comentando gerou impacto em outras partes do sistema.

    P: Comentando o ExtensionsFilter os componentes do tomahawk vão continuar funcionando?
    R: Não. Os componentes tomahawk não estão mais funcionando. Inclusive o t:saveState que eu uso em vários lugares parou de funcionar.

    Agora só sobrou um pergunta: Teria como deixar os filters do richfaces e do myfaces ativos e invalidar somente o upload do tomahawk?

    Reply
    • Marcos Sousa says:
      February 19, 2010 at 4:31 pm

      Rafael,

      Atualizei o post colocando um exemplo de implementeção. Ele deve substituir o ExtensionFilter padrão do Tomahawk. Qualquer dúvida é só falar.

      Reply
  10. Robekson says:
    July 7, 2010 at 2:17 pm

    No meu caso so mudei a ordem dos filtros e funcionou, declaro o filtro do richfaces primeiro e em seguida o do Tomahawk. Funcionou sem problemas.

    Valeu !!!!!!

    Reply
  11. RenZo says:
    November 4, 2010 at 10:41 am

    Fala pessoal belezinha? Poxa to penando pra colocar o RichFaces+MyFaces pra operar junto porém ta foda! Alguém poderia me dar uma mão?

    Abraços!

    Reply

Leave a Reply

Click here to cancel reply.

Núvens de tags

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

  • Great article about the importance of sleeping. http://t.co/vfFyS1ri 16 hours ago
  • Aos participantes do Bhjs que gostariam de vir para a Globo.com, segue as outras vagas http://t.co/KjBinf4x #bhjs #beagajs 2 weeks ago
  • Se você precisa buscar dado no disco, prefira assíncrona @luciano #bhjs #beagajs http://t.co/5gCHp7P8 2 weeks ago
  • @DouglasAguiar @HerberthAmaral Porque na copa? 2 weeks ago
  • Slides da palestra 'Indo além com jQuery' #bhjs #beagajs http://t.co/wHbhaI75 2 weeks ago
  • @araujolucas na parte da frente a temperatura está melhor 2 weeks ago
  • Começando a palestra do @cmilfont no #bhjs #beagajs http://t.co/9DZt7MQj 2 weeks ago
  • @isaias_barroso @DeivissonBruno @cmilfont gula ao extremo:) 2 weeks ago
  • Palestra com insights do desenvolvimento do paparazzo #gcom #bhjs #beagajs http://t.co/7igVbtmS 2 weeks ago
  • @flavio1110 energético? 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