[产生背景]
刚一开使用renderFile(file);前端使用audio标签播放,播放时后台总是出现异常
前台audio标签
- <audio id="audioPlay" src="/litongjava-windows-tts/tts?text=很多文本"></audio>
后台异常
- 九月 06, 2020 10:16:50 上午 com.jfinal.core.ActionHandler error
- 严重: /tts?text=省略内容
- com.jfinal.render.RenderException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
- at com.jfinal.render.FileRender.rangeRender(FileRender.java:244)
- at com.jfinal.render.FileRender.render(FileRender.java:123)
- at com.jfinal.core.ActionHandler.handle(ActionHandler.java:111)
- at com.litong.jfinal.handler.ActionSuffixHandler.handle(ActionSuffixHandler.java:28)
- at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:90)
- at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
- at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
- at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
- at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
- at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
- at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
- at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
- at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
- at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
- at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
- at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
- at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
- at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
- at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
- at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
- at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
- at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
- at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
- at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
- at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
- at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
- at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
- at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
- at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
- at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
- at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
- at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
- at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
- at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
- at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
- at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
- at java.lang.Thread.run(Thread.java:748)
请求返回的状态码,并且点击一次播放按钮,播放了3次
异常的具体原因我没有找到,但是我认为和renderFile默认弹出下载框有关系
[解决思路]
自定义的一个render,读取文件流,输出到response
controller调用
- render(new InputStreamRender(file));
render代码
- package com.litong.jfinal.render;
- import java.io.File;
- import java.io.IOException;
- import com.jfinal.render.Render;
- import com.litong.utils.io.StreamUtils;
- /**
- * @author bill robot
- * @date 2020年9月6日_上午9:56:51
- * @version 1.0
- * @desc
- */
- public class InputStreamRender extends Render {
- private File srcfile;
- public InputStreamRender(File srcfile) {
- this.srcfile = srcfile;
- }
- @Override
- public void render() {
- if (srcfile != null) {
- try {
- StreamUtils.copy(srcfile, response.getOutputStream());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- }
工具类
- package com.litong.utils.io;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.OutputStream;
- /**
- * @author bill robot
- * @date 2020年8月22日_上午1:08:25
- * @version 1.0
- * @desc
- */
- public class StreamUtils {
- public static final int BUFFER_SIZE = 4096;
- public static int copy(InputStream in, OutputStream out) throws IOException{
- int byteCount = 0;
- byte[] buffer = new byte[BUFFER_SIZE];
- int bytesRead = -1;
- while ((bytesRead = in.read(buffer)) != -1) {
- out.write(buffer, 0, bytesRead);
- byteCount += bytesRead;
- }
- return byteCount;
- }
- public static void copy(File file, OutputStream outputStream) {
- FileInputStream fileInputStream=null;
- try {
- fileInputStream = new FileInputStream(file);
- copy(fileInputStream, outputStream);
- } catch (IOException e) {
- e.printStackTrace();
- }finally {
- IOUtils.closeQuietly(fileInputStream);
- }
- }
- }
再次测试,可以返回200