springboot借助sftp将文件上传到远端的nginx服务器中,然后将文件路径存进数据库

先看效果
在这里插入图片描述
demo比较粗糙,忽略其中的命名,图片也是随便找的。

这里的上传文件使用的commons-fileupload工具包实现文件上传。
pom文件的部分依赖如下:

<!-- 文件上传组件 -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.22</version>
        </dependency>
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.3</version>
        </dependency>

Controller层

@Controller
@RequestMapping(value = "/restaurantApi")
@Slf4j
public class UploadController {
    //注入业务对象
    @Resource
    private UploadService uploadService;

    @Resource
    private NginxService nginxService;

    /**
     * 可上传图片、视频,只需在nginx配置中配置可识别的尾缀
     */
    @PostMapping("/upload")
    public String pictureUpload(String name, double prices, String description,@RequestParam(value = "file") MultipartFile pictureFileURL) {
        long begin = System.currentTimeMillis();
        String json = "";
        try {
            //上传至nginx服务器
            Object result = nginxService.uploadPicture(pictureFileURL);
            //在数据库中插入一条信息
            uploadService.addFood(new Food(name, prices, description, (String)result));
            // 浏览器擅长处理json格式的字符串,为了减少因为浏览器内核不同导致的bug,建议用json
            json = new ObjectMapper().writeValueAsString(result);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        log.info("定时任务结束,共耗时:[" + (end-begin) + "]毫秒");
        return json;
    }
}

实体类定义如下:

//Lombok插件使用注释
@Data                              // get,set
//@NoArgsConstructor                 //无参构造
@AllArgsConstructor                //有参构造
public class Food {
    private String name;
    private double prices;
    private String description;
    private String pictureFileURL;
}

服务层NginxService跟uploadService,前者是上传至图片服务器相关业务,后者是数据库相关业务。

@Service
@Slf4j
public class NginxServiceImpl implements NginxService {
    @Override
    public Object uploadPicture(MultipartFile uploadFile) {
        //1、给上传的图片生成新的文件名
        //1.1获取原始文件名
        String oldName = uploadFile.getOriginalFilename();
        //1.2使用IDUtils工具类生成新的文件名,新文件名 = newName + 文件后缀
        String newName = IDUtils.getImageName();
        assert oldName != null;
        newName = newName + oldName.substring(oldName.lastIndexOf("."));

        //2、把图片上传到图片服务器
        //2.1获取上传的io流
        InputStream input = null;
        try {
            input = uploadFile.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }


        //2.2调用FtpUtil工具类进行上传
        return FtpUtil.putImages(input,newName);
    }
}
@Service
@Transactional
public class UploadServiceImpl  implements UploadService {
    @Resource
    private UploadMapper uploadMapper;

    @Override
    public int addFood(Food food) {
        return uploadMapper.insertFood(food);
    }
}

两个工具类,一个是FtpUtil,一个是随机生成图片名字的IDUtil

@Component
public class FtpUtil {
    private static Logger logger = LoggerFactory.getLogger(FtpUtil.class);

    /**
     * ftp服务器ip地址
     */
    private static String host;

    @Value("${ftp.host}")
    public void setHost(String val){
        FtpUtil.host = val;
    }

    /**
     * 端口
     */
    private static int port;

    @Value("${ftp.port}")
    public void setPort(int val){
        FtpUtil.port = val;
    }

    /**
     * 用户名
     */
    private static String userName;

    @Value("${ftp.userName}")
    public void setUserName(String val){
        FtpUtil.userName = val;
    }

    /**
     * 密码
     */
    private static String password;

    @Value("${ftp.password}")
    public void setPassword(String val){
        FtpUtil.password = val;
    }

    /**
     * 存放图片的根目录
     */
    private static String rootPath;

    @Value("${ftp.rootPath}")
    public void setRootPath(String val){
        FtpUtil.rootPath = val;
    }

    /**
     * 存放图片的路径
     */
    private static String imgUrl;

    @Value("${ftp.img.url}")
    public void setImgUrl(String val){
        FtpUtil.imgUrl = val;
    }

    /**
     * 获取连接
     */
    private static ChannelSftp getChannel() throws Exception{
        JSch jsch = new JSch();

        //->ssh root@host:port
        Session sshSession = jsch.getSession(userName,host,port);
        //密码
        sshSession.setPassword(password);

        Properties sshConfig = new Properties();
        sshConfig.put("StrictHostKeyChecking", "no");
        sshSession.setConfig(sshConfig);
        sshSession.connect();

        Channel channel = sshSession.openChannel("sftp");
        channel.connect();

        return (ChannelSftp) channel;
    }

    /**
     * ftp上传图片
     * @param inputStream 图片io流
     * @param imagesName 图片名称
     * @return urlStr 图片的存放路径
     */
    public static String putImages(InputStream inputStream,String imagesName){
        try {
            ChannelSftp sftp = getChannel();
            String path = rootPath + "/";

            //上传文件
            sftp.put(inputStream, path + imagesName);
            logger.info("上传成功!");
            sftp.quit();
            sftp.exit();

            //处理返回的路径
            String resultFile;
            resultFile = imgUrl + imagesName;

            return resultFile;

        } catch (Exception e) {
            logger.error("上传失败:" + e.getMessage());
        }
        return "";
    }

    /**
     * 创建目录
     */
    private static void createDir(String path,ChannelSftp sftp) throws SftpException {
        String[] folders = path.split("/");
        sftp.cd("/");
        for ( String folder : folders ) {
            if ( folder.length() > 0 ) {
                try {
                    sftp.cd( folder );
                }catch ( SftpException e ) {
                    sftp.mkdir( folder );
                    sftp.cd( folder );
                }
            }
        }
    }

    /**
     * 删除图片
     */
    public static void delImages(String imagesName){
        try {
            ChannelSftp sftp = getChannel();
            String path = rootPath + imagesName;
            sftp.rm(path);
            sftp.quit();
            sftp.exit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
public class IDUtils {

    /**
     * 生成随机图片名
     */
    public static String getImageName() {
        //取当前时间的长整形值包含毫秒
        long millis = System.currentTimeMillis();
        //加上三位随机数
        Random random = new Random();
        int end3 = random.nextInt(999);
        //如果不足三位前面补0
        String str = millis + String.format("%03d", end3);

        return str;
    }

}

mapper.xml

<?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="com.liu.uploadToNginx.dao.UploadMapper">
    <!-- 添加活动信息 -->
    <insert id="insertFood" parameterType="com.liu.uploadToNginx.domain.Food">
        INSERT INTO Food(name, prices, description, pictureFileURL)
        VALUES (#{name}, #{prices}, #{description}, #{pictureFileURL})
    </insert>
</mapper>

配置类

spring.datasource.url=jdbc:mysql://ip:3306/restaurant?useSSL=false&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss

mybatis.type-aliases-package=com.liu.uploadToNginx.domain
mybatis.mapper-locations=classpath:mapper/*.xml

ftp:
  host: 自己服务器ip
  userName: 服务器账号
  password: 服务器密码
  port: 22
  rootPath: /usr/local/nginx/img
  img:
    url: http://ip:80/

这里用postman测试接口
在这里插入图片描述
在这里插入图片描述
nginx.conf配置改一下就可访问了
在这里插入图片描述
demo地址如下:
https://gitee.com/liuyufu828/upload-to-nginx

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Irons_one

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值