Просмотр исходного кода

增加oss上传的md5校验;修复oss上传bucket选择错误

luoshi 4 лет назад
Родитель
Сommit
31b6704a22

+ 12 - 6
pom.xml

@@ -42,8 +42,9 @@
         <spring-boot.version>2.3.0.RELEASE</spring-boot.version>
         <gson.version>2.8.6</gson.version>
         <commons.version>3.10</commons.version>
+        <commons.codec.version>1.15</commons.codec.version>
         <jackson.version>2.11.0</jackson.version>
-<!--        <ehcache.version>2.10.6</ehcache.version>-->
+        <!--        <ehcache.version>2.10.6</ehcache.version>-->
         <swagger2-bootstrap.version>1.9.6</swagger2-bootstrap.version>
         <jetbrains.version>13.0</jetbrains.version>
         <tencentyun.version>1.1</tencentyun.version>
@@ -113,6 +114,11 @@
                 <artifactId>commons-lang3</artifactId>
                 <version>${commons.version}</version>
             </dependency>
+            <dependency>
+                <groupId>commons-codec</groupId>
+                <artifactId>commons-codec</artifactId>
+                <version>${commons.codec.version}</version>
+            </dependency>
             <dependency>
                 <groupId>com.google.code.gson</groupId>
                 <artifactId>gson</artifactId>
@@ -191,11 +197,11 @@
                 <version>${redis.version}</version>
             </dependency>
             <!-- ehcache 缓存 -->
-<!--            <dependency>-->
-<!--                <groupId>net.sf.ehcache</groupId>-->
-<!--                <artifactId>ehcache</artifactId>-->
-<!--                <version>${ehcache.version}</version>-->
-<!--            </dependency>-->
+            <!--            <dependency>-->
+            <!--                <groupId>net.sf.ehcache</groupId>-->
+            <!--                <artifactId>ehcache</artifactId>-->
+            <!--                <version>${ehcache.version}</version>-->
+            <!--            </dependency>-->
             <!-- rocketmq -->
             <dependency>
                 <groupId>org.apache.rocketmq</groupId>

+ 69 - 72
themis-backend/src/main/java/com/qmth/themis/backend/api/TEOpenController.java

@@ -1,26 +1,23 @@
 package com.qmth.themis.backend.api;
 
-import javax.annotation.Resource;
-
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestMethod;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.RestController;
-
 import com.qmth.themis.business.service.TEOpenService;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
+import io.swagger.annotations.*;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
 
-import io.swagger.annotations.Api;
-import io.swagger.annotations.ApiOperation;
-import io.swagger.annotations.ApiParam;
-import io.swagger.annotations.ApiResponse;
-import io.swagger.annotations.ApiResponses;
+import javax.annotation.Resource;
+import java.io.IOException;
 
-/**开放接口
- * @Description: 
+/**
+ * 开放接口
+ *
+ * @Description:
  * @Author: xiatian
  * @Date: 2020-10-19
  */
