Download de arquivo com JSF não está funcionando

9 respostas
V

E ai pessoal,

Estou com um sério problema com o download de arquivos com o JSF. Sei que existem vários tópicos que mencionam o mesmo assunto porém não vi ngm com esse erro estranho que acontece cmg.

Resumo:

Tenho um datatable e com os dados do mesmo preciso fazer um download de um arquivo ".xls". Possuo um método que gera o arquivo normalmente e coloca numa pasta dentro do meu contexto web. Até ai tudo perfeito. Só que quando chamo o método pra fazer o download, ao invés de aparecer um dialog box pra salvar o arquivo está aparecendo umá página cheia de caracteres estranhos.

Será que algum de vcs tem alguma ideia pra solucionar esse mistério ?

Segue o meu método responsável pela lógica de download:
/**
    * Download a XLS file representing the deliveries filtered.
    * 
    * @throws Exception
    */

   public void downloadXLS() throws Exception {
      FacesContext context = FacesContext.getCurrentInstance();
      ExternalContext ec = context.getExternalContext();
      HttpServletResponse response = (HttpServletResponse) ec.getResponse();

      File file = new File(regDoc.getAbsolutePath());
      if (!file.exists()) {
         log.warn("[ListDocumentGenerator - " + getCurrentLoggedUser().getUserid() + "] File '" + regDoc.getName() + "' doesn't exists.");
         return;
      }
      if (!file.canRead()) {
         log.warn("[ListDocumentGenerator - " + getCurrentLoggedUser().getUserid() + "] File '" + regDoc.getName() + "' can't be read.");
         return;
      }
      // Verify if the size is within the limit of the response
      long size = file.length();
      int sizeInt = (int) size;
      if (size != (long) sizeInt) {
         log.warn("[ListDocumentGenerator - " + getCurrentLoggedUser().getUserid() + "] Size of the file '" + regDoc.getName() + "' (" + size + " bytes) doesn't fit the response's maximum size.");
         return;
      }

      // Define the response length and type
      response.setContentLength(sizeInt);
      // see: http://www.w3schools.com/media/media_mimeref.asp
      response.setContentType("application/vnd.ms-excel");
      response.setHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\"");  

      BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
      BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());

      // Write the file's content to the response
      byte[] b = new byte[sizeInt];
      while (in.available() > 0) {
         int qtty = in.read(b);
         out.write(b, 0, qtty);
      }

      log.info("[ListDocumentGenerator - " + getCurrentLoggedUser().getUserid() + "] File '" + regDoc.getName() + "' (" + sizeInt + " bytes) was downloaded sucessfully.");

      // Flush and close
      in.close();
      out.flush();
      out.close();

      FacesContext.getCurrentInstance().responseComplete();
   }

Any ideas ???? :roll:

9 Respostas

E

Boa noite,

Tenta mudar o ContentType para outro tipo de arquivo… para verificar se ele vai fazer a mesma coisa

Att,

V

ekszuki:
Boa noite,

Tenta mudar o ContentType para outro tipo de arquivo… para verificar se ele vai fazer a mesma coisa

Att,

