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 { 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 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 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 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(); } }