shenyijian
2024-12-02 eed72349910ec181532e5f7ce13677788a769d21
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileHandler.java
New file
@@ -0,0 +1,325 @@
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.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.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";
    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 {
      // Authorization验证
      boolean isRequestValid = isValidHttpRequest(ctx, fullRequest);
      if (!isRequestValid) {
         HttpResponseUtils.sendResponseJson2(ctx, HttpResponseStatus.BAD_REQUEST, "验证失败",null);
         return ;
      }
      // 请求路径验证
      String urlyz = urlyz(ctx, fullRequest);
      if (UPLOAD_FILE_URL.equals(urlyz)) { //传图片
         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;
               System.out.println("getName:::"+attribute.getName());
               System.out.println("getValue:::"+attribute.getValue());
               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());
         // 保存入库xfByPic
         baiyiPicService.inserXfPicUrl(xfByPic);
      } else if(UPLOAD_DATA_URL.equals(urlyz)) { //传数据
         HttpPostMultipartRequestDecoder test = new HttpPostMultipartRequestDecoder(fullRequest);
         List<InterfaceHttpData> bodyHttpDatas = test.getBodyHttpDatas();
         for (InterfaceHttpData item : bodyHttpDatas ) {
            if (  item instanceof Attribute){
//               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);
            } else if (item instanceof FileUpload) {
               System.out.println("Attribute:::"+item.getName());
            }
         }
      } else {
         HttpResponseUtils.sendResponseJson2(ctx, HttpResponseStatus.BAD_REQUEST, "验证失败",null);
         return ;
      }
      HttpResponseUtils.sendResponseJson(ctx, HttpResponseStatus.OK, "上传成功");
    }
   // 请求路径验证
   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;
         }
      } 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();
    }
}