package com.sm.common.servlet;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.util.UriUtils;
import com.sm.common.config.Global; /**
* 查看CK上传的图片
* @author ThinkGem
* @version 2014-06-25
*/
public class UserfilesDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L;
private Logger logger = LoggerFactory.getLogger(getClass()); public void fileOutputStream(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String filepath = request.getRequestURI();
int index = filepath.indexOf(Global.USERFILES_BASE_URL);
if (index >= ) {
filepath = filepath.substring(index + Global.USERFILES_BASE_URL.length());
}
try {
filepath = UriUtils.decode(filepath, "UTF-8");
} catch (UnsupportedEncodingException e1) {
logger.error(String.format("解释文件路径失败,URL地址为%s", filepath), e1);
}
File file = new File(Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + filepath);
logger.debug("===" + Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + filepath + "===");
RandomAccessFile randomFile = new RandomAccessFile(file, "r");// 只读模式
long contentLength = randomFile.length();
String range = request.getHeader("Range");
int start = , end = ;
if (range != null && range.startsWith("bytes=")) {
String[] values = range.split("=")[].split("-");
start = Integer.parseInt(values[]);
if (values.length > ) {
end = Integer.parseInt(values[]);
}
}
int requestSize = ;
if (end != && end > start) {
requestSize = end - start + ;
} else {
requestSize = Integer.MAX_VALUE;
} byte[] buffer = new byte[];
response.setContentType("video/mp4");
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("ETag", file.getName());
response.setHeader("Last-Modified", new Date().toString());
// 第一次请求只返回content length来让客户端请求多次实际数据
if (range == null) {
response.setHeader("Content-length", contentLength + "");
} else {
// 以后的多次以断点续传的方式来返回视频数据
response.setStatus(HttpServletResponse.SC_PARTIAL_CONTENT);//
long requestStart = , requestEnd = ;
String[] ranges = range.split("=");
if (ranges.length > ) {
String[] rangeDatas = ranges[].split("-");
requestStart = Integer.parseInt(rangeDatas[]);
if (rangeDatas.length > ) {
requestEnd = Integer.parseInt(rangeDatas[]);
}
}
long length = ;
if (requestEnd > ) {
length = requestEnd - requestStart + ;
response.setHeader("Content-length", "" + length);
response.setHeader("Content-Range", "bytes " + requestStart + "-" + requestEnd + "/" + contentLength);
} else {
length = contentLength - requestStart;
response.setHeader("Content-length", "" + length);
response.setHeader("Content-Range",
"bytes " + requestStart + "-" + (contentLength - ) + "/" + contentLength);
}
}
OutputStream out = response.getOutputStream();
try { int needSize = requestSize;
randomFile.seek(start);
while (needSize > ) {
int len = randomFile.read(buffer);
if (needSize < buffer.length) {
out.write(buffer, , needSize);
} else {
out.write(buffer, , len);
if (len < buffer.length) {
break;
}
}
needSize -= buffer.length;
}
} catch (FileNotFoundException e) {
request.setAttribute("exception", new FileNotFoundException("请求的文件不存在"));
request.getRequestDispatcher("/WEB-INF/views/error/404.jsp").forward(request, response);
} catch (Exception e1) {
request.setAttribute("exception", e1);
request.getRequestDispatcher("/WEB-INF/views/error/404.jsp").forward(request, response);
} finally {
randomFile.close();
out.close();
} } public void fileOutputStream2(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String filepath = req.getRequestURI();
int index = filepath.indexOf(Global.USERFILES_BASE_URL);
if (index >= ) {
filepath = filepath.substring(index + Global.USERFILES_BASE_URL.length());
}
try {
filepath = UriUtils.decode(filepath, "UTF-8");
} catch (UnsupportedEncodingException e1) {
logger.error(String.format("解释文件路径失败,URL地址为%s", filepath), e1);
}
File file = new File(Global.getUserfilesBaseDir() + Global.USERFILES_BASE_URL + filepath);
try {
if (filepath.endsWith(".mp4")) {
resp.setContentType("video/mpeg4; charset=utf-8");
resp.setHeader("Content-disposition", "attachment;filename=" + file.getName());
} else {
resp.setHeader("Content-Type", "application/octet-stream");
}
FileCopyUtils.copy(new FileInputStream(file), resp.getOutputStream()); return;
} catch (FileNotFoundException e) {
req.setAttribute("exception", new FileNotFoundException("请求的文件不存在"));
req.getRequestDispatcher("/WEB-INF/views/error/404.jsp").forward(req, resp);
} catch (Exception e1) {
req.setAttribute("exception", e1);
req.getRequestDispatcher("/WEB-INF/views/error/404.jsp").forward(req, resp);
}
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
fileOutputStream(req, resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
fileOutputStream(req, resp);
}
}

