1.需求:

之前在公司内部搭建了svn服务器,给部门存放文档、视频,做成了一个文档服务器来用,随着视频文件太大,每次下载太慢

需要把文件在线打开查看

2.解决:

kkFileView

https://kkfileview.keking.cn/zh-cn/index.html

kkFileView为文件文档在线预览解决方案,该项目使用流行的spring boot搭建,易上手和部署,基本支持主流办公文档的在线预览,如doc,docx,xls,xlsx,ppt,pptx,pdf,txt,zip,rar,图片,视频,音频等等

我之前写过的svn部署文档 https://www.cnblogs.com/wang3680/p/dc92818c4cb50701dbc42eef5e8a2482.html


kkFileView无法适配svn服务,需要开发svn客户端完成svn服务器文件的checkout操作

3.改造kkFileView适配svn服务

我用的版本是4.0.0 GitHub地址https://github.com/kekingcn/kkFileView

下载源码,导入到idea中

  • <dependency>
    <groupId>org.tmatesoft.svnkit</groupId>
    <artifactId>svnkit</artifactId>
    <version>1.9.3</version>
    </dependency>

  • 新增SVNUtils.java 在 package cn.keking.utils;

  •   1 package cn.keking.utils;
    2
    3 import org.slf4j.Logger;
    4 import org.slf4j.LoggerFactory;
    5 import org.tmatesoft.svn.core.*;
    6 import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
    7 import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
    8 import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
    9 import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
    10 import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
    11 import org.tmatesoft.svn.core.io.SVNRepository;
    12 import org.tmatesoft.svn.core.wc.*;
    13
    14 import java.io.File;
    15 import java.io.FileOutputStream;
    16 import java.io.IOException;
    17 import java.io.OutputStream;
    18
    19 /**
    20 * @program: filepreview
    21 * @ClassName SVNUtils
    22 * @description: svn下的https文件下载
    23 * @author: wangshaoshuai
    24 * @create: 2022/3/14 16:34
    25 */
    26 public class SVNUtils {
    27 private final static Logger logger = LoggerFactory.getLogger(SVNUtils.class);
    28
    29 private String url;
    30 private String username;
    31 private String password;
    32 private SVNRepository repository;
    33
    34 public SVNUtils(String url, String username, String password) {
    35 super();
    36 this.url = url;
    37 this.username = username;
    38 this.password = password;
    39 initialize();
    40 }
    41
    42 /**
    43 * 初始化操作
    44 *
    45 * @throws SVNException
    46 */
    47 private void initialize() {
    48 FSRepositoryFactory.setup();
    49 DAVRepositoryFactory.setup();
    50 SVNRepositoryFactoryImpl.setup();
    51 try {
    52 repository = SVNRepositoryFactoryImpl.create(SVNURL.parseURIEncoded(this.url));
    53 ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(this.username, this.password);
    54 repository.setAuthenticationManager(authManager);
    55 } catch (SVNException e) {
    56 e.printStackTrace();
    57 }
    58 }
    59
    60 /**
    61 * 从SVN服务器获取最新版本的文件
    62 *
    63 * @param filePath 相对于仓库根目录的路径
    64 * @return 返回checkout文件的版本号
    65 * @throws Exception 可以自定义Exception
    66 */
    67 public long getFileFromSVN(String filePath, String outFileName) {
    68 return getFileFromSVN(filePath, outFileName, 0);
    69 }
    70
    71 /**
    72 * 从SVN服务器获取文件
    73 *
    74 * @param filePath 相对于仓库根目录的路径
    75 * @param version 要checkout的版本号,当传入的版本号为0时,默认获取最新版本
    76 * @return 返回checkout文件的版本号
    77 * @throws Exception 可以自定义Exception
    78 */
    79 public long getFileFromSVN(String filePath, String outFileName, long version) {
    80 SVNNodeKind node = null;
    81 try {
    82 if (version == 0) {
    83 version = repository.getLatestRevision();
    84 }
    85 // node = repository.checkPath(filePath, version);
    86 } catch (SVNException e) {
    87 logger.error("SVN检测不到该文件:" + filePath, e);
    88 }
    89 // if (node != SVNNodeKind.FILE) {
    90 // logger.error(node.toString() + "不是文件");
    91 // }
    92 SVNProperties properties = new SVNProperties();
    93 try {
    94 OutputStream outputStream = new FileOutputStream(outFileName);
    95 repository.getFile(filePath, version, properties, outputStream);
    96 outputStream.close();
    97 } catch (SVNException e) {
    98 logger.error("获取SVN服务器中的" + filePath + "文件失败", e);
    99 } catch (IOException e) {
    100 logger.error("SVN check out file faild.", e);
    101 }
    102 return Long.parseLong(properties.getStringValue("svn:entry:revision"));
    103 }
    104 }
  • 修改DownloadUtils.java 具体位置为package cn.keking.utils;
  •   1 package cn.keking.utils;
    2
    3 import cn.keking.config.ConfigConstants;
    4 import cn.keking.model.FileAttribute;
    5 import cn.keking.model.ReturnResponse;
    6 import io.mola.galimatias.GalimatiasParseException;
    7 import org.apache.commons.io.FileUtils;
    8 import org.slf4j.Logger;
    9 import org.slf4j.LoggerFactory;
    10
    11 import java.io.*;
    12 import java.net.*;
    13 import java.util.UUID;
    14
    15 import static cn.keking.utils.KkFileUtils.isFtpUrl;
    16 import static cn.keking.utils.KkFileUtils.isHttpUrl;
    17
    18 /**
    19 * @author yudian-it
    20 */
    21 public class DownloadUtils {
    22
    23 private final static Logger logger = LoggerFactory.getLogger(DownloadUtils.class);
    24 private static final String fileDir = ConfigConstants.getFileDir();
    25 private static final String URL_PARAM_FTP_USERNAME = "ftp.username";
    26 private static final String URL_PARAM_FTP_PASSWORD = "ftp.password";
    27 private static final String URL_PARAM_FTP_CONTROL_ENCODING = "ftp.control.encoding";
    28
    29 private static final String URL_PARAM_URL_TYPE = "url.type";
    30 private static final String URL_PARAM_SVN_USERNAME = "svn.username";
    31 private static final String URL_PARAM_SVN_PASSWORD = "svn.password";
    32
    33 /**
    34 * @param fileAttribute fileAttribute
    35 * @param fileName 文件名
    36 * @return 本地文件绝对路径
    37 */
    38 public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
    39 String urlStr = fileAttribute.getUrl();
    40 ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
    41 String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
    42 try {
    43 URL url = WebUtils.normalizedURL(urlStr);
    44 if (isHttpUrl(url)) {
    45 File realFile = new File(realPath);
    46 String url_type = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_URL_TYPE);
    47 if(url_type.equalsIgnoreCase("svn")){//svn的服务的话下载方式不一样
    48 String svn_username = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_SVN_USERNAME);
    49 String svn_password = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_SVN_PASSWORD);
    50 String svn_folder = urlStr.substring(0,urlStr.lastIndexOf("/"));
    51 String file_name = urlStr.substring(urlStr.lastIndexOf("/")+1,urlStr.indexOf("?"));
    52 SVNUtils svnUtils = new SVNUtils(svn_folder,svn_username,svn_password);
    53 svnUtils.getFileFromSVN(file_name,realPath);
    54 }else{
    55 FileUtils.copyURLToFile(url,realFile);
    56 }
    57 } else if (isFtpUrl(url)) {
    58 String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
    59 String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);
    60 String ftpControlEncoding = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING);
    61 FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding);
    62 } else {
    63 response.setCode(1);
    64 response.setMsg("url不能识别url" + urlStr);
    65 }
    66 response.setContent(realPath);
    67 response.setMsg(fileName);
    68 return response;
    69 } catch (IOException | GalimatiasParseException e) {
    70 logger.error("文件下载失败,url:{}", urlStr, e);
    71 response.setCode(1);
    72 response.setContent(null);
    73 if (e instanceof FileNotFoundException) {
    74 response.setMsg("文件不存在!!!");
    75 } else {
    76 response.setMsg(e.getMessage());
    77 }
    78 return response;
    79 }
    80 }
    81
    82
    83 /**
    84 * 获取真实文件绝对路径
    85 *
    86 * @param fileName 文件名
    87 * @return 文件路径
    88 */
    89 private static String getRelFilePath(String fileName, FileAttribute fileAttribute) {
    90 String type = fileAttribute.getSuffix();
    91 if (null == fileName) {
    92 UUID uuid = UUID.randomUUID();
    93 fileName = uuid + "." + type;
    94 } else { // 文件后缀不一致时,以type为准(针对simText【将类txt文件转为txt】)
    95 fileName = fileName.replace(fileName.substring(fileName.lastIndexOf(".") + 1), type);
    96 }
    97 String realPath = fileDir + fileName;
    98 File dirFile = new File(fileDir);
    99 if (!dirFile.exists() && !dirFile.mkdirs()) {
    100 logger.error("创建目录【{}】失败,可能是权限不够,请检查", fileDir);
    101 }
    102 return realPath;
    103 }
    104
    105 }
     1 public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
    2 String urlStr = fileAttribute.getUrl();
    3 ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
    4 String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
    5 try {
    6 URL url = WebUtils.normalizedURL(urlStr);
    7 if (isHttpUrl(url)) {
    8 File realFile = new File(realPath);
    9 String url_type = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_URL_TYPE);
    10 if(url_type.equalsIgnoreCase("svn")){//svn的服务的话下载方式不一样
    11 String svn_username = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_SVN_USERNAME);
    12 String svn_password = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_SVN_PASSWORD);
    13 String svn_folder = urlStr.substring(0,urlStr.lastIndexOf("/"));
    14 String file_name = urlStr.substring(urlStr.lastIndexOf("/")+1,urlStr.indexOf("?"));
    15 SVNUtils svnUtils = new SVNUtils(svn_folder,svn_username,svn_password);
    16 svnUtils.getFileFromSVN(file_name,realPath);
    17 }else{
    18 FileUtils.copyURLToFile(url,realFile);
    19 }
    20 } else if (isFtpUrl(url)) {
    21 String ftpUsername = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_USERNAME);
    22 String ftpPassword = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_PASSWORD);
    23 String ftpControlEncoding = WebUtils.getUrlParameterReg(fileAttribute.getUrl(), URL_PARAM_FTP_CONTROL_ENCODING);
    24 FtpUtils.download(fileAttribute.getUrl(), realPath, ftpUsername, ftpPassword, ftpControlEncoding);
    25 } else {
    26 response.setCode(1);
    27 response.setMsg("url不能识别url" + urlStr);
    28 }
    29 response.setContent(realPath);
    30 response.setMsg(fileName);
    31 return response;
    32 } catch (IOException | GalimatiasParseException e) {
    33 logger.error("文件下载失败,url:{}", urlStr, e);
    34 response.setCode(1);
    35 response.setContent(null);
    36 if (e instanceof FileNotFoundException) {
    37 response.setMsg("文件不存在!!!");
    38 } else {
    39 response.setMsg(e.getMessage());
    40 }
    41 return response;
    42 }
    43 }

    主要是修改这段代码,增加svn类型的判断和工具类的使用

  • 使用方法如下:a.html
  • <!DOCTYPE html>
    
    <html lang="en">
    <head>
    <title>kkFileView演示首页</title>
    </head> <body>
    <div> </div>
    <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/js-base64@3.6.0/base64.min.js"></script>
    <script>
    var url = 'https://127.0.0.1/svn/业务学习资料/资料整理文档/JAVA学习/JAVA开发工具idea的使用01-王少帅.mp4';
    var pre_url = url + '?url.type=svn&svn.username=wangshaoshuai&svn.password=123456';
    window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(pre_url)));
    </script>
    </body>
    </html>
    1    var url = 'https://127.0.0.1/svn/业务学习资料/资料整理文档/JAVA学习/JAVA开发工具idea的使用01-王少帅.mp4';
    2 var pre_url = url + '?url.type=svn&svn.username=wangshaoshuai&svn.password=123456';
    3 window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(Base64.encode(pre_url)));

    主要是这段代码,即可加入到svn列表显示的服务里面会弹窗跳转一个新的预览页面