@@ -35,81 +32,81 @@ public class TEOpenController {
     @Resource
     RedisUtil redisUtil;
 
-
     @ApiOperation(value = "获取考试详情")
     @RequestMapping(value = "/exam/query", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examQueryPage(@ApiParam(value = "考试id", required = false) @RequestParam(required = false) Long examId,
-                                     @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
-                                     @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
-                                     @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
-    	
-    	if(pageSize!=null&&pageSize>20) {
-    		throw new BusinessException("每页最大条数为20");
-    	}
-    	if(pageNumber==null) {
-    		pageNumber=1;
-    	}
-    	if(pageSize==null) {
-    		pageSize=20;
-    	}
+            @ApiParam(value = "考试code", required = false) @RequestParam(required = false) String code,
+            @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
+            @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
+
+        if (pageSize != null && pageSize > 20) {
+            throw new BusinessException("每页最大条数为20");
+        }
+        if (pageNumber == null) {
+            pageNumber = 1;
+        }
+        if (pageSize == null) {
+            pageSize = 20;
+        }
         return ResultUtil.ok(openService.examQueryPage(examId, code, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "获取考试课程详情")
     @RequestMapping(value = "/exam/course/query", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examCourseQueryPage(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-                                     @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
-                                     @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
-                                     @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
-                                     @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
-    	if(pageSize!=null&&pageSize>100) {
-    		throw new BusinessException("每页最大条数为100");
-    	}
-    	if(pageNumber==null) {
-    		pageNumber=1;
-    	}
-    	if(pageSize==null) {
-    		pageSize=100;
-    	}
-    	if(examId==null) {
-    		throw new BusinessException("考试id不能为空");
-    	}
-        return ResultUtil.ok(openService.examCourseQueryPage(examId, courseCode,hasPaper, pageNumber, pageSize));
+            @ApiParam(value = "课程code", required = false) @RequestParam(required = false) String courseCode,
+            @ApiParam(value = "是否有试卷", required = false) @RequestParam(required = false) Boolean hasPaper,
+            @ApiParam(value = "分页页码", required = false) @RequestParam(required = false) Integer pageNumber,
+            @ApiParam(value = "分页数", required = false) @RequestParam(required = false) Integer pageSize) {
+        if (pageSize != null && pageSize > 100) {
+            throw new BusinessException("每页最大条数为100");
+        }
+        if (pageNumber == null) {
+            pageNumber = 1;
+        }
+        if (pageSize == null) {
+            pageSize = 100;
+        }
+        if (examId == null) {
+            throw new BusinessException("考试id不能为空");
+        }
+        return ResultUtil.ok(openService.examCourseQueryPage(examId, courseCode, hasPaper, pageNumber, pageSize));
     }
-    
+
     @ApiOperation(value = "获取考试试卷详情")
     @RequestMapping(value = "/exam/paper/detail", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examPaperDetail(@ApiParam(value = "试卷id", required = true) @RequestParam Long paperId,
-                                     @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String filter) {
-    	if(paperId==null) {
-    		throw new BusinessException("试卷id不能为空");
-    	}
+            @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String filter)
+            throws IOException {
+        if (paperId == null) {
+            throw new BusinessException("试卷id不能为空");
+        }
         return ResultUtil.ok(openService.examPaperDetail(paperId, filter));
     }
-    
+
     @ApiOperation(value = "待评卷考试记录查询")
     @RequestMapping(value = "/exam/record/need_mark", method = RequestMethod.POST)
-    @ApiResponses({@ApiResponse(code = 200, message = "结果信息")})
+    @ApiResponses({ @ApiResponse(code = 200, message = "结果信息") })
     public Result examRecordNeedMark(@ApiParam(value = "考试id", required = true) @RequestParam Long examId,
-                                     @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String courseCode,
-                                     @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
-                                     @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
-    	if(examId==null) {
-    		throw new BusinessException("考试id不能为空");
-    	}
-    	if(examStudentIdGt==null) {
-    		examStudentIdGt=0L;
-    	}
-    	if(count!=null&&count>20) {
-    		throw new BusinessException("count最大为20");
-    	}
-    	if(count==null) {
-    		count=20;
-    	}
-        return ResultUtil.ok(openService.examRecordNeedMark(examId, courseCode,examStudentIdGt,count));
+            @ApiParam(value = "内容过滤卷", required = false) @RequestParam(required = false) String courseCode,
+            @ApiParam(value = "考生ID大于此参数", required = false) @RequestParam(required = false) Long examStudentIdGt,
+            @ApiParam(value = "数量(最大20)", required = false) @RequestParam(required = false) Integer count) {
+        if (examId == null) {
+            throw new BusinessException("考试id不能为空");
+        }
+        if (examStudentIdGt == null) {
+            examStudentIdGt = 0L;
+        }
+        if (count != null && count > 20) {
+            throw new BusinessException("count最大为20");
+        }
+        if (count == null) {
+            count = 20;
+        }
+        return ResultUtil.ok(openService.examRecordNeedMark(examId, courseCode, examStudentIdGt, count));
     }
 
 }

+ 8 - 6
themis-business/src/main/java/com/qmth/themis/business/service/TEOpenService.java

@@ -1,20 +1,22 @@
 package com.qmth.themis.business.service;
 
-import java.util.List;
-
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.qmth.themis.business.bean.backend.OpenExamBean;
 import com.qmth.themis.business.bean.backend.OpenExamCourseBean;
 
+import java.io.IOException;
+import java.util.List;
+
 public interface TEOpenService {
 
-	public List<OpenExamBean> examQueryPage(Long examId, String examCode, int pageNumber, int pageSize);
+    public List<OpenExamBean> examQueryPage(Long examId, String examCode, int pageNumber, int pageSize);
 
-	public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper, int pageNumber, int pageSize);
+    public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper,
+            int pageNumber, int pageSize);
 
-	public JSONObject examPaperDetail(Long paperId, String filter);
+    public JSONObject examPaperDetail(Long paperId, String filter) throws IOException;
 
-	public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count);
+    public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count);
 
 }

+ 4 - 1
themis-business/src/main/java/com/qmth/themis/business/service/impl/TBAttachmentServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.dao.TBAttachmentMapper;
@@ -12,6 +13,7 @@ import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.common.contanst.Constants;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.util.HexUtils;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
@@ -125,7 +127,8 @@ public class TBAttachmentServiceImpl extends ServiceImpl<TBAttachmentMapper, TBA
             if (oss) {//上传至oss
                 stringJoiner.add(File.separator).add(String.valueOf(UUID.randomUUID()).replaceAll("-", ""))
                         .add(tbAttachment.getType());
-                ossUtil.upload(ossUtil.isPublic(type), stringJoiner.toString(), file.getInputStream());
+                ossUtil.upload(ossUtil.isPublic(type), stringJoiner.toString(), file.getInputStream(),
+                        BinaryUtil.toBase64String(HexUtils.decodeHex(md5)));
             } else {//上传至服务器
                 File finalFile = new File(
                         stringJoiner.add(File.separator).add(String.valueOf(UUID.randomUUID()).replaceAll("-", ""))

+ 5 - 8
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEExamServiceImpl.java

@@ -1,6 +1,7 @@
 package com.qmth.themis.business.service.impl;
 
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -28,8 +29,8 @@ import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.*;
 import com.qmth.themis.common.enums.ExceptionResultEnum;
 import com.qmth.themis.common.exception.BusinessException;
+import com.qmth.themis.common.util.HexUtils;
 import com.qmth.themis.common.util.IpUtil;
-import org.apache.commons.codec.digest.DigestUtils;
 import org.springframework.beans.BeanUtils;
 import org.springframework.cache.annotation.CacheEvict;
 import org.springframework.cache.annotation.CachePut;
@@ -756,13 +757,9 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
         String filePath = "upload" + File.separator + sdf.format(new Date()) + File.separator + uuid() + "." + suffix;
         InputStream in = null;
         try {
-            String fileMd5 = DigestUtils.md5Hex(file.getBytes());
-            if (!md5.equals(fileMd5)) {
-                throw new BusinessException("文件md5不一致");
-            }
             in = file.getInputStream();
-            ossUtil.upload(false, filePath, in);
-            String url = ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + File.separator + filePath;
+            ossUtil.upload(true, filePath, in, BinaryUtil.toBase64String(HexUtils.decodeHex(md5)));
+            String url = ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + filePath;
             ExamFileUploadBean ret = new ExamFileUploadBean();
             ret.setUrl(url);
             ret.setUploadTime(System.currentTimeMillis());
@@ -1306,7 +1303,7 @@ public class TEExamServiceImpl extends ServiceImpl<TEExamMapper, TEExam> impleme
             task.setStatus(TaskStatusEnum.FINISH);
             task.setFinishTime(System.currentTimeMillis());
             JSONObject json = new JSONObject();
-            String reportFilePath = "file/" + sdf.format(new Date()) + "/" + uuid() + SystemConstant.TXT_PREFIX;
+            String reportFilePath = "/" + sdf.format(new Date()) + "/" + uuid() + SystemConstant.TXT_PREFIX;
             json.put("path", reportFilePath);
             json.put("type", SystemConstant.OSS);
             ossUtil.upload(false, reportFilePath, e.getMessage());

+ 101 - 109
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEOpenServiceImpl.java

@@ -11,7 +11,6 @@ import com.qmth.themis.business.bean.backend.OpenRecordAnswerBean;
 import com.qmth.themis.business.bean.backend.OpenRecordNeedMarkBean;
 import com.qmth.themis.business.cache.RedisKeyHelper;
 import com.qmth.themis.business.cache.bean.ExamPaperCacheBean;
-import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEExamCourse;
 import com.qmth.themis.business.enums.InvigilateMonitorStatusEnum;
@@ -19,18 +18,22 @@ import com.qmth.themis.business.enums.RecordSelectStrategyEnum;
 import com.qmth.themis.business.service.*;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.common.exception.BusinessException;
-import com.qmth.themis.common.util.FileUtil;
 import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 
 import javax.annotation.Resource;
-import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.stream.Collectors;
 
 @Service
 public class TEOpenServiceImpl implements TEOpenService {
 
+    private final static Logger log = LoggerFactory.getLogger(TEOpenServiceImpl.class);
+
     @Resource
     TEExamService examService;
 
@@ -60,137 +63,124 @@ public class TEOpenServiceImpl implements TEOpenService {
         return ret.getRecords();
     }
 
-
     @Override
     public List<OpenExamCourseBean> examCourseQueryPage(Long examId, String courseCode, Boolean hasPaper,
-                                                        int pageNumber, int pageSize) {
+            int pageNumber, int pageSize) {
         Page<OpenExamCourseBean> ipage = new Page<>(pageNumber, pageSize);
         ipage.addOrder(OrderItem.desc("t.id"));
         IPage<OpenExamCourseBean> ret = examCourseService.examCourseQueryForOpen(ipage, examId, courseCode, hasPaper);
         return ret.getRecords();
     }
 
-
     @Override
-    public JSONObject examPaperDetail(Long paperId, String filter) {
-        String tempDir = SystemConstant.TEMP_FILES_DIR;
-        String dir = tempDir + "/" + uuid() + "/";
-        File dfile = new File(dir);
-
-        try {
-            ExamPaperCacheBean paper = examPaperService.getExamPaperCacheBean(paperId);
-            if (paper == null) {
-                throw new BusinessException("未找到试卷信息");
-            }
-            checkExam(paper.getExamId());
-            dfile.mkdirs();
-            String paperPath = paper.getPaperViewPath();
-            String anwserPath = paper.getAnswerPath();
-            File paperFile = new File(dir + uuid() + ".json");
-            File anwserFile = new File(dir + uuid() + ".json");
-            FileUtil.saveUrlAsFile(ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + paperPath, paperFile);
-            FileUtil.saveUrlAsFile(ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + anwserPath, anwserFile);
-            JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(anwserFile));
-            JSONArray answerdetails = answerJson.getJSONArray("details");
-            JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
-            structJson.put("id", paperId);
-            structJson.put("code", paper.getCode());
-            JSONArray structdetails = structJson.getJSONArray("details");
-            for (int i = 0; i < answerdetails.size(); i++) {
-                JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
-                JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
-                for (int j = 0; j < structdetailquestions.size(); j++) {
-                    JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
-                    JSONObject structquestion = structdetailquestions.getJSONObject(j);
-                    if ("objective".equals(filter)) {
-                        if (structquestion.getInteger("structType").intValue() == 1
-                                || structquestion.getInteger("structType").intValue() == 2
-                                || structquestion.getInteger("structType").intValue() == 3) {
-                            if (structquestion.getInteger("structType").intValue() == 3) {
-                                structquestion.put("answer", answerquestion.getBoolean("answer"));
-                            } else {
-                                structquestion.put("answer", answerquestion.getJSONArray("answer"));
-                            }
+    public JSONObject examPaperDetail(Long paperId, String filter) throws IOException {
+        ExamPaperCacheBean paper = examPaperService.getExamPaperCacheBean(paperId);
+        if (paper == null) {
+            throw new BusinessException("未找到试卷信息");
+        }
+        checkExam(paper.getExamId());
+        String paperPath = paper.getPaperViewPath();
+        String anwserPath = paper.getAnswerPath();
+        JSONObject answerJson = JSONObject
+                .parseObject(new String(ossUtil.download(false, anwserPath), StandardCharsets.UTF_8));
+        JSONArray answerdetails = answerJson.getJSONArray("details");
+        JSONObject structJson = JSONObject
+                .parseObject(new String(ossUtil.download(false, paperPath), StandardCharsets.UTF_8));
+        structJson.put("id", paperId);
+        structJson.put("code", paper.getCode());
+        JSONArray structdetails = structJson.getJSONArray("details");
+        for (int i = 0; i < answerdetails.size(); i++) {
+            JSONArray answerdetailquestions = answerdetails.getJSONObject(i).getJSONArray("questions");
+            JSONArray structdetailquestions = structdetails.getJSONObject(i).getJSONArray("questions");
+            for (int j = 0; j < structdetailquestions.size(); j++) {
+                JSONObject answerquestion = answerdetailquestions.getJSONObject(j);
+                JSONObject structquestion = structdetailquestions.getJSONObject(j);
+                if ("objective".equals(filter)) {
+                    if (structquestion.getInteger("structType").intValue() == 1
+                            || structquestion.getInteger("structType").intValue() == 2
+                            || structquestion.getInteger("structType").intValue() == 3) {
+                        if (structquestion.getInteger("structType").intValue() == 3) {
+                            structquestion.put("answer", answerquestion.getBoolean("answer"));
                         } else {
-                            if (structquestion.getInteger("structType").intValue() == 6) {
-                                JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
-                                JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
-                                for (int k = 0; k < structsubQuestions.size(); k++) {
-                                    JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
-                                    JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
-                                    if (structsubquestion.getInteger("structType").intValue() == 1
-                                            || structsubquestion.getInteger("structType").intValue() == 2
-                                            || structsubquestion.getInteger("structType").intValue() == 3) {
-                                        if (structsubquestion.getInteger("structType").intValue() == 3) {
-                                            structsubquestion.put("answer", answersubquestion.getBoolean("answer"));
-                                        } else {
-                                            structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
-                                        }
-                                    } else {
-                                        structsubQuestions.remove(k);
-                                        k--;
-                                    }
-                                }
-                            } else {
-                                structdetailquestions.remove(j);
-                                j--;
-                            }
-                        }
-
-                    } else if ("subjective".equals(filter)) {
-                        if (structquestion.getInteger("structType").intValue() != 1
-                                && structquestion.getInteger("structType").intValue() != 2
-                                && structquestion.getInteger("structType").intValue() != 3) {
                             structquestion.put("answer", answerquestion.getJSONArray("answer"));
-                        } else {
-                            if (structquestion.getInteger("structType").intValue() == 6) {
-                                JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
-                                JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
-                                for (int k = 0; k < structsubQuestions.size(); k++) {
-                                    JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
-                                    JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
-                                    if (structsubquestion.getInteger("structType").intValue() != 1
-                                            && structsubquestion.getInteger("structType").intValue() != 2
-                                            && structsubquestion.getInteger("structType").intValue() != 3) {
-                                        structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
+                        }
+                    } else {
+                        if (structquestion.getInteger("structType").intValue() == 6) {
+                            JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
+                            JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
+                            for (int k = 0; k < structsubQuestions.size(); k++) {
+                                JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
+                                JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
+                                if (structsubquestion.getInteger("structType").intValue() == 1
+                                        || structsubquestion.getInteger("structType").intValue() == 2
+                                        || structsubquestion.getInteger("structType").intValue() == 3) {
+                                    if (structsubquestion.getInteger("structType").intValue() == 3) {
+                                        structsubquestion.put("answer", answersubquestion.getBoolean("answer"));
                                     } else {
-                                        structsubQuestions.remove(k);
-                                        k--;
+                                        structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
                                     }
+                                } else {
+                                    structsubQuestions.remove(k);
+                                    k--;
                                 }
-                            } else {
-                                structdetailquestions.remove(j);
-                                j--;
                             }
+                        } else {
+                            structdetailquestions.remove(j);
+                            j--;
                         }
+                    }
+
+                } else if ("subjective".equals(filter)) {
+                    if (structquestion.getInteger("structType").intValue() != 1
+                            && structquestion.getInteger("structType").intValue() != 2
+                            && structquestion.getInteger("structType").intValue() != 3) {
+                        structquestion.put("answer", answerquestion.getJSONArray("answer"));
                     } else {
-                        if (structquestion.getInteger("structType").intValue() != 6) {
-                            if (structquestion.getInteger("structType").intValue() == 3) {
-                                structquestion.put("answer", answerquestion.getBoolean("answer"));
-                            } else {
-                                structquestion.put("answer", answerquestion.getJSONArray("answer"));
-                            }
-                        } else {
+                        if (structquestion.getInteger("structType").intValue() == 6) {
                             JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
                             JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
                             for (int k = 0; k < structsubQuestions.size(); k++) {
                                 JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
                                 JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
-                                if (structsubquestion.getInteger("structType").intValue() == 3) {
-                                    structsubquestion.put("answer", answersubquestion.getBoolean("answer"));
-                                } else {
+                                if (structsubquestion.getInteger("structType").intValue() != 1
+                                        && structsubquestion.getInteger("structType").intValue() != 2
+                                        && structsubquestion.getInteger("structType").intValue() != 3) {
                                     structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
+                                } else {
+                                    structsubQuestions.remove(k);
+                                    k--;
                                 }
                             }
+                        } else {
+                            structdetailquestions.remove(j);
+                            j--;
+                        }
+                    }
+                } else {
+                    if (structquestion.getInteger("structType").intValue() != 6) {
+                        if (structquestion.getInteger("structType").intValue() == 3) {
+                            structquestion.put("answer", answerquestion.getBoolean("answer"));
+                        } else {
+                            structquestion.put("answer", answerquestion.getJSONArray("answer"));
+                        }
+                    } else {
+                        JSONArray answersubQuestions = answerquestion.getJSONArray("subQuestions");
+                        JSONArray structsubQuestions = structquestion.getJSONArray("subQuestions");
+                        for (int k = 0; k < structsubQuestions.size(); k++) {
+                            JSONObject answersubquestion = answersubQuestions.getJSONObject(k);
+                            JSONObject structsubquestion = structsubQuestions.getJSONObject(k);
+                            if (structsubquestion.getInteger("structType").intValue() == 3) {
+                                structsubquestion.put("answer", answersubquestion.getBoolean("answer"));
+                            } else {
+                                structsubquestion.put("answer", answersubquestion.getJSONArray("answer"));
+                            }
                         }
                     }
-
                 }
+
             }
-            return structJson;
-        } finally {
-            FileUtil.deleteFolder(dir);
         }
+        return structJson;
     }
 
     private String uuid() {
@@ -219,10 +209,8 @@ public class TEOpenServiceImpl implements TEOpenService {
         }
     }
 
-
     @Override
-    public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt,
-                                        Integer count) {
+    public JSONArray examRecordNeedMark(Long examId, String courseCode, Long idGt, Integer count) {
         checkExam(examId);
         List<OpenRecordNeedMarkBean> list;
         for (; ; ) {
@@ -243,7 +231,8 @@ public class TEOpenServiceImpl implements TEOpenService {
             for (int i = 0; i < answers.size(); i++) {//剔除客观题答案
                 OpenRecordAnswerBean answer = answers.get(i);
                 Map<String, Integer> struct = examPaperService.getPaperStructCacheBean(answer.getPaperId());
-                Integer type = struct.get(RedisKeyHelper.examAnswerHashKey(answer.getMainNumber(), answer.getSubNumber(), answer.getSubIndex()));
+                Integer type = struct.get(RedisKeyHelper
+                        .examAnswerHashKey(answer.getMainNumber(), answer.getSubNumber(), answer.getSubIndex()));
                 if (type == 1 || type == 2 || type == 3) {
                     answers.remove(i);
                     i--;
@@ -306,7 +295,8 @@ public class TEOpenServiceImpl implements TEOpenService {
         TEExam exam = examService.getById(examId);
         if (RecordSelectStrategyEnum.HIGHEST_TOTAL_SCORE.equals(exam.getRecordSelectStrategy())) {//全阅
             return list;
-        } else if (RecordSelectStrategyEnum.HIGHEST_OBJECTIVE_SCORE.equals(exam.getRecordSelectStrategy())) {//客观分最高,相同则都阅
+        } else if (RecordSelectStrategyEnum.HIGHEST_OBJECTIVE_SCORE
+                .equals(exam.getRecordSelectStrategy())) {//客观分最高,相同则都阅
             Map<Long, List<OpenRecordNeedMarkBean>> map = new HashMap<>();
             for (OpenRecordNeedMarkBean bean : list) {
                 List<OpenRecordNeedMarkBean> temList = map.get(bean.getExamStudentId());
@@ -331,6 +321,7 @@ public class TEOpenServiceImpl implements TEOpenService {
                 }
             }
             Collections.sort(ret, new Comparator<OpenRecordNeedMarkBean>() {
+
                 @Override
                 public int compare(OpenRecordNeedMarkBean o1, OpenRecordNeedMarkBean o2) {
                     Long c1 = o1.getExamStudentId();
@@ -356,6 +347,7 @@ public class TEOpenServiceImpl implements TEOpenService {
             }
             List<OpenRecordNeedMarkBean> ret = map.values().stream().collect(Collectors.toList());
             Collections.sort(ret, new Comparator<OpenRecordNeedMarkBean>() {
+
                 @Override
                 public int compare(OpenRecordNeedMarkBean o1, OpenRecordNeedMarkBean o2) {
                     Long c1 = o1.getExamStudentId();

+ 4 - 7
themis-business/src/main/java/com/qmth/themis/business/service/impl/TEStudentServiceImpl.java

@@ -1,5 +1,6 @@
 package com.qmth.themis.business.service.impl;
 
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -14,7 +15,7 @@ import com.qmth.themis.business.service.TEStudentService;
 import com.qmth.themis.business.util.OssUtil;
 import com.qmth.themis.business.util.RedisUtil;
 import com.qmth.themis.common.exception.BusinessException;
-import org.apache.commons.codec.digest.DigestUtils;
+import com.qmth.themis.common.util.HexUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
@@ -88,18 +89,14 @@ public class TEStudentServiceImpl extends ServiceImpl<TEStudentMapper, TEStudent
         String filePath = "base_photo/" + orgId + "/" + student.getId() + "." + suffix;
         InputStream in = null;
         try {
-            String fileMd5 = DigestUtils.md5Hex(file.getBytes());
-            if (!md5.equals(fileMd5)) {
-                throw new BusinessException("文件md5不一致");
-            }
             student.setBasePhotoPath(filePath);
             this.saveOrUpdate(student);
             Gson gson = new Gson();
             TEStudentCacheDto teStudentCacheDto = gson.fromJson(gson.toJson(student), TEStudentCacheDto.class);
             redisUtil.setStudent(student.getId(), teStudentCacheDto);
             in = file.getInputStream();
-            ossUtil.upload(false, filePath, in);
-            String url = ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + File.separator + filePath;
+            ossUtil.upload(true, filePath, in, BinaryUtil.toBase64String(HexUtils.decodeHex(md5)));
+            String url = ossUtil.getAliYunOssPublicDomain().getPublicUrl() + File.separator + filePath;
             StudentPhotoUploadResponseBean ret = new StudentPhotoUploadResponseBean();
             ret.setPhotoUrl(url);
             return ret;

+ 1 - 3
themis-business/src/main/java/com/qmth/themis/business/service/impl/TOeExamRecordServiceImpl.java

@@ -422,9 +422,7 @@ public class TOeExamRecordServiceImpl extends ServiceImpl<TOeExamRecordMapper, T
             //            examStudentService.saveOrUpdate(examStudent);
             //上传个人试卷结构
             if (struct != null) {
-                File structFile = new File(dir + "struct.json");
-                FileUtil.saveAsFile(structFile.getAbsolutePath(), struct.getContent());
-                ossUtil.upload(false, structFilePath, structFile);
+                ossUtil.upload(false, structFilePath, struct.getContent());
             }
         } finally {
             FileUtil.deleteFolder(dir);

+ 6 - 3
themis-business/src/main/java/com/qmth/themis/business/templete/TaskExportCommon.java

@@ -16,7 +16,10 @@ import org.apache.poi.ss.usermodel.Row;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.*;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.util.*;
 
 /**
@@ -109,10 +112,10 @@ public class TaskExportCommon {
      * @param file
      * @throws FileNotFoundException
      */
-    public void ossUpload(File file) throws FileNotFoundException {
+    public void ossUpload(File file) throws IOException {
         boolean oss = (boolean) this.getOssEnv().get(SystemConstant.OSS);
         if (oss) {//上传至oss
-            this.ossUtil.upload(false, file.getPath().replaceAll("\\\\", "/"), new FileInputStream(file));
+            this.ossUtil.upload(false, file.getPath().replaceAll("\\\\", "/"), file);
             file.delete();
         }
     }

+ 33 - 35
themis-business/src/main/java/com/qmth/themis/business/templete/impl/TaskExamPaperImportTemplete.java

@@ -3,6 +3,7 @@ package com.qmth.themis.business.templete.impl;
 import cn.hutool.core.date.DateUtil;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.qmth.themis.business.constant.SystemConstant;
 import com.qmth.themis.business.entity.TEExam;
 import com.qmth.themis.business.entity.TEExamCourse;
@@ -25,16 +26,16 @@ import com.qmth.themis.common.exception.BusinessException;
 import com.qmth.themis.common.util.FileUtil;
 import com.qmth.themis.common.util.Result;
 import com.qmth.themis.common.util.ResultUtil;
-import org.apache.commons.io.FileUtils;
+import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-import sun.misc.BASE64Decoder;
 
 import javax.annotation.Resource;
+import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FilenameFilter;
 import java.io.IOException;
@@ -159,7 +160,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void disposeCourseDir(String rootDir, TEExam teExam, File courseDir, Map<String, Object> map) {
+    private void disposeCourseDir(String rootDir, TEExam teExam, File courseDir, Map<String, Object> map)
+            throws IOException {
         String courseCode = courseDir.getName();
         TEExamCourse course = teExamCourseService.findByExamIdAndCourseCode(teExam.getId(), courseCode);
         if (course == null) {
@@ -227,7 +229,7 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
     }
 
     private void disposePaperDir(String rootDir, TEExam teExam, TEExamCourse course, File paperDir,
-            Map<String, Object> map) {
+            Map<String, Object> map) throws IOException {
         String paperCode = paperDir.getName();
         File[] childs = paperDir.listFiles();
 
@@ -289,8 +291,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         teExamPaperService.saveOrUpdate(paper);
     }
 
-    private void disposeViewPaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
-        File urlPaperFile = new File(rootDir + uuid() + ".json");
+    private void disposeViewPaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir)
+            throws IOException {
         JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(paperFile));
         JSONArray structdetails = structJson.getJSONArray("details");
         if (structdetails == null || structdetails.size() == 0) {
@@ -318,13 +320,13 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                 }
             }
         }
-        FileUtil.saveAsFile(urlPaperFile.getAbsolutePath(), structJson.toJSONString());
         String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
         paper.setPaperViewPath(filePath);
-        ossUtil.upload(false, filePath, urlPaperFile);
+        ossUtil.upload(false, filePath, structJson.toJSONString());
     }
 
-    private void disposeQuestionBodyUrl(String rootDir, JSONObject body, Long paperId, File attachmentDir) {
+    private void disposeQuestionBodyUrl(String rootDir, JSONObject body, Long paperId, File attachmentDir)
+            throws IOException {
         if (body == null) {
             return;
         }
@@ -346,7 +348,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void disposeQuestionOptionsUrl(String rootDir, JSONArray options, Long paperId, File attachmentDir) {
+    private void disposeQuestionOptionsUrl(String rootDir, JSONArray options, Long paperId, File attachmentDir)
+            throws IOException {
         if (options == null || options.size() == 0) {
             return;
         }
@@ -375,7 +378,8 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void disposePaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir) {
+    private void disposePaper(String rootDir, TEExamPaper paper, File paperFile, File attachmentDir)
+            throws IOException {
         if (paperFile == null) {
             return;
         }
@@ -440,21 +444,18 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
             }
         }
 
-        File file = new File(rootDir + uuid() + ".json");
-        FileUtil.saveAsFile(file.getAbsolutePath(), paperJson.toJSONString());
         String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
         paper.setStructPath(filePath);
         paper.setTotalObjectiveScore(obTotal.doubleValue());
         paper.setTotalSubjectiveScore(subTotal.doubleValue());
-        ossUtil.upload(false, filePath, file);
+        ossUtil.upload(false, filePath, paperJson.toJSONString());
     }
 
-    private void disposeAnswer(String rootDir, TEExamPaper paper, File answerFile, File structFile,
-            File attachmentDir) {
+    private void disposeAnswer(String rootDir, TEExamPaper paper, File answerFile, File structFile, File attachmentDir)
+            throws IOException {
         if (answerFile == null) {
             return;
         }
-        File urlAnswerFile = new File(rootDir + uuid() + ".json");
         JSONObject answerJson = JSONObject.parseObject(FileUtil.readFileContent(answerFile));
         JSONArray answerdetails = answerJson.getJSONArray("details");
         JSONObject structJson = JSONObject.parseObject(FileUtil.readFileContent(structFile));
@@ -488,13 +489,13 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
                 }
             }
         }
-        FileUtil.saveAsFile(urlAnswerFile.getAbsolutePath(), answerJson.toJSONString());
         String filePath = sdf.format(new Date()) + "/" + uuid() + ".json";
         paper.setAnswerPath(filePath);
-        ossUtil.upload(false, filePath, urlAnswerFile);
+        ossUtil.upload(false, filePath, answerJson.toJSONString());
     }
 
-    private void disposeAnswerUrl(String rootDir, JSONArray answer, Long paperId, File attachmentDir) {
+    private void disposeAnswerUrl(String rootDir, JSONArray answer, Long paperId, File attachmentDir)
+            throws IOException {
         if (answer != null && answer.size() > 0) {
             for (int i = 0; i < answer.size(); i++) {
                 JSONObject section = answer.getJSONObject(i);
@@ -519,30 +520,27 @@ public class TaskExamPaperImportTemplete implements TaskImportTemplete {
         }
     }
 
-    private void uploadImageAndAudio(String rootDir, JSONObject blockInfo, Long paperId, File attachmentDir) {
+    private void uploadImageAndAudio(String rootDir, JSONObject blockInfo, Long paperId, File attachmentDir)
+            throws IOException {
         String type = blockInfo.getString("type");
         String value = blockInfo.getString("value");
         if (("image".equals(type) || "audio".equals(type)) && StringUtils.isNotBlank(value) && !value.toLowerCase()
                 .startsWith("https://") && !value.toLowerCase().startsWith("http://")) {
             if ("image".equals(type) && value.contains("data:image")) {
                 String suff = value.substring(11, value.indexOf(";"));
-                File iamgeFile = new File(rootDir + uuid() + "." + suff);
-                BASE64Decoder decoder = new BASE64Decoder();
-                try {
-                    byte[] bytes = decoder.decodeBuffer(value.substring(value.indexOf(",") + 1));
-                    FileUtils.writeByteArrayToFile(iamgeFile, bytes);
-                } catch (IOException e) {
-                    throw new BusinessException("媒体文件上传处理出错:" + blockInfo.toJSONString() + " errmsg:" + e.getMessage());
-                }
-                String filePath = "upload/paper_file/" + paperId + "/" + uuid() + "." + suff;
-                ossUtil.upload(false, filePath, iamgeFile);
-                blockInfo.put("value", ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + filePath);
+                byte[] bytes = Base64.decodeBase64(value.substring(value.indexOf(",") + 1));
+                String filePath =
+                        "upload" + File.separator + sdf.format(new Date()) + File.separator + uuid() + "." + suff;
+                String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(bytes));
+                ossUtil.upload(true, filePath, new ByteArrayInputStream(bytes), md5);
+                blockInfo.put("value", ossUtil.getAliYunOssPublicDomain().getPublicUrl() + "/" + filePath);
             } else {
                 String suff = value.substring(value.indexOf("."));
-                String filePath = "upload/paper_file/" + paperId + "/" + uuid() + suff;
+                String filePath =
+                        "upload" + File.separator + sdf.format(new Date()) + File.separator + uuid() + "." + suff;
                 File audioFile = new File(attachmentDir.getAbsolutePath() + "/" + value);
-                ossUtil.upload(false, filePath, audioFile);
-                blockInfo.put("value", ossUtil.getAliYunOssPrivateDomain().getPrivateUrl() + "/" + filePath);
+                ossUtil.upload(true, filePath, audioFile);
+                blockInfo.put("value", ossUtil.getAliYunOssPublicDomain().getPublicUrl() + "/" + filePath);
             }
         }
     }

+ 17 - 4
themis-business/src/main/java/com/qmth/themis/business/util/OssUtil.java

@@ -3,12 +3,14 @@ package com.qmth.themis.business.util;
 import com.aliyun.oss.ClientBuilderConfiguration;
 import com.aliyun.oss.OSS;
 import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.common.utils.BinaryUtil;
 import com.aliyun.oss.model.*;
 import com.qmth.themis.business.domain.AliYunOssDomain;
 import com.qmth.themis.business.domain.AliYunOssPrivateDomain;
 import com.qmth.themis.business.domain.AliYunOssPublicDomain;
 import com.qmth.themis.business.domain.SysDomain;
 import com.qmth.themis.business.enums.UploadFileEnum;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -95,10 +97,13 @@ public class OssUtil {
      * @param objectName
      * @param inputStream
      */
-    public void upload(boolean isPublic, String objectName, InputStream inputStream) {
+    public void upload(boolean isPublic, String objectName, InputStream inputStream, String md5) {
         log.info("oss  upload stream is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;
+        ObjectMetadata meta = new ObjectMetadata();
+        // 设置MD5校验。
+        meta.setContentMD5(md5);
         // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
         PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, inputStream);
         PutObjectResult por = client.putObject(putObjectRequest);
@@ -112,12 +117,16 @@ public class OssUtil {
      * @param objectName
      * @param file
      */
-    public void upload(boolean isPublic, String objectName, File file) {
+    public void upload(boolean isPublic, String objectName, File file) throws IOException {
         log.info("oss  upload file is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;
+        ObjectMetadata meta = new ObjectMetadata();
+        // 设置MD5校验。
+        String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(FileUtils.readFileToByteArray(file)));
+        meta.setContentMD5(md5);
         // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
-        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, file);
+        PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName, file, meta);
         PutObjectResult por = client.putObject(putObjectRequest);
         log.info("objectName:{},requestid:{}", objectName, por.getRequestId());
     }
@@ -133,9 +142,13 @@ public class OssUtil {
         log.info("oss public upload string is come in");
         String bucket = isPublic ? aliYunOssPublicDomain.getPublicBucket() : aliYunOssPrivateDomain.getPrivateBucket();
         OSS client = isPublic ? publicClient : privateClient;
+        ObjectMetadata meta = new ObjectMetadata();
+        // 设置MD5校验。
+        String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
+        meta.setContentMD5(md5);
         // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。
         PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, objectName,
-                new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)));
+                new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), meta);
         PutObjectResult por = client.putObject(putObjectRequest);
         log.info("objectName:{},requestid:{}", objectName, por.getRequestId());
     }

+ 73 - 69
themis-common/pom.xml

@@ -1,78 +1,82 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-	<groupId>com.qmth.themis.common</groupId>
-	<artifactId>themis-common</artifactId>
-	<version>1.0.0</version>
-	<packaging>jar</packaging>
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>com.qmth.themis.common</groupId>
+    <artifactId>themis-common</artifactId>
+    <version>1.0.0</version>
+    <packaging>jar</packaging>
 
-	<parent>
-		<groupId>com.qmth.themis</groupId>
-		<artifactId>themis-service</artifactId>
-		<version>1.0.0</version>
-	</parent>
+    <parent>
+        <groupId>com.qmth.themis</groupId>
+        <artifactId>themis-service</artifactId>
+        <version>1.0.0</version>
+    </parent>
 
-	<dependencies>
-		<dependency>
-			<groupId>com.alibaba</groupId>
-			<artifactId>fastjson</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.fasterxml.jackson.core</groupId>
-			<artifactId>jackson-core</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.fasterxml.jackson.core</groupId>
-			<artifactId>jackson-annotations</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.fasterxml.jackson.core</groupId>
-			<artifactId>jackson-databind</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.apache.commons</groupId>
-			<artifactId>commons-lang3</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.google.guava</groupId>
-			<artifactId>guava</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>com.google.code.gson</groupId>
-			<artifactId>gson</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>cn.hutool</groupId>
-			<artifactId>hutool-all</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.bouncycastle</groupId>
-			<artifactId>bcprov-jdk15on</artifactId>
-		</dependency>
-		<dependency>
-			<groupId>org.springframework</groupId>
-			<artifactId>spring-web</artifactId>
-			<version>5.2.7.RELEASE</version>
-		</dependency>
-		<dependency>
-			<groupId>commons-io</groupId>
-			<artifactId>commons-io</artifactId>
-			<version>2.6</version>
-		</dependency>
+    <dependencies>
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>fastjson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.commons</groupId>
+            <artifactId>commons-lang3</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>5.2.7.RELEASE</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
+            <version>2.6</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.tomcat.embed</groupId>
             <artifactId>tomcat-embed-core</artifactId>
         </dependency>
-		<dependency>
-			<groupId>org.slf4j</groupId>
-			<artifactId>slf4j-api</artifactId>
-			<version>2.0.0-alpha1</version>
-		</dependency>
-		<dependency>
-			<groupId>com.github.tencentyun</groupId>
-			<artifactId>tls-sig-api-v2</artifactId>
-		</dependency>
-	</dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>2.0.0-alpha1</version>
+        </dependency>
+        <dependency>
+            <groupId>com.github.tencentyun</groupId>
+            <artifactId>tls-sig-api-v2</artifactId>
+        </dependency>
+    </dependencies>
 </project>

+ 25 - 0
themis-common/src/main/java/com/qmth/themis/common/util/HexUtils.java

@@ -0,0 +1,25 @@
+package com.qmth.themis.common.util;
+
+import org.apache.commons.codec.DecoderException;
+import org.apache.commons.codec.binary.Hex;
+
+public class HexUtils {
+
+    /**
+     * Hex编码.
+     */
+    public static String encodeHex(byte[] input) {
+        return Hex.encodeHexString(input);
+    }
+
+    /**
+     * Hex解码.
+     */
+    public static byte[] decodeHex(String input) {
+        try {
+            return Hex.decodeHex(input.toCharArray());
+        } catch (DecoderException e) {
+            return null;
+        }
+    }
+}