【转】jfinal-4.9 自定义render,返回音频文件

https://jfinal.com/share/2255

[产生背景]

刚一开使用renderFile(file);前端使用audio标签播放,播放时后台总是出现异常

前台audio标签

  1. <audio id="audioPlay" src="/litongjava-windows-tts/tts?text=很多文本"></audio>

后台异常

  1. 九月 06, 2020 10:16:50 上午 com.jfinal.core.ActionHandler error
  2. 严重: /tts?text=省略内容
  3. com.jfinal.render.RenderException: java.io.IOException: 远程主机强迫关闭了一个现有的连接。
  4. at com.jfinal.render.FileRender.rangeRender(FileRender.java:244)
  5. at com.jfinal.render.FileRender.render(FileRender.java:123)
  6. at com.jfinal.core.ActionHandler.handle(ActionHandler.java:111)
  7. at com.litong.jfinal.handler.ActionSuffixHandler.handle(ActionSuffixHandler.java:28)
  8. at com.jfinal.core.JFinalFilter.doFilter(JFinalFilter.java:90)
  9. at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:61)
  10. at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
  11. at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
  12. at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
  13. at io.undertow.servlet.handlers.ServletChain$1.handleRequest(ServletChain.java:68)
  14. at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
  15. at io.undertow.servlet.handlers.RedirectDirHandler.handleRequest(RedirectDirHandler.java:68)
  16. at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:132)
  17. at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
  18. at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  19. at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
  20. at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
  21. at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
  22. at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
  23. at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
  24. at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  25. at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
  26. at io.undertow.servlet.handlers.SessionRestoringHandler.handleRequest(SessionRestoringHandler.java:119)
  27. at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:269)
  28. at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:78)
  29. at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:133)
  30. at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:130)
  31. at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
  32. at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
  33. at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:249)
  34. at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:78)
  35. at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:99)
  36. at io.undertow.server.Connectors.executeRootHandler(Connectors.java:376)
  37. at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:830)
  38. at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
  39. at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
  40. at java.lang.Thread.run(Thread.java:748)

请求返回的状态码,并且点击一次播放按钮,播放了3次

image.png

异常的具体原因我没有找到,但是我认为和renderFile默认弹出下载框有关系

[解决思路]

自定义的一个render,读取文件流,输出到response

controller调用

  1. render(new InputStreamRender(file));

render代码

  1. package com.litong.jfinal.render;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import com.jfinal.render.Render;
  5. import com.litong.utils.io.StreamUtils;
  6. /**
  7.  * @author bill robot
  8.  * @date 2020年9月6日_上午9:56:51 
  9.  * @version 1.0 
  10.  * @desc
  11.  */
  12. public class InputStreamRender extends Render {
  13.   private File srcfile;
  14.   public InputStreamRender(File srcfile) {
  15.     this.srcfile = srcfile;
  16.   }
  17.   @Override
  18.   public void render() {
  19.     if (srcfile != null) {
  20.       try {
  21.         StreamUtils.copy(srcfile, response.getOutputStream());
  22.       } catch (IOException e) {
  23.         e.printStackTrace();
  24.       }
  25.     }
  26.   }
  27. }

工具类

  1. package com.litong.utils.io;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. import java.io.OutputStream;
  7. /**
  8.  * @author bill robot
  9.  * @date 2020年8月22日_上午1:08:25 
  10.  * @version 1.0 
  11.  * @desc
  12.  */
  13. public class StreamUtils {
  14.   public static final int BUFFER_SIZE = 4096;
  15.   public static int copy(InputStream in, OutputStream out) throws IOException{
  16.     int byteCount = 0;
  17.     byte[] buffer = new byte[BUFFER_SIZE];
  18.     int bytesRead = -1;
  19.     while ((bytesRead = in.read(buffer)) != -1) {
  20.       out.write(buffer, 0, bytesRead);
  21.       byteCount += bytesRead;
  22.     }
  23.     return byteCount;
  24.   }
  25.   public static void copy(File file, OutputStream outputStream) {
  26.     FileInputStream fileInputStream=null;
  27.     try {
  28.       fileInputStream = new FileInputStream(file);
  29.       copy(fileInputStream, outputStream);
  30.     } catch (IOException e) {
  31.       e.printStackTrace();
  32.     }finally {
  33.       IOUtils.closeQuietly(fileInputStream);
  34.     }
  35.   }
  36. }

再次测试,可以返回200

image.png

原文地址:https://www.cnblogs.com/tc310/p/13628338.html