Já tentei de tudo… mudei o content type pra application/xls, application/excel… e por ai vai… continua com a mesma coisa =(

F

Normalmente esta parada é content-type.

Qnd vc alterou o conten-type e não funcionou,
você apagou o cache do browser, reiniciou o container, …? Fez este tipo de coisa pra garantir q a sua alteração valeu?

V

fvslistas:
Normalmente esta parada é content-type.

Qnd vc alterou o conten-type e não funcionou,
você apagou o cache do browser, reiniciou o container, …? Fez este tipo de coisa pra garantir q a sua alteração valeu?

Eu criei outro war, reiniciei o server, limpei o cache e os cookies e nada… =(

Eu utilizo o JSF sem cookies… com o jsessionid na URL… n sei se isso tem a ver…

F

http://wiki.metawerx.net/wiki/Web.xml.MimeMapping
Tente isto

<mime-mapping> 
    <extension>xls</extension> 
    <mime-type>application/vnd.ms-excel</mime-type> 
</mime-mapping>

no web.xml

V
fvslistas:
[url]http://wiki.metawerx.net/wiki/Web.xml.MimeMapping[/url] Tente isto
<mime-mapping> 
    <extension>xls</extension> 
    <mime-type>application/vnd.ms-excel</mime-type> 
</mime-mapping>
no web.xml
Boa dica cara.. mas mesmo adicionando isso ainda tá dando o problema.. Segue abaixo meu web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="myApp" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

	<description>My App</description>
	<display-name>myApp</display-name>
	<context-param>
		<description>
			Monitors Faces JSP files for modifications and synchronizes a running server with the changes without restarting the server. If this parameter is set to false or removed from the
			deployment descriptor, any changes made to Faces JSP files may not be seen by the server until it is restarted. This parameter is usually set to true while the Faces JSP files are being
			developed and debugged in order to improve the performance of the development environment.
		</description>
		<param-name>com.ibm.ws.jsf.JSP_UPDATE_CHECK</param-name>
		<param-value>true</param-value>
	</context-param>
	<context-param>
		<description />
		<param-name>com.ibm.ws.jsf.LOAD_FACES_CONFIG_AT_STARTUP</param-name>
		<param-value>true</param-value>
	</context-param>
	<context-param>
		<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
		<param-value>server</param-value>
	</context-param>
	<context-param>
		<param-name>org.richfaces.SKIN</param-name>
		<param-value>#{skinMBean.skin}</param-value>
	</context-param>


	<context-param>
		<param-name>org.richfaces.CONTROL_SKINNING</param-name>
		<param-value>enable</param-value>
	</context-param>

	<context-param>
		<param-name>org.richfaces.CONTROL_SKINNING_LEVEL</param-name>
		<param-value>basic</param-value>
	</context-param>

	<context-param>
		<description>
		   This configuration tells the ContextLoaderListener where to find the Spring context, thus enabling the startup of
		   the Spring context at webserver startup.
		</description>
		<param-name>contextConfigLocation</param-name>
		<param-value>
         	classpath*:applicationContext.xml
            classpath*:applicationContext-dataSource.xml
            classpath*:applicationContext-security-web.xml
            classpath*:applicationContext-aspects.xml
            classpath*:applicationContext-validation.xml
        </param-value>
	</context-param>

	<filter>
		<filter-name>CustomCharacterEncodingFilter</filter-name>
		<filter-class>de.kybeidos.mmw.jsf.CharsetEncodeFilter</filter-class>
	</filter>

	<filter>
		<filter-name>UrlSessionFilter</filter-name>
		<filter-class>de.kybeidos.mmw.jsf.UrlSessionFilter</filter-class>
	</filter>

	<filter>
		<filter-name>OSIVFilter</filter-name>
		<filter-class>
			org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
		<init-param>
			<param-name>singleSession</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>sessionFactoryBeanName</param-name>
			<param-value>sessionFactory</param-value>
		</init-param>
	</filter>

	<filter>
		<filter-name>Acegi Filter Chain Proxy</filter-name>
		<filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class>
		<init-param>
			<param-name>targetClass</param-name>
			<param-value>org.acegisecurity.util.FilterChainProxy</param-value>
		</init-param>
	</filter>


	<filter-mapping>
		<filter-name>CustomCharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>UrlSessionFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>OSIVFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<filter-mapping>
		<filter-name>Acegi Filter Chain Proxy</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<listener>
		<listener-class>com.sun.faces.config.ConfigureListener</listener-class>
	</listener>

	<!-- commented because ibm libraries was removed -->
	<!--	<servlet id="Servlet_1108413200548">-->
	<!--		<servlet-name>JS Resource Servlet</servlet-name>-->
	<!--
		<servlet-class>com.ibm.faces.webapp.JSResourceServlet</servlet-class>
	-->
	<!--		<load-on-startup>1</load-on-startup>-->
	<!--	</servlet>-->

	<servlet id="Servlet_1108413201740">
		<servlet-name>Faces Servlet</servlet-name>
		<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet>
		<servlet-name>DownloadServlet</servlet-name>
		<servlet-class>de.kybeidos.mmw.util.servlet.DownloadServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>/faces/*</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>Faces Servlet</servlet-name>
		<url-pattern>*.faces</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>DownloadServlet</servlet-name>
		<url-pattern>/servlet/download</url-pattern>
	</servlet-mapping>

	<filter>
		<display-name>Ajax4jsf Filter</display-name>
		<filter-name>ajax4jsf</filter-name>
		<filter-class>org.ajax4jsf.Filter</filter-class>
		<init-param>
			<param-name>createTempFiles</param-name>
			<param-value>false</param-value>
		</init-param>
		<init-param>
			<param-name>maxRequestSize</param-name>
			<param-value>512000</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>ajax4jsf</filter-name>
		<servlet-name>Faces Servlet</servlet-name>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
	</filter-mapping>

	<mime-mapping>
		<extension>xls</extension>
		<mime-type>application/vnd.ms-excel</mime-type>
	</mime-mapping>

	<mime-mapping>
		<extension>pdf</extension>
		<mime-type>application/pdf</mime-type>
	</mime-mapping>

	<session-config>
		<session-timeout>90</session-timeout>
	</session-config>
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>
	<error-page>
		<error-code>500</error-code>
		<location>/faces/open/error.jsp</location>
	</error-page>
	<error-page>
		<error-code>404</error-code>
		<location>/faces/open/error.jsp</location>
	</error-page>
	<error-page>
		<exception-type>javax.faces.application.ViewExpiredException</exception-type>
		<location>/faces/open/newAuthentication.jsp</location>
	</error-page>
</web-app>
V

Alguém pode me ajudar ?? Ainda nao consegui resolver esse problema… :?

V

Cara consegui resolver o problema… o botão que chamava um actionListener era a4j:commandButton. Mudei para h:commandButton e aí funcionou. Só descobri isso pq tinha uma parte da minha aplicação que fazia uma lógica parecida, senao ia fica mudando codigo e nao ia descobrir nunca…

Valeu pela ajuda

F

Eu só conseguia pensar em mime e coisas do tipo. Nunca ia pensar na mudança do botão. :slight_smile:
Que bom que conseguiu, parabéns e obrigado por postar a solução.

Criado 26 de março de 2010
Ultima resposta 16 de abr. de 2010
Respostas 9
Participantes 3