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.

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

  • Nos encontraremos lá :) RT @rodrigodealer No avião. Embarcando para o #qconsp. 7 hours ago
  • RT @steppat: great #ANTLR introduction: http://vimeo.com/groups/29150/videos (via @fmeyer) 1 day ago
  • @rafaeligor ok, now look this: http://meme.yahoo.com/marcossousa/p/mC4SHdY/ 1 day ago
  • I got it! RT @emerleite Gmail Priority Inbox is useless if you use to do Inbox Zero aproach. #gmail #inboxzero #priorityinbox 2 days ago
  • Inception is great, engineers must love it! A movie full of concepts, math and engineering. It's worth it! 4 days ago
  • Interessante o post do @pcalcado sobre liderança http://j.mp/bzSytt 4 days ago
  • Playing Cilada puzzle with my nephew and laughing a lot. #funny #childparty 4 days ago
  • Eu não :) RT @cmilfont: Maré de Agilidade do ano passado foi excelente, vai perder desse ano? http://j.mp/cyKeOg 4 days ago
  • Interesting post about generic relationships using Django http://bit.ly/dtMYfK #django 6 days ago
  • Pelo menos seriam mais objetivos :) RT @rodrigoy: @plentz Se desse eu leria emails como twitter... 6 days 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