//jsp页面贴错了 正确的如下:<%@ page contentType="text/html; charset=GBK" %>
<%@ page import ="Com.Fh.Xtpt.Test.DownLoad"%>
<%@ page import = "Com.Fh.Xtpt.Servers.PubServers"%>
<%@ page import = "javax.servlet.RequestDispatcher"%>
<%@ page import = "java.io.*"%><html>
  <head><title>下载页面</title></head>
  <body bgcolor="#ffffff">  <%try{
      String fileURL = "C:/jboss-3.2.5/bin/www.xml";
      String fileName = "www.xml";
      DownLoad downLoad = new DownLoad();
      downLoad.downLoad(response,fileURL,fileName);
  }catch(Exception e){
     System.out.println("****** 下载出错了!******");
  }
  %>
  </body>
</html>打印信息如下:说明DownLoad没有发生异常
0:49:23,421 INFO  [STDOUT] ****** good1 ******  20:49:23,421 INFO  [STDOUT] ****** good2 ******20:49:23,421 INFO  [STDOUT] ****** good3 ******20:49:23,437 INFO  [STDOUT] ****** good4 ******报错信息如下:
20:49:23,453 ERROR [Engine] StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exceptionjava.lang.IllegalStateException: getOutputStream() has already been called for this response at org.apache.coyote.tomcat5.CoyoteResponse.getWriter(CoyoteResponse.java:599) at org.apache.coyote.tomcat5.CoyoteResponseFacade.getWriter(CoyoteResponseFacade.java:163) at org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:122) at org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:115) at org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:190) at org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:115) at org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:75) at org.apache.jsp.downLoad_jsp._jspService(downLoad_jsp.java:128) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:94) at javax.servlet.http.HttpServlet.service(HttpServlet.java:810) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:324) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:292) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:236) at javax.servlet.http.HttpServlet.service(HttpServlet.java:810) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157) at Com.Fh.Xtpt.Pub.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:30) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:186) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:157) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:214) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.StandardContextValve.invokeInternal(StandardContextValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:152) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:72) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102) at org.jboss.web.tomcat.security.JBossSecurityMgrRealm.invoke(JBossSecurityMgrRealm.java:275) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:102) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.core.StandardValveContext.invokeNext(StandardValveContext.java:104) at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:520) at org.apache.catalina.core.ContainerBase.invoke(ContainerBase.java:929) at org.apache.coyote.tomcat5.CoyoteAdapter.service(CoyoteAdapter.java:160) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:799) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.processConnection(Http11Protocol.java:705) at org.apache.tomcat.util.net.TcpWorkerThread.runIt(PoolTcpEndpoint.java:577) at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:683) at java.lang.Thread.run(Thread.java:536)

解决方案 »

  1.   

    在一个页面(page scope)中,只能使用一次response.getWriter或是getOutputStream,并且getWriter或是getOutputStream必须是在setContentType后面调用,你在jsp页面中采用jsp命令<%@ page%>设定了一次页面的contentType,然后又在页面的buffer中写入了"<head>..."这样的字符串,然后调用类Download,在这个类中你又设定了页面的ContentType,于是报错了,并且是 getOutputStream() has already been called,因为在这个方法前面在jsp中已经得到了jsp的out对象,你可以看看jsp编译成的servlet代码就完全明白了
      

  2.   

    头部已经输出了,然后你又重新设置Header,在某些WEB容器里就会出错,这是不规范的
    建议修改你的DownLoad 相应部分为:
    ====================================================
        if (headName.endsWith(".txt")) {
          response.setContentType("text/plain");
          response.addHeader("Content-disposition","attachment; filename=" + headName);
        }
        else {
          response.setContentType("application/x-msdownload");
          response.addHeader("Content-disposition","attachment; filename=" + headName);
        }
    ====================================================这里我觉得你的那个判断没有任何意义,txt会提示下载,如果是其他后缀,还是提示下载。
    注意headName中如果有中文,最好用UTF-8编码headName,因为IE默认是以UTF-8发送的!!其实你的程序关键错误是你自己写错了函数:String fileURL = "C:/jboss-3.2.5/bin/www.xml";
    String fileName = "www.xml";
    DownLoad downLoad = new DownLoad();
    downLoad.downLoad(response,fileURL,fileName); // 你写的参数和函数定义中的不一致,虽然编译是可以通过的应该是:downLoad.downLoad(response,fileName,fileURL);///////////////////////////////////////////////////////////////////////////测试是通过了的//DownLoad.java/*
     * Created on 2004-11-24
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package download;import java.io.File;
    import java.io.FileInputStream;
    import java.io.OutputStream;import javax.servlet.http.HttpServletResponse;/**
     * @author NetSniffer
     *
     * TODO To change the template for this generated type comment go to
     * Window - Preferences - Java - Code Style - Code Templates
     */public class DownLoad { public void down(HttpServletResponse response, String headName,
    String fileUrl) throws Exception { if (headName.endsWith(".txt")) {
    response.setContentType("text/plain");
    response.addHeader("Content-disposition", "attachment; filename="
    + headName);
    } else {
    response.setContentType("application/x-msdownload");
    response.addHeader("Content-disposition", "attachment; filename="
    + headName);
    } String fileURL = fileUrl;
    if (fileURL == null) {
    return;
    } try {
    File file = new File(fileUrl);
    FileInputStream bis = new FileInputStream(file);
    OutputStream bos = response.getOutputStream(); byte[] buff = new byte[1024];
    int readCount = 0;
    int i = 0;
    readCount = bis.read(buff);
    while (readCount != -1) {
    bos.write(buff, 0, readCount);
    readCount = bis.read(buff);
    } bis.close();
    bos.close(); } catch (Exception e) {
    System.out.println("****** bad ******");
    }
    }}//////////////////////////////////////////////////////////
      

  3.   

    JSP中的JSPWriter对象在JSP被访问的时候,一旦你在第一个<%%>之前有HTML,out就把HTTP头信息提交了,然后接着向客户端输出HTML内容,所以你这样做无论如何不会正确的,你的jsp中不能有任何非Java代码,也就是从<%写到%>,所以不如干脆写成Servlet,或者使用页面重定向直接定位到资源,HTTP下载何必自己写服务,HTTP服务器已经提供了,发不出来即可。
      

  4.   

    请问 wpx80(wpx80) :
    怎样用页面重定向定位到资源
    我的文件在:c:/jboss/bin/www.xml;
    写出代码好吗? 谢谢!