图片视频访问servlet(支持苹果视频断点续传)的更多相关文章

  1. C#开发微信门户及应用(19)-微信企业号的消息发送(文本、图片、文件、语音、视频、图文消息等)

    我们知道,企业号主要是面向企业需求而生的,因此内部消息的交流显得非常重要,而且发送.回复消息数量应该很可观,对于大企业尤其如此,因此可以结合企业号实现内部消息的交流.企业号具有关注安全.消息无限制等特 ...

  2. [Unity3D][Vuforia][IOS]vuforia在unity3d中添加自己的动态模型,识别自己的图片,添加GUI,播放视频

    使用环境 unity3D 5 pro vuforia 4 ios 8.1(6.1) xcode 6.1(6.2) 1.新建unity3d工程,添加vuforia 4.0的工程包 Hierarchy中 ...

  3. Android/iOS微信6.3.5同时发布更新 支持群视频聊天、群公告

    下午微信6.3.5发布更新,新版最大变化就是支持群视频聊天,又一次向手机QQ靠拢.在群管理方面,支持发布群公告,支持群主转让给其他群成员,同样都是QQ玩剩下的功能.另外,新版支持微信运动查看步数图表. ...

  4. wzplayer for android V1.6.1 (支持音视频加密播放)

    1.更新 2013-11-25: 1.6.1 修复1.6.0版本对rk版本的支持. 以往版本: 1.6.0 1)1.6.0修改了所有默认音频渲染使用AudioTrack输出,这样只要不播放视频,能支持 ...

  5. 【教你zencart仿站 文章1至6教训 高清1280x900视频下载】[支持手机端]

    [教你zencart仿站 第1至6课 高清晰1280x900视频下载][支持移动端] 经过筹备, 我们的课件最终出来了- 我们 zencart联盟合伙人 项目推出的 在线yy同步演示zencart仿站 ...

  6. VideoView 监听视频格式不支持时的错误。

    视频播放格式不支持的处理https://www.cnblogs.com/ygj0930/p/7737209.html 不处理的情况下,默认会有弹框提示:不支持该视频格式. mVideoView.set ...

  7. h5的video标签支持的视频格式

    关于<video>标签所支持的视频格式和编码: MP4 = MPEG 4文件使用 H264 视频编解码器和AAC音频编解码器 WebM = WebM 文件使用 VP8 视频编解码器和 Vo ...

  8. Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型

    转自原文 Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型 播放mp4格式的时候提示 Html 播放 mp4格式视频提示 没有发现支持的视频格式和mime类型 原因是在IIS中 ...

  9. 最稳定万能vip视频解析接口 支持HTTPS

    最稳定万能vip视频解析接口 支持HTTPS https://cdn.yangju.vip/k/?url=后面加上播放的地址即可 https://cdn.yangju.vip/k/?url= http ...

随机推荐

  1. vue 新增时清除表单验证注意事项

    // 清除表单校验的提示 if (this.$refs['XXX']) { // 延时执行 this.$nextTick(function () { this.$refs['XXX'].clearVa ...

  2. linux命令总结free命令

    free 命令是什么 free 命令是一个显示系统中空闲和已用内存大小的工具.free 命令的输出和 top 命令相似.大多数Linux发行版已经含有 free 命令. 如何运行 free 想要运行, ...

  3. JavaScript模拟QQ签名(HTML5 contenteditable属性)

    例图: 一.思路 1.单击元素时,使元素可以编辑,并获得焦点 2.按下键盘检测用户编辑元素中的文本 3.监听按下Enter键操作或离开可编辑元素焦点时,更新数据库 二.代码 $(function(){ ...

  4. 【51Nod】1510 最小化序列 贪心+动态规划

    [题目]1510 最小化序列 [题意]给定长度为n的数组A和数字k,要求重排列数组从而最小化: \[ans=\sum_{i=1}^{n-k}|A_i-A_{i+k}|\] 输出最小的ans,\(n \ ...

  5. MongoDB 之 手把手教你增删改查 MongoDB - 2

    我们在  MongoDB 之 你得知道MongoDB是个什么鬼 MongoDB - 1  中学习了如果安装部署一个 MongoDB 如果没看到我的金玉良言的话,就重新打开一次客户端和服务端吧 本章我们 ...

  6. CodeForces Contest #1114: Round #538 (Div. 2)

    比赛传送门:CF #1114. 比赛记录:点我. 又 FST 了. [A]Got Any Grapes? 题意简述: 有三个人,第一个人需要吃绿色葡萄至少 \(a\) 个,第二个人需要吃绿色和紫色葡萄 ...

  7. Redis配置文件介绍

    Redis在源码包中存放了一个Redis配置实例文件,文件中对各个配置点进行了简单的介绍,我也通过这个文件来对Redis的一些配置进行一些简单介绍. 一.UNITS(单位)[了解] 1.Redis服务 ...

  8. 解决“tar:Exiting with failure status due to previous errors”【转】

    问题: 当我想试着用tar命令来创建一个压缩文件时,总在执行过程中失败,并且抛出一个错误说明"tar:由于前一个错误导致于失败状态中退出"("Exiting with f ...

  9. javascript 模拟按键点击提交

    上代码 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> & ...

  10. ps自由变换以及再次变换快捷键

    ctrl+t:自由变换ctrl+shift+t:再次变换ctrl+shift+alt+t:复制一次,再次变换.