zhanghua
2022-09-10 fa10620c874c944f4b37ce15a6782d3d08d2a8da
文件上传接口
3个文件已修改
5个文件已添加
507 ■■■■■ 已修改文件
pom.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server.sh 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/dto/media/Media.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/dto/media/PictureZoomParameter.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-common/src/main/java/com/ycl/utils/MediaFileUtil.java 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-platform/src/main/java/com/ycl/controller/FileController.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-platform/src/main/resources/application-dev.yml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ycl-platform/src/main/resources/application-pro.yml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -2,6 +2,18 @@
<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">
    <modelVersion>4.0.0</modelVersion>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>16</source>
                    <target>16</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
@@ -101,6 +113,13 @@
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.github.tobato/fastdfs-client -->
        <dependency>
            <groupId>com.github.tobato</groupId>
            <artifactId>fastdfs-client</artifactId>
            <version>1.27.2</version>
        </dependency>
        <!--Hutool Java工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
server.sh
New file
@@ -0,0 +1,95 @@
#!/bin/bash
#定义服务数组
serviceArr=(ycl)
#当前路径
rootPath=$(pwd)
#输入操作方式
read -p "请输入操作方式对应的序号:
1.start
2.stop
-> " action
echo ----------------------------------------------------------------------------------
#输入操作服务
read -p "请输入需要操作的服务对应的序号,请以空格分隔:
1.ycl
-> "
servers=$REPLY
echo ----------------------------------------------------------------------------------
#判断操作
if [ "$action" -eq 1 ];then
    read -p "请输入启动环境参数(如不指定,默认为开发环境):
dev-开发环境
prod-生产环境
test-本地测试环境
onlinetest-线上测试环境
-> " env
echo ----------------------------------------------------------------------------------
    if [ -n "$env" ];then
        envConfig="--spring.profiles.active="${env}
    fi
    for i in $servers
    do
        if [ $i -gt 1 ];then
            echo 输入的服务序号过大
        elif [ $i -lt 1 ];then
                echo 输入的服务序号过小
        else
            i=$(($i-1))
            echo 正在启动服务 ${serviceArr[$i]}
            cd $rootPath/${serviceArr[$i]}
            # java启动参数 $startConfig
            #-Xms128m 最小堆
            #-Xmx256m 最大堆 此值可以设置与-Xms相同,以避免每次垃圾回收完成后JVM重新分配内存
            #-Xmn2g 年轻代
            #-Xss128k 线程堆大小a
            #BackManager配置
            if [[ $serviceArr[$i] =~ "ycl" ]];then
                startConfig="-Xms400m -Xmx400m"
            else
                startConfig="-Xms400m -Xmx400m"
            fi
            echo 在路径 $(pwd) 下
            echo 执行 nohup java $startConfig -jar *.jar $envconfig "&"
            nohup java $startConfig -jar *.jar $envConfig &
            pid=$(ps -ef|grep -i ${serviceArr[$i]}|grep .jar|grep -v grep|awk '{print $2}')
            if [ -n "$pid" ];then
                echo 启动服务 ${serviceArr[$i]} 成功,进程ID为: $pid
            else
                echo 启动服务 ${serviceArr[$i]} 失败,执行的命令为:
                echo nohup java $startConfig -jar *.jar $envconfig &
            fi
            echo ----------------------------------------------------------------------------------
        fi
    done
elif [ "$action" -eq 2 ];then
    for i in $servers
    do
        if [ $i -gt 1 ];then
            echo 输入的服务序号过大
        elif [ $i -lt 1 ];then
            echo 输入的服务序号过小
        else
            i=$(($i-1))
            pid=$(ps -ef|grep -i ${serviceArr[$i]}|grep .jar|grep -v grep|awk '{print $2}')
            serverName=$(ps -ef|grep -i ${serviceArr[$i]}|grep .jar|grep -v grep|awk '{print $12}')
            if [ -n "$pid" ];then
                echo 关闭服务 ${serviceArr[$i]} 的进程ID为: $pid
                echo 关闭服务 ${serviceArr[$i]} 的jar包名为: $serverName
                kill -9 $pid
                result=$(ps -ef|grep $pid|grep -v grep)
                if [ -n "$result" ];then
                    echo 关闭服务成功!
                else
                    echo 关闭服务失败! 查询到的进程为:
                    echo $result
                    echo 请重新尝试!
                fi
            else
                echo 未启动服务 ${serviceArr[$i]}
            fi
            echo ----------------------------------------------------------------------------------
        fi
    done
else
    echo 输入的操作方式有误,请重新执行脚本!
fi
ycl-common/src/main/java/com/ycl/dto/media/Media.java
New file
@@ -0,0 +1,20 @@
package com.ycl.dto.media;
import lombok.Data;
@Data
public class Media {
    private String type;//类型
    private String def; //视频默认图片
    private String url1; //小
    private String url2; //中
    private String url3;//大
    private String url4; //最大(暂时不使用)
    private Integer sort;//集合中的排序
}
ycl-common/src/main/java/com/ycl/dto/media/PictureZoomParameter.java
New file
@@ -0,0 +1,29 @@
package com.ycl.dto.media;
import lombok.Data;
/**
 * 图片缩放参数
 */
