client.completePendingCommand();
你这句没加
######回复
@edwardlu_ : 找到原因了centos版本与vsfftp版本问题 最中文支持不好 ,升级后解决######回复
@红番茄 : 什么意思?这是查看它的返回代码,不是下多个文件啊。你查看ftpClient为什么没有获取到文件######回复
@红番茄 : 使用 getReplyCode(), getReplyString(), getReplyStrings() ,获取一下返回的信息######回复
@edwardlu_ : 不行 我不是一次下载多个文件 跟这个没关系 我是每次下载1个######回复
@红番茄 : http://ly-mad.iteye.com/blog/1180777######
你最好是贴一下你的代码。不过这种经典问题很多人遇到的,有两个地址,你可以看一下:http://my.oschina.net/zhongwenhao/blog/209653
http://stackoverflow.com/questions/21039471/spring-getoutputstream-has-already-been-called-for-this-response
######下面######/**
* 下载行程word
*
@param request
*
@param response
*
@param fileName
*/
public void downloadTripWord(HttpServletRequest request, HttpServletResponse response, String fileName) {
String path = "/word/";
String saveName = "";
InputStream fis = null;
BufferedInputStream buff = null;
OutputStream os = null;
try {
login();
ftpClient.changeWorkingDirectory(path);
ftpClient.setControlEncoding("gbk");
FTPFile[] fs = ftpClient.listFiles();
for(FTPFile ff:fs){
if(ff.getName().equals(fileName)){
//读出文件到i/o流
response.setContentType("application/x-msdownload");
if(request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
saveName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");//firefox浏览器
}
else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
saveName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
}
else if (request.getHeader("User-Agent").indexOf("Trident") > 0) {
saveName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
}
response.addHeader("Content-Disposition", "attachment; filename=\"" + saveName + "\"");
fis = ftpClient.retrieveFileStream(ff.getName());
buff = new BufferedInputStream(fis);
byte [] b=new byte[1024];
long k=0;
os = response.getOutputStream();
while(k<ff.getSize()){
int j=buff.read(b,0,1024);
k+=j;
os.write(b,0,j);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
os.flush();
os.close();
buff.close();
fis.close();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
######
引用来自“红番茄”的评论
/**
* 下载行程word
*
@param request
*
@param response
*
@param fileName
*/
public void downloadTripWord(HttpServletRequest request, HttpServletResponse response, String fileName) {
String path = "/word/";
String saveName = "";
InputStream fis = null;
BufferedInputStream buff = null;
OutputStream os = null;
try {
login();
ftpClient.changeWorkingDirectory(path);
ftpClient.setControlEncoding("gbk");
FTPFile[] fs = ftpClient.listFiles();
for(FTPFile ff:fs){
if(ff.getName().equals(fileName)){
//读出文件到i/o流
response.setContentType("application/x-msdownload");
if(request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
saveName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");//firefox浏览器
}
else if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
saveName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
}
else if (request.getHeader("User-Agent").indexOf("Trident") > 0) {
saveName = URLEncoder.encode(fileName, "UTF-8");//IE浏览器
}
response.addHeader("Content-Disposition", "attachment; filename=\"" + saveName + "\"");
fis = ftpClient.retrieveFileStream(ff.getName());
buff = new BufferedInputStream(fis);
byte [] b=new byte[1024];
long k=0;
os = response.getOutputStream();
while(k<ff.getSize()){
int j=buff.read(b,0,1024);
k+=j;
os.write(b,0,j);
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
os.flush();
os.close();
buff.close();
fis.close();
ftpClient.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
fis = ftpClient.retrieveFileStream(ff.getName()); 你确定两次传的文件 ,文件名不相同么,然后调试下是在哪个流关闭的时候报的时候报的异常######回复
@红番茄 : 你的ftpClient不能是全局变量,只能局部变量######回复
@edwardlu_ : 登录方法里new 的 login()######回复
@红番茄 : ftpClient 这个对象你是在哪里定义的,是在哪里进行连接的######下同一个文件就不会错 ,下另一个文件就会出错了,在这出的错 fis = ftpClient.retrieveFileStream(ff.getName()); fis 会 =null######这里你已经在finally中 ftpClient.disconnect 了,你是不是没有重新连接######回复
@edwardlu_ : 是这出的异常 但很多人都说了是response造成的######回复
@红番茄 : 额,你不是在 fis =ftpClient.retrieveFileStream(ff.getName());出的异常么?怎么会是 response啊######不是这个的问题 我每次都重新new 了的 问题应该是response上######回复
@edwardlu_ :
public void login(){
ResourceBundle cfg = ResourceBundle.getBundle("cfg");
ftpClient = new FTPClient();
ftpClient.connect(cfg.getString("ftp.ip"), 52114);
ftpClient.login(cfg.getString("ftp.uname"), cfg.getString("ftp.upass"));
}
######
引用来自“edwardlu_”的评论
这里你已经在finally中 ftpClient.disconnect 了,你是不是没有重新连接
是因为你的问题中给出了“getOutputStream() has already been called for this response ”这个异常,如果是这个异常,那确实是response的错,不过他们的异常是:java.lang.IllegalStateException: Stream closed getOutputStream() has already been called for this response ;
而你的是IOException,是不同的,你后面的异常代码可能是由于前一个异常导致的。因此你得先调试,你的调试结果已经确定是在哪个位置出错了,你就只需在前面的代码里面找错了,这个时候的response还没用呢
######回复
@edwardlu_ : 给你私信######回复
@红番茄 : 这样,你把你的调试日志截张图发下######用了的 我第一次下载正常 第2个文件就错了######
引用来自“红番茄”的评论
回复
@edwardlu_ :
public void login(){
ResourceBundle cfg = ResourceBundle.getBundle("cfg");
ftpClient = new FTPClient();
ftpClient.connect(cfg.getString("ftp.ip"), 52114);
ftpClient.login(cfg.getString("ftp.uname"), cfg.getString("ftp.upass"));
}
你的登录代码没错,你的登录是每次都会调用,还是只调用了一次######每次下载都很重新登录 下载完后关闭断开######
######显示的日志记录,控制台的输出也贴一下######
fis = ftpClient.retrieveFileStream(ff.getName());
System.out.println(fis);
第一次打印结果org.apache.commons.net.io.SocketInputStream@f10f8ee
第二次打印结果null
java.io.IOException: Stream closed
at java.io.BufferedInputStream.getInIfOpen(BufferedInputStream.java:151)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
at com.trip.common.FTPUploadUtils.downloadTripWord(FTPUploadUtils.java:148)
at com.trip.circuit.action.CircuitInfoAction.downloadTrip(CircuitInfoAction.java:501)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:219)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:745)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:686)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:925)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:856)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:936)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:827)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:812)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.trip.common.AuthorityFilter.doFilter(AuthorityFilter.java:140)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.logging.log4j.core.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:66)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:744)