4.测试验证

  • idea下面启动服务
  • 用浏览器打开a.html

点击播放即可播放

kkFileView部署到windows服务出现问题解决

kkFileView对接svn服务完成文件在线预览功能的更多相关文章

  1. kkfileview v2.0 发布,文件在线预览项目方案

    kkfileview文件在线预览 此项目为文件文档在线预览项目解决方案,项目使用流行的spring boot搭建,易上手和部署,部署好后可以独立提供预览服务,使用http接口访问,不需要和应用集成,具 ...

  2. svn服务支持网页显示并增加在线预览功能,支持视频在线播放

    1.svn服务器支持网页显示 VisualSVN Server是一个非常不错的SVN Server程序,方便,直观,用户管理也异常方便.不过,它本身并没有提供在线修改密码的功能.由于在实际使用过程中, ...

  3. 基于开源方案构建统一的文件在线预览与office协同编辑平台的架构与实现历程

    大家好,又见面了. 在构建业务系统的时候,经常会涉及到对附件的支持,继而又会引申出对附件在线预览.在线编辑.多人协同编辑等种种能力的诉求. 对于人力不是特别充裕.或者项目投入预期规划不是特别大的公司或 ...

  4. 网页中动态嵌入PDF文件/在线预览PDF内容https://www.cnblogs.com/xgyy/p/6119459.html

    #网页中动态嵌入PDF文件/在线预览PDF内容# 摘要:在web开发时我们有时会需要在线预览PDF内容,在线嵌入pdf文件: 问题1:如何网页中嵌入PDF: 在网页中: 常用的几种PDF预览代码片段如 ...

  5. asp.net word ecxel类型文件在线预览

    asp.net word ecxel类型文件在线预览 首先得引用COM: Microsoft Excel 10 Object Library Microsoft Word 10 Object Libr ...

  6. 使用PDF.JS实现pdf文件在线预览时,报文件被损坏的错误

    首先大概说明一下问题出现的背景:我用PDF.JS实现文件在线预览,参考网上的办法,在jsp文件中使用 <iframe src="<c:url value="js/gen ...

  7. 文件在线预览doc,docx转换pdf(一)

    文件在线预览doc,docx转换pdf(一) 1. 前言 文档转换是一个是一块硬骨头,但是也是必不可少的,我们正好做的知识库产品中,也面临着同样的问题,文档转换,精准的全文搜索,知识的转换率,是知识库 ...

  8. C# WebAPI 文件在线预览

    最近在写一个移动端API接口,其中有一个需求:接口返回附件url地址让手机端调用实现文件在线预览.大体实现思路:把doc.xls等文本格式文件转换为pdf,转换后的pdf文件存放在服务器上面,方便第二 ...

  9. pdf文件在线预览

    使用pdfjs技术实现PDF的在线预览功能. 目录 1.官网下载pdf.js 2. 将下载下来的文件全部复制 3. js使用 4. java IO流 1.官网下载pdf.js 2. 将下载下来的文件全 ...

