2015-06-16 4 views
4

Я использую этот код для загрузки файла с страницы JSF. Когда называют это Java:org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe

<?xml version='1.0' encoding='UTF-8' ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" 
     xmlns:h="http://java.sun.com/jsf/html" 
     xmlns:f="http://java.sun.com/jsf/core" 
     xmlns:ui="http://java.sun.com/jsf/facelets"> 

    <h:head></h:head> 

    <h:body> 
     <ui:composition> 
      <title>example</title> 
      <meta charset="utf-8"></meta> 
     </ui:composition> 
    </h:body> 
</html> 

Bean:

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.Serializable; 
import java.util.ArrayList; 
import java.util.Date; 
import java.util.List; 
import javax.annotation.PostConstruct; 
import javax.faces.context.FacesContext; 
import javax.faces.view.ViewScoped; 
import javax.inject.Named; 
import javax.servlet.http.HttpServletResponse; 

@Named 
@ViewScoped 
public class Download implements Serializable { 

    private String path = "/opt"; 
    private List<directoryListObj> dataList; 
    private List<String> items = new ArrayList<>(); 
    private String zone; 

    @PostConstruct 
    public void init() { 
     items.add("Select download mirror"); 
     items.add("USA"); 
    } 

    public String downloadFile(String fileName) { 
     try { 
      FacesContext facesContext = FacesContext.getCurrentInstance(); 
      HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse(); 

      String reportPath = path + File.separator + fileName; 
      File file = new File(reportPath); 

      if (!file.exists()) { 
       response.sendError(HttpServletResponse.SC_NOT_FOUND, "No file " + reportPath); 
      } 

      int DEFAULT_BUFFER_SIZE = 10240; 
      response.setBufferSize(DEFAULT_BUFFER_SIZE); 
      response.setHeader("Content-Length", String.valueOf(file.length())); // Display file size during download 
      response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); 

      BufferedInputStream bIn = new BufferedInputStream(new FileInputStream(file)); 

      int rLength = -1; 

      byte[] buffer = new byte[1000]; 

      while ((rLength = bIn.read(buffer, 0, 100)) != -1) { 
       response.getOutputStream().write(buffer, 0, rLength); 
      } 

      FacesContext.getCurrentInstance().responseComplete(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    public class directoryListObj { 

     private String filename; 
     private long size; 
     private String lastModified; 

     public directoryListObj(String filename, long size, long lastModified) { 
      this.filename = filename; 
      this.size = size/1024; 
      this.lastModified = new Date(lastModified).toString(); 
     } 

     public String getFilename() { 
      return filename; 
     } 

     public void setFilename(String filename) { 
      this.filename = filename; 
     } 

     public long getSize() { 
      return size; 
     } 

     public void setSize(long size) { 
      this.size = size; 
     } 

     public String getLastModified() { 
      return lastModified; 
     } 

     public void setLastModified(String lastModified) { 
      this.lastModified = lastModified; 
     } 
    } 

    public List<directoryListObj> getDataList() { 
     dataList = new ArrayList(); 
     String files; 
     File folder = new File(path); 
     File[] listOfFiles = folder.listFiles(); 

     if (listOfFiles != null) { 
      for (int i = 0; i < listOfFiles.length; i++) { 
       if (listOfFiles[i].isFile()) { 
        files = listOfFiles[i].getName(); 
        // Get the size 
        // Put discovered log files into the Array List 
        dataList.add(new directoryListObj(files, listOfFiles[i].length(), listOfFiles[i].lastModified())); 
       } 
      } 
     } 

     return dataList; 
    } 

    public String getZone() { 
     return zone; 
    } 

    public void setZone(String zone) { 
     this.zone = zone; 
    } 

    public List<String> getItems() { 
     return items; 
    } 

    public void setItems(List<String> items) { 
     this.items = items; 
    } 
} 

web.xml

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
     http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
     version="3.1"> 

    <display-name>JavaServerFaces</display-name> 

    <!-- Change to "Production" when you are ready to deploy --> 
    <context-param> 
     <param-name>javax.faces.PROJECT_STAGE</param-name> 
     <param-value>Development</param-value> 
    </context-param> 

    <resource-env-ref> 
     <!-- Enable Weld CDI, also needs META-INF/context.xml entry --> 
     <resource-env-ref-name>BeanManager</resource-env-ref-name> 
     <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type> 
    </resource-env-ref> 

    <!-- Skip comments in HTML code --> 
    <context-param> 
     <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name> 
     <param-value>true</param-value> 
    </context-param> 

    <!-- Welcome page --> 
    <welcome-file-list> 
     <welcome-file>faces/index.xhtml</welcome-file> 
    </welcome-file-list> 

    <!-- JSF mapping --> 
    <servlet> 
     <servlet-name>Faces Servlet</servlet-name> 
     <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <!-- Map these files with JSF --> 
    <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>*.jsf</url-pattern> 
    </servlet-mapping> 
    <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>*.xhtml</url-pattern> 
    </servlet-mapping> 
</web-app> 

beans.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
     http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" 
     bean-discovery-mode="annotated"> 
</beans> 

content.xml

<?xml version="1.0" encoding="UTF-8"?> 
<Context antiJARLocking="true" path="/tomcat-test"> 
    <Resource name="BeanManager" 
       auth="Container" 
       type="javax.enterprise.inject.spi.BeanManager" 
       factory="org.jboss.weld.resources.ManagerObjectFactory"/> 
</Context> 

лица-config.xml

<?xml version="1.0"?> 
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
       http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" 
       version="2.2"> 
</faces-config> 

Я получаю трассировку стека напечатанный в лог-файл Tomcat:

org.apache.catalina.connector.ClientAbortException: java.io.IOException: Broken pipe 
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:393) 
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:426) 
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:339) 
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:418) 
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:406) 
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:97) 
    at com.web.common.Download.downloadFile(Download.java:70) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.apache.el.parser.AstValue.invoke(AstValue.java:247) 
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:267) 
    at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) 
    at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:87) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
    at javax.faces.component.UIData.broadcast(UIData.java:1108) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:646) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:617) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521) 
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.io.IOException: Broken pipe 
    at sun.nio.ch.FileDispatcherImpl.write0(Native Method) 
    at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:47) 
    at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) 
    at sun.nio.ch.IOUtil.write(IOUtil.java:65) 
    at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471) 
    at org.apache.tomcat.util.net.NioChannel.write(NioChannel.java:127) 
    at org.apache.tomcat.util.net.NioBlockingSelector.write(NioBlockingSelector.java:101) 
    at org.apache.tomcat.util.net.NioSelectorPool.write(NioSelectorPool.java:173) 
    at org.apache.coyote.http11.InternalNioOutputBuffer.writeToSocket(InternalNioOutputBuffer.java:139) 
    at org.apache.coyote.http11.InternalNioOutputBuffer.addToBB(InternalNioOutputBuffer.java:197) 
    at org.apache.coyote.http11.InternalNioOutputBuffer.access$000(InternalNioOutputBuffer.java:41) 
    at org.apache.coyote.http11.InternalNioOutputBuffer$SocketOutputBuffer.doWrite(InternalNioOutputBuffer.java:320) 
    at org.apache.coyote.http11.filters.IdentityOutputFilter.doWrite(IdentityOutputFilter.java:84) 
    at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:256) 
    at org.apache.coyote.Response.doWrite(Response.java:503) 
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:388) 
    ... 46 more 

