package cn.gistack.by.nettyUpload;
|
|
|
import cn.gistack.by.nettyUpload.config.NettyHttpConfig;
|
import cn.gistack.by.nettyUpload.utils.BeenUtils;
|
import cn.gistack.by.nettyUpload.utils.HttpResponseUtils;
|
import cn.gistack.by.nettyUpload.utils.UriUtils;
|
import cn.gistack.by.nettyUpload.utils.ExceptionUtils;
|
import cn.gistack.by.picUpload.entity.BaiyiPicEntity;
|
import cn.gistack.by.picUpload.entity.XfByPic;
|
import cn.gistack.by.picUpload.entity.XfBySnRelation;
|
import cn.gistack.by.picUpload.service.BaiyiPicService;
|
import cn.gistack.resource.feign.IOssClient;
|
import cn.hutool.core.date.DateUtil;
|
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBufUtil;
|
import io.netty.buffer.Unpooled;
|
import io.netty.channel.ChannelFutureListener;
|
import io.netty.channel.ChannelHandlerContext;
|
import io.netty.channel.SimpleChannelInboundHandler;
|
import io.netty.handler.codec.http.*;
|
import io.netty.handler.codec.http.multipart.*;
|
import io.netty.util.CharsetUtil;
|
import lombok.extern.slf4j.Slf4j;
|
|
import java.io.*;
|
import java.net.URI;
|
import java.net.URISyntaxException;
|
import java.text.SimpleDateFormat;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import static cn.gistack.by.nettyUpload.utils.ExceptionUtils.getStackString;
|
|
/**
|
* 文件上传处理类
|
* @author chenhaijian
|
* @date 2020-05-21 14:45
|
*/
|
@Slf4j
|
public class HttpUploadFileHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
|
// http请求中可选参数
|
private static final String FILENAME_PARAM = "filename";
|
// http请求中必选的参数
|
private static final String FILE_EXTNAME_PARAM = "fileextname";
|
|
|
private static final String UPLOAD_DATA_URL = "/termite/syncDeviceState";
|
|
/***
|
* 新设备传图片接口
|
*/
|
private static final String UPLOAD_FILE_URL = "/termite/termiteDataup";
|
/**
|
* 旧设备传图片接口
|
* 没有Authorization验证
|
*/
|
private static final String UPLOAD_FILE_URL_OLD = "/termite/termiteDataupOld";
|
/**
|
* * 旧设备sn码和物联网关系表
|
* * 没有Authorization验证
|
*/
|
private static final String UPLOAD_FILE_OLD_RELATION = "/termite/termiteRelation";
|
|
private NettyHttpConfig nettyHttpConfig;
|
|
private BaiyiPicService baiyiPicService;
|
|
/**
|
* 对象存储构建类
|
*/
|
|
private IOssClient iOssClient;
|
|
static {
|
// should delete file on exit (in normal exit)
|
DiskFileUpload.deleteOnExitTemporaryFile = true;
|
DiskFileUpload.baseDirectory = null; // system temp directory
|
DiskAttribute.deleteOnExitTemporaryFile = true; // should delete file on
|
// exit (in normal exit)
|
DiskAttribute.baseDirectory = null; // system temp directory
|
|
|
}
|
|
public HttpUploadFileHandler(NettyHttpConfig nettyHttpConfig, IOssClient iOssClient,BaiyiPicService baiyiPicService) {
|
this.nettyHttpConfig = nettyHttpConfig;
|
this.iOssClient = iOssClient;
|
this.baiyiPicService = baiyiPicService;
|
|
}
|
|
|
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest fullRequest) throws Exception {
|
|
// 请求路径验证
|
String urlyz = UriUtils.getURI(fullRequest).getPath();
|
log.info("请求路径urlyz::"+urlyz);
|
|
if (UPLOAD_FILE_URL.equals(urlyz)) { //传图片
|
// Authorization验证
|
boolean isRequestValid = isValidHttpRequest(ctx, fullRequest);
|
if (!isRequestValid) {
|
HttpResponseUtils.sendResponseJson2(ctx, HttpResponseStatus.BAD_REQUEST, "验证失败",null);
|
return ;
|
}
|
|
XfByPic xfByPic = setEntity(fullRequest);
|
|
// 保存入库xfByPic
|
baiyiPicService.inserXfPicUrl(xfByPic);
|
|
|
|
}else if(UPLOAD_FILE_URL_OLD.equals(urlyz)) { // 旧类型设备上传图片数据接口
|
log.info("UPLOAD_FILE_URL_OLD接口调用成功!!!!:");
|
System.err.println(fullRequest);
|
|
XfByPic xfByPic = setEntity(fullRequest);
|
// 保存入库xfByPic
|
baiyiPicService.inserXfOldPicUrl(xfByPic);
|
|
|
}else if(UPLOAD_FILE_OLD_RELATION.equals(urlyz)) { //传sn和rtu编码关系接口
|
HttpPostMultipartRequestDecoder test = new HttpPostMultipartRequestDecoder(fullRequest);
|
List<InterfaceHttpData> bodyHttpDatas = test.getBodyHttpDatas();
|
String sn = "";
|
for (InterfaceHttpData item : bodyHttpDatas ) {
|
if ( item instanceof Attribute){
|
Attribute attribute = (Attribute) item;
|
String value = attribute.getValue();
|
switch (attribute.getName()) {
|
case "sn":
|
sn = value;
|
break;
|
}
|
|
}
|
}
|
// 查询sn对应的
|
XfBySnRelation xfBySnRelation = baiyiPicService.selectMnnoBySn(sn);
|
HashMap<String, Object> objectObjectHashMap = new HashMap<>();
|
objectObjectHashMap.put("mn_no", xfBySnRelation.getWlwRtu());
|
objectObjectHashMap.put("order", xfBySnRelation.getWlwOrder());
|
|
|
HttpResponseUtils.sendResponseJson2(ctx, HttpResponseStatus.OK, "查询成功",objectObjectHashMap);
|
return ;
|
} else {
|
HttpResponseUtils.sendResponseJson2(ctx, HttpResponseStatus.BAD_REQUEST, "验证失败",null);
|
return ;
|
}
|
|
HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.OK, "上传成功");
|
}
|
|
//请求参数注入实体
|
public XfByPic setEntity(FullHttpRequest fullRequest) throws Exception {
|
HttpPostMultipartRequestDecoder test = new HttpPostMultipartRequestDecoder(fullRequest);
|
List<InterfaceHttpData> bodyHttpDatas = test.getBodyHttpDatas();
|
XfByPic xfByPic = new XfByPic();
|
for (InterfaceHttpData item : bodyHttpDatas ) {
|
if (item instanceof Attribute) {
|
Attribute attribute = (Attribute) item;
|
String value = attribute.getValue();
|
switch (attribute.getName()) {
|
case "mnNo":
|
xfByPic.setMnNo(value);
|
break;
|
case "order":
|
|
xfByPic.setOrder(value);
|
break;
|
case "sn":
|
xfByPic.setSn(value);
|
break;
|
case "ap":
|
xfByPic.setAp(value);
|
break;
|
case "camera":
|
xfByPic.setCamera(value);
|
break;
|
case "hardware":
|
xfByPic.setHardware(value);
|
break;
|
case "rssi":
|
xfByPic.setRssi(value);
|
break;
|
case "software":
|
xfByPic.setSoftware(value);
|
break;
|
case "temperature":
|
xfByPic.setTemperature(value);
|
break;
|
case "voltage":
|
xfByPic.setVoltage(value);
|
break;
|
}
|
|
|
} else if (item instanceof FileUpload) {
|
|
FileUpload file = (FileUpload) item;
|
String filename = file.getFilename();
|
|
ByteArrayInputStream stream = new ByteArrayInputStream(ByteBufUtil.getBytes(file.getByteBuf()));
|
MockMultipartFile multipartFile
|
= new MockMultipartFile("11", filename, "application/octet-stream", stream);
|
|
String picurl = iOssClient.uploadFile(filename, multipartFile);
|
log.info("图片上传地址::" + picurl);
|
xfByPic.setImageurl(picurl);
|
}
|
}
|
xfByPic.setCreatedAt(new Date());
|
|
return xfByPic;
|
}
|
|
|
// 请求路径验证
|
public String urlyz(ChannelHandlerContext ctx, FullHttpRequest request) {
|
try {
|
|
URI uri = UriUtils.getURI(request);
|
System.err.println("uri.getPath()::::"+uri.getPath());
|
System.err.println(""+uri.getPath());
|
|
if (uri.getPath().startsWith(UPLOAD_DATA_URL)) {
|
return UPLOAD_DATA_URL;
|
|
} else if (uri.getPath().startsWith(UPLOAD_FILE_URL)) {
|
return UPLOAD_FILE_URL;
|
|
} else if (uri.getPath().startsWith(UPLOAD_FILE_URL_OLD)) {
|
|
return UPLOAD_FILE_URL_OLD;
|
}
|
} catch (Exception exception) {
|
exception.printStackTrace();
|
log.error(getStackString(exception));
|
return null;
|
}
|
return null;
|
}
|
|
|
|
public static MultipartFile convert(File file) throws IOException {
|
|
FileInputStream input = new FileInputStream(file);
|
MultipartFile multipartFile = new MockMultipartFile("file",
|
file.getName(), "application/octet-stream", input);
|
|
return multipartFile;
|
}
|
|
private String parseFilePath(FullHttpRequest fullRequest) throws URISyntaxException {
|
String dirPath = this.nettyHttpConfig.getFileSaveRootPath();
|
String fileName = this.parseFileName(fullRequest);
|
|
return dirPath + File.separator + fileName;
|
}
|
|
private RandomAccessFile getSaveFile(String filePath) {
|
try {
|
RandomAccessFile file = new RandomAccessFile(filePath, "rw");
|
return file;
|
} catch (Exception exception) {
|
log.error(getStackString(exception));
|
return null;
|
}
|
}
|
|
private boolean isValidHttpRequest(ChannelHandlerContext ctx, FullHttpRequest request) {
|
try {
|
URI uri = UriUtils.getURI(request);
|
// log.info(uri.getPath());
|
// authorization效验
|
String authorization = request.headers().get("Authorization");
|
if(!this.nettyHttpConfig.getAuthorization().equals(authorization)) {
|
log.warn("Authorization校验失败!!");
|
// 校验不通过
|
HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.UNAUTHORIZED, HttpResponseStatus.UNAUTHORIZED.toString());
|
// 校验不通过
|
return false;
|
}
|
|
// 密码校验
|
// boolean authFlag = auth(ctx, uri);
|
// if (!authFlag) {
|
// // 校验不通过
|
// HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.UNAUTHORIZED, HttpResponseStatus.UNAUTHORIZED.toString());
|
// // 校验不通过
|
// return false;
|
// }
|
|
// uri 路径校验
|
// if (!uri.getPath().startsWith(UPLOAD_FILE_URL)) {
|
// HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.BAD_REQUEST,"the url must starts with /postfile");
|
// return false;
|
// }
|
|
return true;
|
} catch (Exception exception) {
|
exception.printStackTrace();
|
log.error(getStackString(exception));
|
return false;
|
}
|
}
|
|
private String parseFileName(FullHttpRequest fullRequest) throws URISyntaxException {
|
URI uri = UriUtils.getURI(fullRequest);
|
Map<String, String> queryParams = UriUtils.getQueryParams(uri);
|
try {
|
if (queryParams.containsKey(FILENAME_PARAM)) {
|
return queryParams.get(FILENAME_PARAM);
|
} else {
|
SimpleDateFormat dateFormat = new SimpleDateFormat("YYYY_MM_dd_HH_MM_SS_sss");
|
String filePureName = dateFormat.format(new Date());
|
return filePureName + "." + queryParams.get(FILE_EXTNAME_PARAM);
|
}
|
} catch (Exception exception) {
|
log.error(ExceptionUtils.getStackString(exception));
|
return String.valueOf(System.currentTimeMillis());
|
}
|
}
|
|
private void writeResponse(ChannelHandlerContext ctx, String context) {
|
ByteBuf buf = Unpooled.copiedBuffer(context, CharsetUtil.UTF_8);
|
FullHttpResponse response = new DefaultFullHttpResponse(
|
HttpVersion.HTTP_1_1, HttpResponseStatus.OK, buf);
|
response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/html;charset=utf-8");
|
//设置短连接 addListener 写完马上关闭连接
|
ctx.channel().writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
|
}
|
|
/**
|
* 进行请求的密码校验
|
* @param ctx
|
* @param uri
|
* @return
|
*/
|
private boolean auth(ChannelHandlerContext ctx, URI uri) {
|
Map<String, String> queryParams = UriUtils.getQueryParams(uri);
|
String passwd = queryParams.get("passwd");
|
if (this.nettyHttpConfig.getFileUpPasswd().equals(passwd)) {
|
return true;
|
}
|
return false;
|
}
|
|
@Override
|
public void channelInactive(ChannelHandlerContext ctx) {
|
ctx.close();
|
}
|
|
@Override
|
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
|
log.error(getStackString(cause));
|
cause.printStackTrace();
|
ctx.close();
|
}
|
}
|