随机推荐

  1. Mysql Json函数总览 (一)

    JSON函数相关文章均来自官网,此处仅做记录,以便以后查询方便. https://dev.mysql.com/doc/refman/5.7/en/json-functions.html JSON函数参 ...

  2. VC 获取当前运行窗口名称

    转载请注明来源:https://www.cnblogs.com/hookjc/ BOOL CALLBACK WindowChild(HWND hwnd,LPARAM lparam){ CFGDlg* ...

  3. Mybatis foreach的用法

    本文援引:https://www.cnblogs.com/fnlingnzb-learner/p/10566452.html 在做mybatis的mapper.xml文件的时候,我们时常用到这样的情况 ...

  4. [转]有关ListIterator接口的add与remove方法探究

    原文地址: http://www.java123.net/v/492971.html 应用案例: http://820199753.iteye.com/blog/2230032 ListIterato ...

  5. BumbleBee: 如丝般顺滑构建、交付和运行 eBPF 程序

    本文地址:https://www.ebpf.top/post/bumblebee 1. 前言 不久前,Solo.io 公司在官网博客宣布了开源了一个名称为 BumbleBee 的新项目.该项目专注于简 ...

  6. 图计算 on nLive:Nebula 的图计算实践

    本文首发于 Nebula Graph Community 公众号 在 #图计算 on nLive# 直播活动中,来自 Nebula 研发团队的 nebula-plato 维护者郝彤和 nebula-a ...

  7. 一文了解如何源码编译Rainbond基础组件

    Rainbond 主要由以下三个项目组成,参考官网详细 技术架构 业务端 Rainbond-UI 和 Rainbond-Console 合起来构成了业务层.业务层是前后端分离模式.UI是业务层的前端代 ...

  8. Qunar风控安全产品的探索之路

    李建威.2017年7月以春招实习生的身份加入去哪儿网,毕业后一直在从事抓取与反抓取相关工作,先后负责搭建过智能打码.设备指纹以及环境检测等服务.目前主要负责反爬风控的基础安全产品建设.对各类作弊原理感 ...

  9. RFC2899广播吞吐量测试——网络测试仪实操

    一.简介 RFC 2889为LAN交换设备的基准测试提供了方法学,它将RFC 2544中为网络互联设备基准测试所定义的方法学扩展到了交换设备,提供了交换机转发性能(Forwarding Perform ...

  10. 如何搭建老板想要的dashborad管理驾驶舱,这篇文章值得一看!

    随着企业管理向精细化发展和信息化步伐的加快,企业采集到的市场客户及内部管理数据越来越多.越来越趋向于实时,系统大量的信息给企业带来了一个问题:管理者怎么用这些数据才能掌握企业动态,做出及时关键的决策? ...