ke
2024-11-26 0f0cd8abae38a873a9a97bd8bda019a197df2637
白蚁新模块。图片上传接口
2 files modified
21 files added
1017 ■■■■■ changed files
skjcmanager/skjcmanager-service-api/pom.xml 1 ●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service-api/skjcmanager-by-api/pom.xml 18 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/pom.xml 5 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/pom.xml 132 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/ByApplication.java 27 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileHandler.java 269 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileInitialzer.java 74 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileServer.java 62 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/config/NettyHttpConfig.java 21 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/controller/NettyHttpService.java 28 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/BeenUtils.java 70 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/ExceptionUtils.java 18 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/HttpResponseUtils.java 52 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/UriUtils.java 55 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/entity/BaiyiPicEntity.java 47 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/mapper/BaiyiPicMapper.java 10 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/mapper/BaiyiPicMapper.xml 18 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/service/BaiyiPicService.java 8 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/service/impl/BaiyiPicServiceImpl.java 19 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/webInterface/controller/test.java 11 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/resources/application-dev.yml 24 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/resources/application-prod.yml 24 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/resources/application-test.yml 24 ●●●●● patch | view | raw | blame | history
skjcmanager/skjcmanager-service-api/pom.xml
@@ -26,6 +26,7 @@
        <module>skjcmanager-xxljob-api</module>
        <module>skjcmanager-nky-api</module>
        <module>skjcmanager-pwd-api</module>
        <module>skjcmanager-by-api</module>
    </modules>
    <dependencies>
skjcmanager/skjcmanager-service-api/skjcmanager-by-api/pom.xml
New file
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>skjcmanager-service-api</artifactId>
        <groupId>cn.gistack</groupId>
        <version>3.0.1.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>skjcmanager-by-api</artifactId>
    <name>${project.artifactId}</name>
    <version>${bladex.project.version}</version>
    <packaging>jar</packaging>
</project>
skjcmanager/skjcmanager-service/pom.xml
@@ -26,6 +26,7 @@
        <module>skjcmanager-xxljob</module>
        <module>skjcmanager-nky</module>
        <module>skjcmanager-pwd</module>
        <module>skjcmanager-by</module>
    </modules>
    <dependencies>
@@ -56,6 +57,10 @@
            <artifactId>skjcmanager-scope-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-core-cloud</artifactId>
        </dependency>
    </dependencies>