@Data
public class PictureZoomParameter {
    public static final PictureZoomParameter getBoardPar(){
        PictureZoomParameter par =new PictureZoomParameter();
        par.setWidth1(300);
        par.setWidth2(600);
        par.setWidth3(1200);
        return  par;
    }
    private Integer width1;
    private Integer width2;
    private Integer width3;
    private Integer width4;
}
ycl-common/src/main/java/com/ycl/utils/MediaFileUtil.java
New file
@@ -0,0 +1,259 @@
package com.ycl.utils;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.domain.upload.FastImageFile;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.ycl.dto.media.PictureZoomParameter;
import com.ycl.dto.media.Media;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.awt.image.BufferedImage;
import java.io.*;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.regex.Pattern;
@Component
public class MediaFileUtil {
    private static MediaFileUtil self;
    @Value("${fdfs.groupName}")
    private String groupName;
    @PostConstruct
    private void init() {
        self = this;
    }
    @Autowired
    private FastFileStorageClient storageClient;
    private static final Pattern videoPattern = Pattern.compile("((mp4|flv|avi|rm|rmvb|wmv)(jpg|png|gif|bmp))");
    @Value("${cfg.res}")
    private String rootPath;
    private final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMM");
    public MediaFileUtil() throws IOException {
    }
    public static String uploadImage(InputStream in) throws IOException {
        return self.storageClient.uploadImage(new FastImageFile(in, in.available(), "jpg", null)).getFullPath();
    }
    public static String uploadImage(File file) throws IOException {
        FileInputStream in = new FileInputStream(file);
        return self.storageClient.uploadImage(new FastImageFile(in, in.available(), "jpg", null)).getFullPath();
    }
    /**
     * 判断文件类型
     *
     * @param fileName
     * @return
     */
    public Short getType(String fileName) {
        String ext = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
        if (".jpg".equals(ext) || ".jpeg".equals(ext) || ".png".equals(ext) || ".gif".equals(ext) || ".bmp".equals(ext)) {
            return 1;
        } else if (".mp4".equals(ext) || ".avi".equals(ext) || ".flv".equals(ext) || ".rm".equals(ext) || ".wmv".equals(ext)) {
            return 2;
        } else {
            return 0;
        }
    }
    public Media save(MultipartFile file, PictureZoomParameter zoomPar) throws Exception {
        String[] fs = file.getOriginalFilename().split("\\.");
        String ext = fs[fs.length - 1];
        switch (this.getType(file.getOriginalFilename())) {
            case 1:
                return this.savePicture(file, ext, zoomPar);
            case 2:
                return this.saveVideo(file, ext);
            default:
                return new Media();
        }
    }
    public Media savePicture(MultipartFile file, String ext, PictureZoomParameter zoomPar) throws Exception {
        ByteArrayOutputStream outs = new ByteArrayOutputStream();
        Media media = new Media();
        media.setType(ext);
        String path = null;
        if (zoomPar.getWidth1() != null && zoomPar.getWidth1() > 0) {
            path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth1());
            media.setUrl1(path);
        }
        if (zoomPar.getWidth2() != null && zoomPar.getWidth2() > 0) {
            path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth2());
            media.setUrl2(path);
        }
        if (zoomPar.getWidth3() != null && zoomPar.getWidth3() > 0) {
            path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth3());
            media.setUrl3(path);
        }
        // width4为原图
        path = this.thumbAndStorageOfFile(file, ext, zoomPar.getWidth4());
        media.setUrl4(path);
        return media;
    }
    /**
     * 保存视频文件
     *
     * @param file
     * @param ext
     * @return
     * @throws Exception
     */
    public Media saveVideo(MultipartFile file, String ext) throws Exception {
//        StorePath sp = storageClient.uploadFile(file.getInputStream(), file.getSize(), ext, null);
        StorePath sp = storageClient.uploadFile(groupName, file.getInputStream(), file.getSize(), ext);
        Media media = new Media();
        media.setType(ext);
        media.setUrl1(sp.getFullPath());
        return media;
    }
    /**
     * 删除一个文件
     *
     * @param rootPath
     */
    public void removeFile(String rootPath) {
        storageClient.deleteFile(rootPath);
    }
    public void removeMedia(Media media) {
        if (!StringUtils.isEmpty(media.getUrl1())) {
            storageClient.deleteFile(media.getUrl1());
        }
        if (!StringUtils.isEmpty(media.getUrl2())) {
            storageClient.deleteFile(media.getUrl2());
        }
        if (!StringUtils.isEmpty(media.getUrl3())) {
            storageClient.deleteFile(media.getUrl3());
        }
        if (!StringUtils.isEmpty(media.getUrl4())) {
            storageClient.deleteFile(media.getUrl4());
        }
    }
    public void removeMedias(List<Media> medias) {
        if (medias != null) {
            for (Media m : medias) {
                if (!StringUtils.isEmpty(m.getUrl1())) {
                    storageClient.deleteFile(m.getUrl1());
                }
                if (!StringUtils.isEmpty(m.getUrl2())) {
                    storageClient.deleteFile(m.getUrl2());
                }
                if (!StringUtils.isEmpty(m.getUrl3())) {
                    storageClient.deleteFile(m.getUrl3());
                }
                if (!StringUtils.isEmpty(m.getUrl4())) {
                    storageClient.deleteFile(m.getUrl4());
                }
            }
        }
    }
    /**
     * 判断文件是否存在
     *
     * @param url
     * @return
     */
    public Boolean isEmpty(String url) {
        return true;
    }
    /**
     * 缩放并且上传
     *
     * @param in
     * @param ext
     * @param width
     * @return
     * @throws Exception
     */
    private String thumbAndStorage(InputStream in, String ext, Integer width) throws Exception {
        Thumbnails.Builder fileBuilder = Thumbnails.of(in).scale(1.0).outputQuality(1.0);
        BufferedImage src = fileBuilder.asBufferedImage();
        Integer w = src.getWidth(null);
        Integer destWidth = width > w ? w : width;
        ByteArrayOutputStream bouts = new ByteArrayOutputStream();
        Thumbnails.of(in).width(destWidth).toOutputStream(bouts);
        InputStream ins = this.out2In(bouts);
        StorePath sp = storageClient.uploadFile(groupName, ins, bouts.size(), ext);
//        StorePath sp = storageClient.uploadFile(ins, bouts.size(), ext, null);
        bouts.close();
        ins.close();
        return sp.getFullPath();
    }
    private String thumbAndStorageOfFile(MultipartFile file, String ext, Integer width) throws Exception {
        Thumbnails.Builder fileBuilder = Thumbnails.of(file.getInputStream()).scale(1.0).outputQuality(1.0);
        BufferedImage src = fileBuilder.asBufferedImage();
        Integer w = src.getWidth(null);
        Integer destWidth = width == null || width > w ? w : width;
        ByteArrayOutputStream bouts = new ByteArrayOutputStream();
        Thumbnails.of(file.getInputStream()).width(destWidth).toOutputStream(bouts);
        InputStream ins = this.out2In(bouts);
        StorePath sp = storageClient.uploadFile(groupName, ins, bouts.size(), ext);
//        StorePath sp = storageClient.uploadFile(ins, bouts.size(), ext, null);
        bouts.close();
        ins.close();
        return sp.getFullPath();
    }
    /**
     * 输出流转输入流
     *
     * @param outs
     * @return
     * @throws Exception
     */
    private InputStream out2In(ByteArrayOutputStream outs) throws Exception {
        InputStream ins = new ByteArrayInputStream(outs.toByteArray());
        return ins;
    }
}
ycl-platform/src/main/java/com/ycl/controller/FileController.java
New file
@@ -0,0 +1,53 @@
package com.ycl.controller;
import com.ycl.api.CommonResult;
import com.ycl.dto.media.Media;
import com.ycl.dto.media.PictureZoomParameter;
import com.ycl.utils.MediaFileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@RestController
@Api(tags = "文件上传")
@RequestMapping("/file")
public class FileController {
    @Autowired
    private MediaFileUtil mediaFileUtil;
    /**
     * 上传图片
     *
     * @param file
     * @return
     */
    @ApiOperation("上传图片")
    @RequestMapping(value = "/medias", method = RequestMethod.POST)
    public CommonResult<Media> mediaUpload(@RequestParam("file") MultipartFile file) {
        try {
            PictureZoomParameter zoomPar = PictureZoomParameter.getBoardPar();
            Media res = mediaFileUtil.save(file, zoomPar);
            return CommonResult.success(res, "ok");
        } catch (Exception e) {
            return CommonResult.failed("fail!");
        }
    }
    @ApiOperation("删除图片")
    @RequestMapping(value = "media/delete", method = RequestMethod.DELETE)
    public CommonResult<Boolean> delete(@RequestBody Media media) {
        try {
            mediaFileUtil.removeMedia(media);
            return CommonResult.success(true, "ok");
        } catch (Exception e) {
            return CommonResult.failed("fail!");
        }
    }
}
ycl-platform/src/main/resources/application-dev.yml
@@ -1,10 +1,25 @@
server:
  port: 8081
  port: 8082
  tomcat:
    uri-encoding: UTF-8
  servlet:
    context-path: /sccg
    compression: true
fdfs:
  groupName: sczhzf
  soTimeout: 1500
  connectTimeout: 600
  trackerList:            #TrackerList参数,支持多个
    - 140.143.152.226:22122
cfg:
  res: d://resources
  media-res: 140.143.152.226/media/
  snow-flake:
    datacenterId: 1
    machineId: 1
spring:
  redis:
    database: 0
ycl-platform/src/main/resources/application-pro.yml
@@ -5,6 +5,21 @@
  servlet:
    context-path: /sccg
    compression: true
fdfs:
  groupName: sczhzf
  soTimeout: 1500
  connectTimeout: 600
  trackerList:            #TrackerList参数,支持多个
    - 140.143.152.226:22122
    -
cfg:
  res: d://resources
  media-res: 140.143.152.226/media/
  snow-flake:
    datacenterId: 1
    machineId: 1
spring:
  redis:
    database: 0