выглядит как ошибка в моем коде, но я не могу ее найти.

У вас есть идеи, где ошибка?

Я использую Tomcat 8.0.23 с Mojarra 2.2.6. В firebug я не вижу ошибок.

+0

Моя ошибка. Здесь полный вывод http://pastebin.com/P86Xqder –

+0

Пожалуйста, проверьте этот файл https://www.dropbox.com/s/yru3k3ycrz1541j/Download_test.zip?dl=0 Не забудьте поставить некоторые файлы под/opt каталог или изменить расположение каталога. –

ответ

-3

Вы должны получить OutputStream от ответа и связать его только один раз, не более и более внутри цикла while.

Попробуйте сделать что-то вроде этого

OutputStream outStream = response.getOutputStream(); 

    byte[] buffer = new byte[1000]; 
    int bytesRead = -1; 

    while ((bytesRead = bIn.read(buffer)) != -1) { 
     outStream.write(buffer, 0, bytesRead); 
    } 

    facesContext.getResponseComplete(); 

    bIn.close(); 
    outStream.close(); 
+0

Я проверил ваше предложенное исправление, но все же вижу ту же ошибку. –

+0

Глупый вопрос, вы перестроили свое приложение? :) try mayby ​​также, если изменение BufferedInputStream на FileInputStream поможет вам – Czarny

+0

Да, я его перестрою. –

Смежные вопросы