mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2025-10-07 23:24:30 +08:00
@@ -130,6 +130,8 @@ tif.preview.type = ${KK_TIF_PREVIEW_TYPE:tif}
|
||||
beian = ${KK_BEIAN:default}
|
||||
#禁止上传类型
|
||||
prohibit = ${KK_PROHIBIT:exe,dll,dat}
|
||||
#启用验证码删除文件 默认关闭
|
||||
delete.captcha= ${KK_DELETE_CAPTCHA:false}
|
||||
#删除密码
|
||||
delete.password = ${KK_DELETE_PASSWORD:123456}
|
||||
#删除 转换后OFFICE、CAD、TIFF、压缩包源文件 默认开启 节约磁盘空间
|
||||
|
@@ -50,6 +50,7 @@ public class ConfigConstants {
|
||||
private static String officeTypeWeb;
|
||||
private static String cadPreviewType;
|
||||
private static Boolean deleteSourceFile;
|
||||
private static Boolean deleteCaptcha;
|
||||
|
||||
public static final String DEFAULT_CACHE_ENABLED = "true";
|
||||
public static final String DEFAULT_TXT_TYPE = "txt,html,htm,asp,jsp,xml,json,properties,md,gitignore,log,java,py,c,cpp,sql,sh,bat,m,bas,prg,cmd";
|
||||
@@ -78,6 +79,7 @@ public class ConfigConstants {
|
||||
public static final String DEFAULT_PDF2_JPG_DPI = "105";
|
||||
public static final String DEFAULT_OFFICE_TYPE_WEB = "web";
|
||||
public static final String DEFAULT_DELETE_SOURCE_FILE = "true";
|
||||
public static final String DEFAULT_DELETE_CAPTCHA = "false";
|
||||
|
||||
public static Boolean isCacheEnabled() {
|
||||
return cacheEnabled;
|
||||
@@ -447,7 +449,9 @@ public class ConfigConstants {
|
||||
setDeleteSourceFileValue(deleteSourceFile);
|
||||
}
|
||||
|
||||
|
||||
public static void setDeleteSourceFileValue(Boolean deleteSourceFile) {
|
||||
ConfigConstants.deleteSourceFile = deleteSourceFile;
|
||||
}
|
||||
|
||||
public static String getCadPreviewType() {
|
||||
return cadPreviewType;
|
||||
@@ -462,8 +466,16 @@ public class ConfigConstants {
|
||||
ConfigConstants.cadPreviewType = cadPreviewType;
|
||||
}
|
||||
|
||||
public static void setDeleteSourceFileValue(Boolean deleteSourceFile) {
|
||||
ConfigConstants.deleteSourceFile = deleteSourceFile;
|
||||
public static Boolean getDeleteCaptcha() {
|
||||
return deleteCaptcha;
|
||||
}
|
||||
|
||||
@Value("${delete.captcha:false}")
|
||||
public void setDeleteCaptcha(Boolean deleteCaptcha) {
|
||||
setDeleteCaptchaValue(deleteCaptcha);
|
||||
}
|
||||
|
||||
public static void setDeleteCaptchaValue(Boolean deleteCaptcha) {
|
||||
ConfigConstants.deleteCaptcha = deleteCaptcha;
|
||||
}
|
||||
}
|
||||
|
@@ -62,6 +62,7 @@ public class ConfigRefreshComponent {
|
||||
String officeTypeWeb;
|
||||
String cadPreviewType;
|
||||
boolean deleteSourceFile;
|
||||
boolean deleteCaptcha;
|
||||
while (true) {
|
||||
FileReader fileReader = new FileReader(configFilePath);
|
||||
BufferedReader bufferedReader = new BufferedReader(fileReader);
|
||||
@@ -94,6 +95,7 @@ public class ConfigRefreshComponent {
|
||||
pdf2JpgDpi = Integer.parseInt(properties.getProperty("pdf2jpg.dpi", ConfigConstants.DEFAULT_PDF2_JPG_DPI));
|
||||
officeTypeWeb = properties.getProperty("office.type.web", ConfigConstants.DEFAULT_OFFICE_TYPE_WEB);
|
||||
deleteSourceFile = Boolean.parseBoolean(properties.getProperty("delete.source.file", ConfigConstants.DEFAULT_DELETE_SOURCE_FILE));
|
||||
deleteCaptcha = Boolean.parseBoolean(properties.getProperty("delete.captcha", ConfigConstants.DEFAULT_DELETE_CAPTCHA));
|
||||
prohibitArray = prohibit.split(",");
|
||||
|
||||
ConfigConstants.setCacheEnabledValueValue(cacheEnabled);
|
||||
@@ -121,6 +123,7 @@ public class ConfigRefreshComponent {
|
||||
ConfigConstants.setPdf2JpgDpiValue(pdf2JpgDpi);
|
||||
ConfigConstants.setOfficeTypeWebValue(officeTypeWeb);
|
||||
ConfigConstants.setDeleteSourceFileValue(deleteSourceFile);
|
||||
ConfigConstants.setDeleteCaptchaValue(deleteCaptcha);
|
||||
setWatermarkConfig(properties);
|
||||
bufferedReader.close();
|
||||
fileReader.close();
|
||||
|
@@ -0,0 +1,90 @@
|
||||
package cn.keking.utils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomValidateCodeUtil {
|
||||
|
||||
private static final int width = 100;// 定义图片的width
|
||||
private static final int height = 30;// 定义图片的height
|
||||
private static final int codeCount = 4;// 定义图片上显示验证码的个数
|
||||
private static final int xx = 18;
|
||||
private static final int fontHeight = 28;
|
||||
private static final int codeY = 27;
|
||||
private static final char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R','T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a','b','c','d','e','f','g','h','j','k','m','n','p','q','r','s','t','u','v','w','x','y', '2', '3', '4','5', '6', '7', '8', '9' };
|
||||
|
||||
/**
|
||||
* 生成一个map集合
|
||||
* code为生成的验证码
|
||||
* codePic为生成的验证码BufferedImage对象
|
||||
*/
|
||||
public static Map<String,Object> generateCodeAndPic(String ip, String sessionCode, int lx) {
|
||||
// 定义图像buffer
|
||||
BufferedImage buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||
// Graphics2D gd = buffImg.createGraphics();
|
||||
// Graphics2D gd = (Graphics2D) buffImg.getGraphics();
|
||||
Graphics gd = buffImg.getGraphics();
|
||||
// 创建一个随机数生成器类
|
||||
Random random = new Random();
|
||||
// 将图像填充为白色
|
||||
gd.setColor(Color.WHITE);
|
||||
gd.fillRect(0, 0, width, height);
|
||||
|
||||
// 创建字体,字体的大小应该根据图片的高度来定。
|
||||
Font font = new Font("Times New Roman", Font.BOLD, fontHeight);
|
||||
// 设置字体。
|
||||
gd.setFont(font);
|
||||
|
||||
// 画边框。
|
||||
gd.setColor(Color.BLACK);
|
||||
gd.drawRect(0, 0, width - 1, height - 1);
|
||||
|
||||
// 随机产生40条干扰线,使图象中的认证码不易被其它程序探测到。
|
||||
gd.setColor(Color.BLACK);
|
||||
for (int i = 0; i < 30; i++) {
|
||||
int x = random.nextInt(width);
|
||||
int y = random.nextInt(height);
|
||||
int xl = random.nextInt(12);
|
||||
int yl = random.nextInt(12);
|
||||
gd.drawLine(x, y, x + xl, y + yl);
|
||||
}
|
||||
StringBuffer randomCode = new StringBuffer();
|
||||
Map<String,Object> map = new HashMap<>();
|
||||
// randomCode用于保存随机产生的验证码,以便用户登录后进行验证。
|
||||
int red, green, blue;
|
||||
if (lx ==1){
|
||||
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
|
||||
red = random.nextInt(255);
|
||||
green = random.nextInt(255);
|
||||
blue = random.nextInt(255);
|
||||
// 用随机产生的颜色将验证码绘制到图像中。
|
||||
gd.setColor(new Color(red, green, blue));
|
||||
gd.drawString(sessionCode, xx, codeY);
|
||||
randomCode.append(sessionCode);
|
||||
}else {
|
||||
// 随机产生codeCount数字的验证码。
|
||||
for (int i = 0; i < codeCount; i++) {
|
||||
// 得到随机产生的验证码数字。
|
||||
String code = String.valueOf(codeSequence[random.nextInt(30)]);
|
||||
// 产生随机的颜色分量来构造颜色值,这样输出的每位数字的颜色值都将不同。
|
||||
red = random.nextInt(255);
|
||||
green = random.nextInt(255);
|
||||
blue = random.nextInt(255);
|
||||
// 用随机产生的颜色将验证码绘制到图像中。
|
||||
gd.setColor(new Color(red, green, blue));
|
||||
gd.drawString(code, (i + 1) * xx, codeY);
|
||||
// 将产生的四个随机数组合在一起。
|
||||
randomCode.append(code);
|
||||
}
|
||||
}
|
||||
//存放验证码
|
||||
map.put("code", randomCode);
|
||||
//存放生成的验证码BufferedImage对象
|
||||
map.put("codePic", buffImg);
|
||||
return map;
|
||||
}
|
||||
}
|
@@ -15,6 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -59,16 +60,29 @@ public class FileController {
|
||||
}
|
||||
|
||||
@GetMapping("/deleteFile")
|
||||
public ReturnResponse<Object> deleteFile(String fileName,String password) {
|
||||
public ReturnResponse<Object> deleteFile(HttpServletRequest request, String fileName, String password) {
|
||||
ReturnResponse<Object> checkResult = this.deleteFileCheck(fileName);
|
||||
if (checkResult.isFailure()) {
|
||||
return checkResult;
|
||||
}
|
||||
fileName = checkResult.getContent().toString();
|
||||
if(!ConfigConstants.getPassword().equalsIgnoreCase(password)) {
|
||||
if(ConfigConstants.getDeleteCaptcha()){
|
||||
String sessionCode;
|
||||
try {
|
||||
sessionCode = request.getSession().getAttribute("code").toString(); //获取已经保存的验证码
|
||||
} catch (Exception e) {
|
||||
sessionCode = "null";
|
||||
}
|
||||
if (password==null || !sessionCode.equalsIgnoreCase(password)){
|
||||
logger.error("删除文件【{}】失败,密码错误!",fileName);
|
||||
return ReturnResponse.failure("删除文件失败,密码错误!");
|
||||
}
|
||||
}else {
|
||||
if(password==null || !ConfigConstants.getPassword().equalsIgnoreCase(password)) {
|
||||
logger.error("删除文件【{}】失败,密码错误!",fileName);
|
||||
return ReturnResponse.failure("删除文件失败,密码错误!");
|
||||
}
|
||||
}
|
||||
File file = new File(fileDir + demoPath + fileName);
|
||||
logger.info("删除文件:{}", file.getAbsolutePath());
|
||||
if (file.exists() && !file.delete()) {
|
||||
@@ -76,6 +90,7 @@ public class FileController {
|
||||
logger.error(msg);
|
||||
return ReturnResponse.failure(msg);
|
||||
}
|
||||
request.getSession().removeAttribute("code"); //删除缓存验证码
|
||||
return ReturnResponse.success();
|
||||
}
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
package cn.keking.web.controller;
|
||||
|
||||
import cn.keking.config.ConfigConstants;
|
||||
import cn.keking.model.FileAttribute;
|
||||
import cn.keking.service.FileHandlerService;
|
||||
import cn.keking.service.FilePreview;
|
||||
@@ -7,6 +8,7 @@ import cn.keking.service.FilePreviewFactory;
|
||||
import cn.keking.service.cache.CacheService;
|
||||
import cn.keking.service.impl.OtherFilePreviewImpl;
|
||||
import cn.keking.utils.KkFileUtils;
|
||||
import cn.keking.utils.RandomValidateCodeUtil;
|
||||
import cn.keking.utils.WebUtils;
|
||||
import fr.opensagres.xdocreport.core.io.IOUtils;
|
||||
import io.mola.galimatias.GalimatiasParseException;
|
||||
@@ -15,18 +17,26 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.awt.image.RenderedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.keking.service.FilePreview.PICTURE_FILE_PREVIEW_PAGE;
|
||||
|
||||
@@ -160,6 +170,82 @@ public class OnlinePreviewController {
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 验证码方法
|
||||
*/
|
||||
@RequestMapping("/captcha")
|
||||
public void captcha(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
if(!ConfigConstants.getDeleteCaptcha()){
|
||||
return;
|
||||
}
|
||||
response.setContentType("image/gif");
|
||||
response.setHeader("Pragma", "No-cache");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setDateHeader("Expires", 0);
|
||||
Date date = new Date(); // 当前时间
|
||||
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 设置时间格式
|
||||
String sessionCode;
|
||||
try {
|
||||
sessionCode = request.getSession().getAttribute("code").toString(); //获取已经保存的验证码
|
||||
} catch (Exception e) {
|
||||
sessionCode= null;
|
||||
}
|
||||
Object time = request.getSession().getAttribute("time"); //获取已经保存的时间
|
||||
if (ObjectUtils.isEmpty(time)){ //判断时间是否为空
|
||||
request.getSession().setAttribute("time", formater.format(date)); //为空重新添加缓存时间
|
||||
time = request.getSession().getAttribute("time");
|
||||
}
|
||||
Date joinTime = formater.parse(String.valueOf(time));
|
||||
String dateStart = formater.format(joinTime);
|
||||
Date d1=formater.parse(dateStart);
|
||||
// 时间差:
|
||||
long diff = date.getTime() - d1.getTime();
|
||||
long diffSeconds = diff / 1000 % 60;
|
||||
String ip=request.getRemoteAddr();
|
||||
ServletOutputStream sos = null;
|
||||
if (ObjectUtils.isEmpty(sessionCode) || diffSeconds > 50){ //判断验证码是否为空 为空重新生成 判断是否在有效时间内 默认50秒
|
||||
Map<String, Object> codeMap = RandomValidateCodeUtil.generateCodeAndPic(ip,sessionCode,0);
|
||||
// 验证码存入session
|
||||
request.getSession().setAttribute("code", codeMap.get("code").toString());
|
||||
// 时间存入session
|
||||
request.getSession().setAttribute("time", formater.format(date));
|
||||
// 禁止图像缓存。
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setDateHeader("Expires", -1);
|
||||
response.setContentType("image/jpeg");
|
||||
// 将图像输出到Servlet输出流中。
|
||||
try {
|
||||
sos = response.getOutputStream();
|
||||
ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
assert sos != null;
|
||||
sos.close();
|
||||
}
|
||||
}else {
|
||||
// System.out.println("请输入你的姓名:");
|
||||
Map<String, Object> codeMap = RandomValidateCodeUtil.generateCodeAndPic(ip,sessionCode,1);
|
||||
// 禁止图像缓存。
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setHeader("Cache-Control", "no-cache");
|
||||
response.setDateHeader("Expires", -1);
|
||||
response.setContentType("image/jpeg");
|
||||
// 将图像输出到Servlet输出流中。
|
||||
try {
|
||||
sos = response.getOutputStream();
|
||||
ImageIO.write((RenderedImage) codeMap.get("codePic"), "jpeg", sos);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
assert sos != null;
|
||||
sos.close();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过api接口入队
|
||||
|
@@ -42,6 +42,7 @@ public class AttributeSetFilter implements Filter {
|
||||
request.setAttribute("fileUploadDisable", ConfigConstants.getFileUploadDisable());
|
||||
request.setAttribute("beian", ConfigConstants.getBeian());
|
||||
request.setAttribute("size", ConfigConstants.maxSize());
|
||||
request.setAttribute("deleteCaptcha", ConfigConstants.getDeleteCaptcha());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -111,6 +111,52 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<#if deleteCaptcha >
|
||||
<#-- 获取删除吗 -->
|
||||
<div class="panel panel-success">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">获取删除码(注意:每个验证码只能删除一个文件,验证码有效期为50秒)</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<img id="verImg" width="130px" height="48px"/>
|
||||
<button id="getPic" type="button" class="btn btn-success">获取删除码</button>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.onload = function(){
|
||||
var windowUrl = window.URL || window.webkitURL; //处理浏览器兼容性
|
||||
document.getElementById('getPic').onclick = function(e){
|
||||
//1、创建ajax对象
|
||||
var xhr = null;
|
||||
try{
|
||||
xhr = new XMLHttpRequest();
|
||||
}catch(error){
|
||||
xhr = new ActiveXObject("Microsoft.XMLHTTP");
|
||||
}
|
||||
//2、调用open
|
||||
xhr.open("get", "/captcha", true);
|
||||
xhr.responseType = "blob";
|
||||
//3、调用send
|
||||
xhr.send();
|
||||
//4、等待数据响应
|
||||
xhr.onreadystatechange = function(){
|
||||
if(xhr.readyState == 4){
|
||||
//判断本次下载的状态码都是多少
|
||||
if(xhr.status == 200){
|
||||
var blob = this.response;
|
||||
$("#verImg").attr("src",windowUrl.createObjectURL(blob));
|
||||
//$('#verImg').attr('src', xhr.responseText);
|
||||
|
||||
// alert(windowUrl.createObjectURL(blob));
|
||||
}else{
|
||||
alert("Error:" + xhr.status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</#if>
|
||||
<#-- 预览测试 -->
|
||||
<div class="panel panel-success">
|
||||
<div class="panel-heading">
|
||||
@@ -164,7 +210,11 @@
|
||||
<script>
|
||||
function deleteFile(fileName,password) {
|
||||
if(window.confirm('你确定要删除文件吗?')){
|
||||
<#if deleteCaptcha >
|
||||
password = prompt("请输入获取的验证码:");
|
||||
<#else>
|
||||
password = prompt("请输入默认密码:123456");
|
||||
</#if>
|
||||
$.ajax({
|
||||
url: '${baseUrl}deleteFile?fileName=' + fileName +'&password='+password,
|
||||
success: function (data) {
|
||||
|
Reference in New Issue
Block a user