</project>
skjcmanager/skjcmanager-service/skjcmanager-by/pom.xml
New file
@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>skjcmanager-service</artifactId>
        <groupId>cn.gistack</groupId>
        <version>3.0.1.RELEASE</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>skjcmanager-by</artifactId>
    <name>${project.artifactId}</name>
    <version>${bladex.project.version}</version>
    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-core-boot</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-starter-swagger</artifactId>
        </dependency>
        <!--hk Hikvision AI 安全认证库-->
        <dependency>
            <groupId>com.hikvision.ga</groupId>
            <artifactId>artemis-http-client</artifactId>
            <version>1.1.3</version>
        </dependency>
        <!--引入 sms 短信 sdk -->
        <!--开启多数据源-->
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-core-auto</artifactId>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-by-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-flow-api</artifactId>
            <version>3.0.1.RELEASE</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-user-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-alerts-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-nky-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-pwd-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-system-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springblade</groupId>
            <artifactId>blade-starter-excel</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.gistack</groupId>
            <artifactId>skjcmanager-resource-api</artifactId>
            <version>3.0.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.25</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-mock</artifactId>
            <version>2.0.8</version>
        </dependency>
        <dependency>
            <groupId>io.netty</groupId>
            <artifactId>netty-all</artifactId>
            <version>4.1.50.Final</version>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <configuration>
                    <username>${docker.username}</username>
                    <password>${docker.password}</password>
                    <repository>${docker.registry.url}/${docker.namespace}/${project.artifactId}</repository>
                    <tag>${project.version}</tag>
                    <useMavenSettingsForAuth>true</useMavenSettingsForAuth>
                    <buildArgs>
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                    <skip>false</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/ByApplication.java
New file
@@ -0,0 +1,27 @@
package cn.gistack.by;
import org.mybatis.spring.annotation.MapperScan;
import org.springblade.core.cloud.client.BladeCloudApplication;
import org.springblade.core.launch.BladeApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@BladeCloudApplication
@EnableFeignClients({"cn.gistack"})
@MapperScan({"org.springblade.**.mapper.**","cn.gistack.by.**.mapper.**"})
public class ByApplication {
    public static void main(String[] args) {
        BladeApplication.run("blade-by", ByApplication.class, args);
    }
//    @Bean
//    public RestTemplate restTemplate(RestTemplateBuilder builder){
//        return builder.build();
//    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileHandler.java
New file
@@ -0,0 +1,269 @@
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 {
        boolean isRequestValid = isValidHttpRequest(ctx, fullRequest);
        if (!isRequestValid) {
            log.warn("Discard invalid 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);
        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);
        // 请求参数放入实体中
        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());
            // 密码校验
            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();
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileInitialzer.java
New file
@@ -0,0 +1,74 @@
package cn.gistack.by.nettyUpload;
import cn.gistack.by.nettyUpload.config.NettyHttpConfig;
import cn.gistack.by.picUpload.service.BaiyiPicService;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpContentCompressor;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpRequestDecoder;
import io.netty.handler.codec.http.HttpResponseEncoder;
import io.netty.util.concurrent.DefaultEventExecutorGroup;
import io.netty.util.concurrent.EventExecutorGroup;
import io.netty.util.concurrent.RejectedExecutionHandler;
import io.netty.util.concurrent.SingleThreadEventExecutor;
import lombok.extern.slf4j.Slf4j;
import cn.gistack.resource.feign.IOssClient;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.concurrent.ThreadFactory;
/**
 *
 * @author chenhaijian
 * @date 2020-05-21 14:42
 */
@Slf4j
public class HttpUploadFileInitialzer extends ChannelInitializer<SocketChannel> {
    /**
     * 所有的工作线程的线程池。
     */
    private static EventExecutorGroup executorGroup = null;
    private NettyHttpConfig nettyHttpConfig;
    private  IOssClient iOssClient;
    private BaiyiPicService baiyiPicService;
    public HttpUploadFileInitialzer(NettyHttpConfig nettyHttpConfig,IOssClient iOssClient,BaiyiPicService baiyiPicService) {
        this.nettyHttpConfig = nettyHttpConfig;
        this.iOssClient = iOssClient;
        this.baiyiPicService = baiyiPicService;
        if (executorGroup == null) {
            ThreadFactory threadFactory = (new ThreadFactoryBuilder()).setNameFormat("netty-business-%d")
                .setDaemon(false).build();
            executorGroup = new DefaultEventExecutorGroup(nettyHttpConfig.getBusinessThreadsCoreNum(), threadFactory,
                nettyHttpConfig.getBusinessThreadsQueueCapacity(),
                new RejectedExecutionHandler() {
                    @Override
                    public void rejected(Runnable runnable, SingleThreadEventExecutor singleThreadEventExecutor) {
                        log.error("Server will discard the runnale {}.", runnable.toString());
                        singleThreadEventExecutor.shutdownGracefully();
                    }
                });
        }
    }
    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline pipeline = ch.pipeline();
        pipeline.addLast("decoder", new HttpRequestDecoder());
        pipeline.addLast("encoder", new HttpResponseEncoder());
        pipeline.addLast(new HttpContentCompressor());
        // 聚合器,负责将http聚合成完整的消息,而不是原始的多个部分
        pipeline.addLast(new HttpObjectAggregator(nettyHttpConfig.getMaxContentLength()));
        pipeline.addLast(executorGroup, "httpUploadFileHandler", new HttpUploadFileHandler(nettyHttpConfig,iOssClient,baiyiPicService));
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/HttpUploadFileServer.java
New file
@@ -0,0 +1,62 @@
package cn.gistack.by.nettyUpload;
import cn.gistack.by.nettyUpload.config.NettyHttpConfig;
import cn.gistack.by.nettyUpload.utils.ExceptionUtils;
import cn.gistack.by.picUpload.service.BaiyiPicService;
import cn.gistack.resource.feign.IOssClient;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;
/**
 * netty实现http协议上传文件 服务端
 *
 * @author Kai.Shan
 * @date 2024-11-13 14:33
 */
@Slf4j
public class HttpUploadFileServer implements Runnable {
    private NettyHttpConfig nettyHttpConfig;
    private IOssClient iOssClient;
    private BaiyiPicService baiyiPicService;
    public HttpUploadFileServer(NettyHttpConfig nettyHttpConfig, IOssClient iOssClient ,BaiyiPicService baiyiPicService) {
        this.nettyHttpConfig = nettyHttpConfig;
        this.iOssClient = iOssClient;
        this.baiyiPicService = baiyiPicService;
    }
    public void run() {
        NioEventLoopGroup bossGroup = new NioEventLoopGroup(this.nettyHttpConfig.getBossGroupThreads());
        NioEventLoopGroup workerGroup = new NioEventLoopGroup(this.nettyHttpConfig.getWorkerGroupThreads());
        try {
            ServerBootstrap bootstrap = new ServerBootstrap();
            bootstrap.group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .option(ChannelOption.SO_BACKLOG, nettyHttpConfig.getNettySoBacklog())
                    .handler(new LoggingHandler(LogLevel.INFO))
                    .childHandler(new HttpUploadFileInitialzer(nettyHttpConfig,iOssClient,baiyiPicService));
            Channel channel = bootstrap.bind(this.nettyHttpConfig.getServerSocketIp(),this.nettyHttpConfig.getServerSocketPort())
                    .sync().channel();
            System.out.println("upload server started ....");
            channel.closeFuture().sync();
        } catch (Exception exception) {
            exception.printStackTrace();
            log.error(ExceptionUtils.getStackString(exception));
        } finally {
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
        }
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/config/NettyHttpConfig.java
New file
@@ -0,0 +1,21 @@
package cn.gistack.by.nettyUpload.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "netty.http")
@Component
@Data
public class NettyHttpConfig {
    private String serverSocketIp;
    private int serverSocketPort;
    private int bossGroupThreads;
    private int workerGroupThreads;
    private int maxContentLength;
    private int nettySoBacklog;
    private String fileSaveRootPath;
    private String fileUpPasswd;
    private int businessThreadsQueueCapacity;
    private int businessThreadsCoreNum;
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/controller/NettyHttpService.java
New file
@@ -0,0 +1,28 @@
package cn.gistack.by.nettyUpload.controller;
import cn.gistack.by.nettyUpload.HttpUploadFileServer;
import cn.gistack.by.nettyUpload.config.NettyHttpConfig;
import cn.gistack.by.picUpload.service.BaiyiPicService;
import cn.gistack.resource.feign.IOssClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.PostConstruct;
//@Component
@RestController
public class NettyHttpService {
    @Autowired
    private NettyHttpConfig nettyHttpConfig;
    @Autowired
    private IOssClient ossClient;
    @Autowired
    private BaiyiPicService baiyiPicService;
    @PostConstruct
    public void postConstructService() {
        new Thread(new HttpUploadFileServer(nettyHttpConfig,ossClient,baiyiPicService)).start();
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/BeenUtils.java
New file
@@ -0,0 +1,70 @@
package cn.gistack.by.nettyUpload.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class BeenUtils implements ApplicationContextAware {
    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        BeenUtils.applicationContext = applicationContext;
    }
    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        if (applicationContext == null){
            throw new RuntimeException("applicationContext注入失败");
        }
        return getApplicationContext().getBean(name);
    }
    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        if (applicationContext == null){
            throw new RuntimeException("applicationContext注入失败");
        }
        return getApplicationContext().getBean(clazz);
    }
    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        if (applicationContext == null){
            throw new RuntimeException("applicationContext注入失败");
        }
        return getApplicationContext().getBean(name, clazz);
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/ExceptionUtils.java
New file
@@ -0,0 +1,18 @@
package cn.gistack.by.nettyUpload.utils;
import java.io.PrintWriter;
import java.io.StringWriter;
public class ExceptionUtils {
    /**
     * 获取异常堆栈字符串。
     *
     * @param t {@link Throwable}
     * @return
     */
    public static String getStackString(Throwable t) {
        StringWriter sw  = new StringWriter();
        t.printStackTrace(new PrintWriter(sw, true));
        return  sw.getBuffer().toString();
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/HttpResponseUtils.java
New file
@@ -0,0 +1,52 @@
package cn.gistack.by.nettyUpload.utils;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.util.CharsetUtil;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
/**
 * response工具
 * @author chenhaijian
 * @date 2020-05-21 17:11
 */
public class HttpResponseUtils {
    /**
     * 向客户端发送消息提示
     * @param ctx
     * @param status
     */
    public static void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_1_1, status, Unpooled.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8));
        response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
    /**
     * 向客户端发送消息提示
     * @param ctx
     * @param status
     * @param message
     */
    public static void sendResponseJson(ChannelHandlerContext ctx, HttpResponseStatus status, String message) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("code", status.code());
        jsonObject.put("msg", message);
        FullHttpResponse response = new DefaultFullHttpResponse(
                HTTP_1_1, status, Unpooled.copiedBuffer(jsonObject.toJSONString(), CharsetUtil.UTF_8));
        response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8");
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/nettyUpload/utils/UriUtils.java
New file
@@ -0,0 +1,55 @@
package cn.gistack.by.nettyUpload.utils;
import io.netty.handler.codec.http.HttpRequest;
import org.apache.commons.lang3.StringUtils;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
/**
 * URI 工具类
 * @author chenhaijian
 * @date 2020-05-21 16:43
 */
public class UriUtils {
    /**
     * 获取HttpRequest中的uri封装成URI对象
     * @param httpRequest
     * @return
     * @throws URISyntaxException
     */
    public static URI getURI(HttpRequest httpRequest) throws URISyntaxException {
        return new URI(httpRequest.uri());
    }
    /**
     * 获取URI对象中的参数
     * @param uri
     * @return
     */
    public static Map<String, String> getQueryParams(URI uri) {
        Map<String, String> params = new HashMap<>();
        String query = uri.getQuery();
        if (StringUtils.isNotBlank(query)) {
            String[] paramsItems = query.split("&");
            for (String item : paramsItems) {
                String[] kv = item.split("=");
                params.put(kv[0], kv[1]);
            }
        }
        return params;
    }
    /**
     * 获取HttpRequest中的 query params
     * @param httpRequest
     * @return
     */
    public static Map<String, String> getQueryParams(HttpRequest httpRequest) throws URISyntaxException {
        URI uri = getURI(httpRequest);
        return getQueryParams(uri);
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/entity/BaiyiPicEntity.java
New file
@@ -0,0 +1,47 @@
package cn.gistack.by.picUpload.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.Date;
@Data
public class BaiyiPicEntity {
    @NotBlank(message = "设备编码不能为空")
    @ApiModelProperty("设备编码")
    private String mnNo;
    @NotBlank(message = "白蚁图片地址不能为空")
    @ApiModelProperty("白蚁图片地址")
    private String picUrl;
    @ApiModelProperty("白蚁图片状态")
    private Integer picStatus;
    @NotBlank(message = "白蚁设备安装的点位顺序不能为空")
    @ApiModelProperty("白蚁设备安装的点位顺序")
    private String order;
    @ApiModelProperty("创建时间")
    private Date createdAt;
    @NotBlank(message = "观测时间不能为空")
    @ApiModelProperty("观测时间")
    private String obTime;
    @NotBlank(message = "观测时间2不能为空")
    @ApiModelProperty("观测时间2")
    private Date obDate;
    @NotBlank(message = "中心站地址不能为空")
    @ApiModelProperty("中心站地址")
    private Integer stationId;
    @NotBlank(message = "站点名称不能为空")
    @ApiModelProperty("站点名称")
    private String stationName;
    @NotBlank(message = "设备id不能为空")
    @ApiModelProperty("设备id")
    private Integer deviceId;
    @NotBlank(message = "设备名称不能为空")
    @ApiModelProperty("设备名称")
    private String deviceName;
    @NotBlank(message = "接收类型不能为空")
    @ApiModelProperty("接收类型")
    private Integer receiveType;
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/mapper/BaiyiPicMapper.java
New file
@@ -0,0 +1,10 @@
package cn.gistack.by.picUpload.mapper;
import cn.gistack.by.picUpload.entity.BaiyiPicEntity;
import org.apache.ibatis.annotations.Param;
public interface BaiyiPicMapper {
    void inserpicData(@Param("item") BaiyiPicEntity entity);
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/mapper/BaiyiPicMapper.xml
New file
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.gistack.by.picUpload.mapper.BaiyiPicMapper">
    <insert id="inserpicData" >
        insert into
            SJZT_ODS."water_data_termites_pic"
            ("mn_no", "pic_url", "pic_status", "order", "created_at", "ob_time",
            "ob_date","station_id", "station_name", "device_id", "device_name",  "receive_type")
        VALUE
            (
             #{item.mnNo},#{item.picUrl},#{item.picStatus},#{item.order},#{item.createdAt},#{item.obTime},#{item.obDate},
            #{item.stationId},#{item.stationName},#{item.deviceId},#{item.deviceName},#{item.receiveType}
            )
    </insert>
</mapper>
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/service/BaiyiPicService.java
New file
@@ -0,0 +1,8 @@
package cn.gistack.by.picUpload.service;
import cn.gistack.by.picUpload.entity.BaiyiPicEntity;
public interface BaiyiPicService {
    void inserpicData(BaiyiPicEntity entity);
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/picUpload/service/impl/BaiyiPicServiceImpl.java
New file
@@ -0,0 +1,19 @@
package cn.gistack.by.picUpload.service.impl;
import cn.gistack.by.picUpload.entity.BaiyiPicEntity;
import cn.gistack.by.picUpload.mapper.BaiyiPicMapper;
import cn.gistack.by.picUpload.service.BaiyiPicService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class BaiyiPicServiceImpl implements BaiyiPicService {
    @Autowired
    private BaiyiPicMapper baiyiPicMapper;
    @Override
    public void inserpicData(BaiyiPicEntity entity) {
        baiyiPicMapper.inserpicData(entity);
    }
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/java/cn/gistack/by/webInterface/controller/test.java
New file
@@ -0,0 +1,11 @@
package cn.gistack.by.webInterface.controller;
import cn.gistack.by.nettyUpload.config.NettyHttpConfig;
import cn.gistack.resource.feign.IOssClient;
public class test {
    private NettyHttpConfig nettyHttpConfig;
    private  IOssClient iOssClient;
}
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/resources/application-dev.yml
New file
@@ -0,0 +1,24 @@
#服务器端口
server:
  port: 8190
#数据源配置
spring:
  datasource:
    url: ${blade.datasource.dev.ztznwh.url}
    username: ${blade.datasource.dev.ztznwh.username}
    password: ${blade.datasource.dev.ztznwh.password}
#netty配置
netty:
  http:
    server-socket-ip: 127.0.0.1
    server-socket-port: 8003
    worker_group_threads: 32
    boss_group_threads: 0
    netty_so_backlog: 4096
    max_content_length: 10485760
    file_save_root_path: C:/Users/kelu/Desktop/111
    file_up_passwd: fireinthehole
    business_threads_queue_capacity: 10000
    business_threads_core_num: 200
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/resources/application-prod.yml
New file
@@ -0,0 +1,24 @@
#服务器端口
server:
  port: 8190
#数据源配置
spring:
  datasource:
    url: ${blade.datasource.dev.ztznwh.url}
    username: ${blade.datasource.dev.ztznwh.username}
    password: ${blade.datasource.dev.ztznwh.password}
#netty配置
netty:
  http:
    server-socket-ip: 127.0.0.1
    server-socket-port: 8003
    worker_group_threads: 32
    boss_group_threads: 0
    netty_so_backlog: 4096
    max_content_length: 10485760
    file_save_root_path: C:/Users/kelu/Desktop/111
    file_up_passwd: fireinthehole
    business_threads_queue_capacity: 10000
    business_threads_core_num: 200
skjcmanager/skjcmanager-service/skjcmanager-by/src/main/resources/application-test.yml
New file
@@ -0,0 +1,24 @@
#服务器端口
server:
  port: 8190
#数据源配置
spring:
  datasource:
    url: ${blade.datasource.dev.ztznwh.url}
    username: ${blade.datasource.dev.ztznwh.username}
    password: ${blade.datasource.dev.ztznwh.password}
#netty配置
netty:
  http:
    server-socket-ip: 127.0.0.1
    server-socket-port: 8003
    worker_group_threads: 32
    boss_group_threads: 0
    netty_so_backlog: 4096
    max_content_length: 10485760
    file_save_root_path: C:/Users/kelu/Desktop/111
    file_up_passwd: fireinthehole
    business_threads_queue_capacity: 10000
    business_threads_core_num: 200