Commit 3ad15971 authored by wangjinjing's avatar wangjinjing

Merge branch 'master' of http://192.168.168.218/wcyuee/szpt

# Conflicts:
#	src/test/java/com/zksy/szpt/MainTest.java
parents 70ef5110 8bc94872
......@@ -3,6 +3,7 @@ package com.zksy.szpt.aspect;
import com.zksy.szpt.domain.HttpResult;
import com.zksy.szpt.domain.HttpResultState;
import com.zksy.szpt.exception.NotificationException;
import org.apache.ibatis.javassist.NotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -135,11 +136,11 @@ public class GlobalExceptionHandler {
//endregion
// @ResponseBody
// @ExceptionHandler({NotificationException.class})
// public HttpResult<HttpResultState> NotificationExceptionHandler(NotificationException e) {
// HttpResultState state = HttpResultState.NOTIFICATION;
// state.setMessage(e.getMessage());
// return new HttpResult<>(state);
// }
@ResponseBody
@ExceptionHandler({NotificationException.class})
public HttpResult<HttpResultState> NotificationExceptionHandler(NotificationException e) {
HttpResultState state = HttpResultState.NOTIFICATION;
state.setMessage(e.getMessage());
return new HttpResult<>(state);
}
}
package com.zksy.szpt.controller;
import com.zksy.szpt.domain.UploadImageDTO;
import com.zksy.szpt.exception.NotificationException;
import com.zksy.szpt.service.ImageUploadService;
import io.swagger.annotations.Api;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Api(tags = "文件上传管理")
@RequestMapping("/rest/image")
@RestController
public class ImageUploadController {
private final ImageUploadService imageUploadService;
public ImageUploadController(ImageUploadService imageUploadService) {
this.imageUploadService = imageUploadService;
}
@PostMapping("/upload")
public Integer upload(@RequestBody @Validated UploadImageDTO uploadImageDTO) throws NotificationException {
return imageUploadService.upload(uploadImageDTO);
}
}
package com.zksy.szpt.domain;
public enum ListImageType {
FACE,
BODY
}
package com.zksy.szpt.domain;
import javax.validation.constraints.NotBlank;
public class UploadImageDTO {
@NotBlank(message = "图片路径不能为空")
private String imagePath;
private ListImageType imageType;
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
public ListImageType getImageType() {
return imageType;
}
public void setImageType(ListImageType imageType) {
this.imageType = imageType;
}
}
package com.zksy.szpt.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
@TableName("xx_imgfile")
public class XxImgfile {
/**
* 图片IID
......@@ -11,6 +16,7 @@ public class XxImgfile {
/**
* 图片ID
*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**
......
package com.zksy.szpt.domain.po;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
@TableName
public class XxImgindex {
/**
* 图片IID
......@@ -11,6 +16,7 @@ public class XxImgindex {
/**
* 图片ID
*/
@TableId(type = IdType.ASSIGN_ID)
private String id;
/**
......
package com.zksy.szpt.exception;
/**
* 其他主动抛出的信息
*/
public class NotificationException extends Exception {
//异常信息
private final String message;
//构造函数
public NotificationException(String message) {
super(message);
this.message = message;
this.initCause(new Throwable(message));//设置cause,方便获取异常信息
}
}
package com.zksy.szpt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zksy.szpt.domain.po.XxImgfile;
import com.zksy.szpt.domain.po.XxImgfileExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface XxImgfileMapper {
public interface XxImgfileMapper extends BaseMapper<XxImgfile> {
long countByExample(XxImgfileExample example);
int deleteByExample(XxImgfileExample example);
int deleteByPrimaryKey(Long iid);
int insert(XxImgfile record);
// int insert(XxImgfile record);
int insertSelective(XxImgfile record);
......
package com.zksy.szpt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zksy.szpt.domain.po.XxImgindex;
import com.zksy.szpt.domain.po.XxImgindexExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface XxImgindexMapper {
public interface XxImgindexMapper extends BaseMapper<XxImgindex> {
long countByExample(XxImgindexExample example);
int deleteByExample(XxImgindexExample example);
......
package com.zksy.szpt.service;
import com.zksy.szpt.domain.UploadImageDTO;
import com.zksy.szpt.domain.po.XxImgfile;
import com.zksy.szpt.domain.po.XxImgindex;
import com.zksy.szpt.domain.po.XxImgindexExample;
import com.zksy.szpt.exception.NotificationException;
import com.zksy.szpt.mapper.XxImgfileMapper;
import com.zksy.szpt.mapper.XxImgindexMapper;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;
import java.net.URISyntaxException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@Service
public class ImageUploadService {
//日志
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ImageUploadService.class);
private final XxImgfileMapper xxImgfileMapper;
private final XxImgindexMapper xxImgindexMapper;
public ImageUploadService(XxImgfileMapper xxImgfileMapper, XxImgindexMapper xxImgindexMapper) {
this.xxImgfileMapper = xxImgfileMapper;
this.xxImgindexMapper = xxImgindexMapper;
}
public Integer upload(UploadImageDTO uploadImageDTO) throws NotificationException {
// 创建一个 TcpClient 并设置超时时间
final TcpClient tcpClient = TcpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 连接超时时间
.doOnConnected(connection -> connection.addHandlerLast(new ReadTimeoutHandler(5)) // 读取超时时间
.addHandlerLast(new WriteTimeoutHandler(5))); // 写入超时时间
// 创建 WebClient 实例用于下载文件
WebClient webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(HttpClient.from(tcpClient)))
.baseUrl(uploadImageDTO.getImagePath())
.build();
// 下载文件到内存中的字节数组
Mono<byte[]> fileContentMono = webClient.get()
.uri("")
.retrieve()
.bodyToMono(byte[].class)
.onErrorResume(WebClientResponseException.class, ex -> {
log.warn("WebClientResponseException: {}", ex.getResponseBodyAsString());
return Mono.error(new NotificationException(uploadImageDTO.getImagePath() + ",Failed to download file: " + ex.getStatusText()));
})
.onErrorResume(URISyntaxException.class, ex -> {
log.warn("URISyntaxException: {}", ex.getMessage());
return Mono.error(new NotificationException(uploadImageDTO.getImagePath() + ",Invalid URL format"));
})
.onErrorResume(Exception.class, ex -> {
log.warn("General Exception: {}", ex.getMessage());
return Mono.error(new NotificationException(ex.getMessage()));
});
XxImgfile xxImgfile = new XxImgfile();
xxImgfile.setOurl(uploadImageDTO.getImagePath());
xxImgfile.setNwzh("0");
// 等待文件内容下载完成
try {
byte[] fileContent = fileContentMono.block();
if (fileContent == null) {
throw new NotificationException("Failed to download file");
}
xxImgfile.setData(fileContent);
// 将文件内容转换为十六进制字符串
String fileContentHexString = toMd5(fileContent);
if (checkByMd5(fileContentHexString)) {
throw new NotificationException("File already exists");
}
//入库
XxImgindex xxImgindex = new XxImgindex();
xxImgindex.setOurl(uploadImageDTO.getImagePath());
xxImgindex.setMd5(fileContentHexString);
xxImgindexMapper.insert(xxImgindex);
return xxImgfileMapper.insert(xxImgfile);
} catch (Exception e) {
throw new NotificationException(e.getCause() == null ? e.getMessage() : e.getCause().getMessage());
}
// 将文件内容插入数据库
// fileContentMono.flatMap(fileContent -> {
// try {
// xxImgfile.setData(fileContent);
// return Mono.just(xxImgfileMapper.insert(xxImgfile));
// } catch (Exception e) {
// e.printStackTrace();
// return Mono.error(e);
// }
// }).subscribe(rowsAffected -> {
// System.out.println("Rows affected: " + rowsAffected);
// }, error -> {
// error.printStackTrace();
// });
}
private boolean checkByMd5(String imageUrl) {
XxImgindexExample example = new XxImgindexExample();
example.createCriteria().andMd5EqualTo(imageUrl);
return xxImgindexMapper.countByExample(example) >= 1;
}
private static final char[] hexCode = "0123456789ABCDEF".toCharArray();
private static String toMd5(byte[] data) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(data, 0, data.length);
byte[] hashBytes = digest.digest();
StringBuilder r = new StringBuilder(hashBytes.length * 2);
for (byte b : hashBytes) {
r.append(hexCode[(b >> 4) & 0xF]);
r.append(hexCode[(b & 0xF)]);
}
return r.toString();
}
}
......@@ -3,6 +3,7 @@ package com.zksy.szpt;
import cn.hutool.crypto.digest.DigestUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zksy.szpt.domain.dto.XxRwwcqkDTO;
import com.zksy.szpt.domain.dto.XxZhjfbgDTO;
import com.zksy.szpt.domain.dto.XxZhxxDTO;
import com.zksy.szpt.service.AppStoreService;
......@@ -11,13 +12,11 @@ import com.zksy.szpt.util.SignatureUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.platform.commons.util.StringUtils;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import javax.annotation.Resource;
import java.sql.Struct;
import java.util.Date;
/**
......@@ -26,7 +25,7 @@ import java.util.Date;
@SpringBootTest()
public class MainTest {
String nonce = "2121";
String nonce = "2";
String timestampStr = "21";
String appId = "1";
......@@ -36,7 +35,6 @@ public class MainTest {
@Resource
private AppStoreService appStoreService;
/**
* 任务完成情况
*/
......@@ -44,6 +42,51 @@ public class MainTest {
@DisplayName("任务完成情况")
public void xxRwwcqkTest() {
timestampStr = String.valueOf(System.currentTimeMillis() / 1000);
String secretKey = this.appStoreService.getAppSecretByAppKey(appId);
Assertions.assertNotNull(secretKey, "appId不存在");//断言appId存在,为空直接抛出异常不进行下一步测试,提高测试效率
//请求参数
XxRwwcqkDTO xxRwwcqkDTO = new XxRwwcqkDTO();
xxRwwcqkDTO.setRwid("123456");
xxRwwcqkDTO.setXxyid("123456");
xxRwwcqkDTO.setShrid("123456");
xxRwwcqkDTO.setWczt("1");
xxRwwcqkDTO.setBmzt("1");
String json = null;
try {
json = objectMapper.writeValueAsString(xxRwwcqkDTO);
} catch (JsonProcessingException e) {
Assertions.fail("json序列化失败");
}
//请求体加密
json = EncryptUtil.getInstance().AESEncode(json, secretKey);
//签名appId+nonce+timestampStr+aes(body)
String data = String.format("%s%s%s%s", appId, nonce, timestampStr, json);
String generatedSignature = DigestUtil.md5Hex(data);
//请求
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8086")
.defaultHeader("Content-Type", "application/json")
.build();
String response = webClient.post().uri("/rest/index/addXxRwwcqk")
.header(SignatureUtil.APPID, appId)
.header(SignatureUtil.NONCE, nonce)
.header(SignatureUtil.TIMESTAMP, timestampStr)
.header(SignatureUtil.SIGNATURE, generatedSignature)
.body(Mono.just(xxRwwcqkDTO), XxRwwcqkDTO.class)
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println(response);
}
/**
* 任务完成情况
*/
@Test
@DisplayName("任务完成情况")
public void xxRwwcqkTest1() {
timestampStr = String.valueOf(System.currentTimeMillis() / 1000);
nonce=String.valueOf(System.currentTimeMillis() / 1000);
String secretKey = this.appStoreService.getAppSecretByAppKey(appId);
Assertions.assertNotNull(secretKey, "appId不存在");//断言appId存在,为空直接抛出异常不进行下一步测试,提高测试效率
......@@ -126,4 +169,48 @@ public class MainTest {
.block();
System.out.println(response);
}
/**
* 任务完成情况
*/
@Test
@DisplayName("文件上传")
public void uploadFileTest() {
nonce = UUID.randomUUID().toString();
timestampStr = String.valueOf(System.currentTimeMillis() / 1000);
String secretKey = this.appStoreService.getAppSecretByAppKey(appId);
Assertions.assertNotNull(secretKey, "appId不存在");//断言appId存在,为空直接抛出异常不进行下一步测试,提高测试效率
//请求参数
UploadImageDTO uploadImageDTO = new UploadImageDTO();
uploadImageDTO.setImagePath("http://192.168.168.219/guoqing1.jpg");
uploadImageDTO.setImageType(ListImageType.FACE);
String json = null;
try {
json = objectMapper.writeValueAsString(uploadImageDTO);
} catch (JsonProcessingException e) {
Assertions.fail("json序列化失败");
}
//请求体加密
json = EncryptUtil.getInstance().AESEncode(json, secretKey);
//签名appId+nonce+timestampStr+aes(body)
String data = String.format("%s%s%s%s", appId, nonce, timestampStr, json);
String generatedSignature = DigestUtil.md5Hex(data);
//请求
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8086")
.defaultHeader("Content-Type", "application/json")
.build();
String response = webClient.post().uri("/rest/image/upload")
.header(SignatureUtil.APPID, appId)
.header(SignatureUtil.NONCE, nonce)
.header(SignatureUtil.TIMESTAMP, timestampStr)
.header(SignatureUtil.SIGNATURE, generatedSignature)
.body(Mono.just(uploadImageDTO), XxRwwcqkDTO.class)
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println(response);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment