1.最近在做一个文档管理的功能,遇到的问题是上传的音频文件播放时遇到的,音频播放前端用的是audiojs,由于上传的文件没有放在项目目录下,请求是用struts action 返回的OutputStream.
2.出现的问题:前端请求了三次,后台报错,错误信息如下:
2016-09-02 12:04:57 INFO [http-bio-8080-exec-22] - saveName:af240eda1e9b78341b42b0ca555bfc04.mp3
2016-09-02 12:04:57 INFO [http-bio-8080-exec-39] - saveName:af240eda1e9b78341b42b0ca555bfc04.mp3
2016-09-02 12:04:57 INFO [http-bio-8080-exec-41] - saveName:af240eda1e9b78341b42b0ca555bfc04.mp3
org.apache.catalina.connector.ClientAbortException: java.net.SocketException: Broken pipe
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:407)
at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480)
at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:432)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:420)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91)
at app.component.doc.action.TbDocInfoAction.readDocs(TbDocInfoAction.java:484)
at app.component.doc.action.TbDocInfoAction.openImgOrTxt(TbDocInfoAction.java:145)
at app.component.doc.action.TbDocInfoAction$$FastClassByCGLIB$$ef9208ea.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:698)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:96)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:260)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:94)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:631)
前端调用代码如下:
$(".audio-read").click(function(){
var audioName = $(this).attr("name"); //音频文件的名字
var titleName = $(this).attr("title"); //音频本身名字
var audioHtml = '<audio preload="auto"><source src="XXXXXXXAction_xxxx.action?saveName='+audioName+'"></audio>';
$(".audio-modal-title").text(titleName);
$(".audio-modal-body").html(audioHtml);
audiojs.events.ready(function() {
var as = audiojs.createAll();
});
})
保存在服务器其他目录的文件能不通过输出流来实现吗?
请问各位这种情况该怎么来处理。感激不尽。
音乐文件可以当静态文件处理,和JS, CSS, IMG一样。
按流式处理也是没问题的,从错误日志来看是客户端断开了连接导致。你可以在浏览器里打开该链接看是否能够正常下载和打开该audio
首先你需要确认客户端能正确的访问到你的音频文件,即采用你的调用方法获取到文件数据(这需要你对服务器进行正确配置,此外还需要在服务器端代码中对调用接口正确实现)。这里的客户端并不一定是你的前端程序,最好是纯粹的浏览器调用,你甚至可以用诸如curl/wget之类的命令行进行测试。
在保证了1的前提下再进一步测试你自己的前端是否能正确发起调用,因为涉及到html的audio标签,这个由不同的浏览器各自实现,所以还可能存在浏览器兼容问题,所以也要测试一下。
此外一点可能的影响是因为你采用服务器调用返回音频数据文件流,所以在浏览器看来仅仅是一些数据块,而不能通过诸如文件扩展名之类获得一些关于音频格式的信息,这对正确解析文件可能是必要的,所以你可以尝试对source标签定义编码、文件格式方面的属性,方便浏览器识别。