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.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.DiskAttribute;
|
import io.netty.handler.codec.http.multipart.DiskFileUpload;
|
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.Map;
|
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
|
import javax.annotation.Resource;
|
|
import static cn.gistack.by.nettyUpload.utils.ExceptionUtils.getStackString;
|
|
/**
|
* 文件上传处理类
|
* @author chenhaijian
|
* @date 2020-05-21 14:45
|
*/
|
@Slf4j
|
public class HttpUploadFileHandler extends SimpleChannelInboundHandler<FullHttpRequest> {
|
private static final String UPLOAD_FILE_URL = "/postfile";
|
// http请求中可选参数
|
private static final String FILENAME_PARAM = "filename";
|
// http请求中必选的参数
|
private static final String FILE_EXTNAME_PARAM = "fileextname";
|
|
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 {
|
System.err.println("fullRequest:::"+fullRequest);
|
boolean isRequestValid = isValidHttpRequest(ctx, fullRequest);
|
if (!isRequestValid) {
|
log.warn("Discard invalid request.");
|
|
//HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.BAD_REQUEST, "验证失败");
|
return;
|
}
|
|
// 解析出文件路径
|
// String filePath = parseFilePath(fullRequest);
|
// System.err.println(filePath);
|
// RandomAccessFile file = getSaveFile(filePath);
|
// file.seek(0);
|
// file.write(ByteBufUtil.getBytes(fullRequest.content()));
|
// file.close();
|
|
//String fileName = this.parseFileName(fullRequest);
|
|
String fileName = System.currentTimeMillis() + ".jpg";
|
|
ByteArrayInputStream stream = new ByteArrayInputStream(ByteBufUtil.getBytes(fullRequest.content()));
|
MockMultipartFile multipartFile
|
= new MockMultipartFile("11", fileName, "application/octet-stream", stream);
|
|
|
|
// 上传荆楚水库的文件地址
|
// System.err.println("iOssClient::");
|
// System.err.println(iOssClient.getClass().getName());
|
// System.err.println(iOssClient);
|
|
String picurl = iOssClient.uploadFile(fileName, multipartFile);
|
// System.err.println("图片上传地址"+picurl);
|
log.info("图片上传地址::"+picurl);
|
|
// 请求参数放入实体中
|
BaiyiPicEntity baiyiPicEntity = parseEntity(fullRequest);
|
baiyiPicEntity.setPicUrl(picurl);
|
baiyiPicEntity.setPicStatus(1);
|
|
//baiyiPicEntity存入数据库
|
baiyiPicService.inserpicData(baiyiPicEntity);
|
|
|
HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.OK, "上传成功");
|
}
|
|
private BaiyiPicEntity parseEntity(FullHttpRequest fullRequest) throws URISyntaxException {
|
URI uri = UriUtils.getURI(fullRequest);
|
Map<String, String> queryParams = UriUtils.getQueryParams(uri);
|
|
String mnNo = queryParams.get("mnNo");
|
String order = queryParams.get("order");
|
String obTime = queryParams.get("obTime");
|
String obDatestr = queryParams.get("obDate");
|
Date obDate = DateUtil.parse(obDatestr, "yyyy-MM-dd HH:mm:ss");
|
|
String stationIdstr = queryParams.get("stationId");
|
Integer stationId = Integer.parseInt(stationIdstr);
|
|
String stationName = queryParams.get("stationName");
|
String deviceIdstr = queryParams.get("deviceId");
|
Integer deviceId = Integer.parseInt(deviceIdstr);
|
|
String deviceName = queryParams.get("deviceName");
|
String receiveTypestr = queryParams.get("receiveType");
|
Integer receiveType = Integer.parseInt(receiveTypestr);
|
|
BaiyiPicEntity baiyiPicEntity = new BaiyiPicEntity();
|
baiyiPicEntity.setMnNo(mnNo);
|
baiyiPicEntity.setOrder(order);
|
baiyiPicEntity.setDeviceId(deviceId);
|
baiyiPicEntity.setObTime(obTime);
|
baiyiPicEntity.setObDate(obDate);
|
baiyiPicEntity.setReceiveType(receiveType);
|
baiyiPicEntity.setStationId(stationId);
|
baiyiPicEntity.setStationName(stationName);
|
baiyiPicEntity.setDeviceName(deviceName);
|
|
baiyiPicEntity.setCreatedAt(new Date());
|
|
|
return baiyiPicEntity;
|
}
|
|
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();
|
}
|
}
|