感谢:Keepalived,和寄点以及网友分享的博客,以下是我整理的在
相關連接:
SpringCloud feign整合FtpClient连接池实现文件上传下载微服务以及遇到的坑。
maven创建springboot
一 首先搭建zddts-ftp文件服务连接池及服务:zddts-ftp 服务提供者pom依赖的jar包,springcloud依赖的全家桶此处不说明
<!--ftp文件上传-->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
<!--自定义连接池-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.4.2</version>
</dependency>
springboot启动类:
package com.zddts;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import javax.servlet.MultipartConfigElement;
@SpringBootApplication
public class ZddtsFtpApplication {
public static void main(String[] args) {
SpringApplication.run(ZddtsFtpApplication.class, args);
}
/**
* 文件上传配置
*
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 单个数据大小
factory.setMaxFileSize("20480KB"); // KB,MB
/// 总上传数据大小
factory.setMaxRequestSize("61440KB");
return factory.createMultipartConfig();
}
}
yml上配置ftp相关配置路径
接下来写连接池:
FtpClient工厂类:
package com.zddts.ftp.core;
import com.zddts.common.contants.ftp.FtpConstants;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.pool2.PooledObject;
import org.apache.commons.pool2.PooledObjectFactory;
import org.apache.commons.pool2.impl.DefaultPooledObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* 连接工厂
*/
@Component
public class FtpClientFactory implements PooledObjectFactory<FTPClient> {
@Autowired
FtpConfig ftpConfig;
//创建连接到池中
@Override
public PooledObject<FTPClient> makeObject() {
FTPClient ftpClient = new FTPClient();//创建客户端实例
return new DefaultPooledObject<FTPClient>(ftpClient);
}
//销毁连接,当连接池空闲数量达到上限时,调用此方法销毁连接
@Override
public void destroyObject(PooledObject<FTPClient> pooledObject) {
FTPClient ftpClient = pooledObject.getObject();
try {
ftpClient.logout();
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
} catch (IOException e) {
throw new RuntimeException("Could not disconnect from server.", e);
}
}
//链接状态检查
@Override
public boolean validateObject(PooledObject<FTPClient> pooledObject) {
FTPClient ftpClient = pooledObject.getObject();
try {
return ftpClient.sendNoOp();
} catch (IOException e) {
return false;
}
}
//初始化连接
@Override
public void activateObject(PooledObject<FTPClient> pooledObject) throws Exception {
FTPClient ftpClient = pooledObject.getObject();
ftpClient.connect(ftpConfig.getIp(), ftpConfig.getPort());
ftpClient.login(ftpConfig.getUserName(), ftpConfig.getPassWord());
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);//设置上传文件类型为二进制,否则将无法打开文件
// 开启服务器对UTF-8的支持,如果服务器支持就用UTF-8编码,否则就使用本地编码(GBK).
String LOCAL_CHARSET = "GBK";
if (FTPReply.isPositiveCompletion(ftpClient.sendCommand("OPTS UTF8", "ON"))) {
LOCAL_CHARSET = "UTF-8";
}
ftpClient.setControlEncoding(LOCAL_CHARSET);
}
//钝化连接,使链接变为可用状态
@Override
public void passivateObject(PooledObject<FTPClient> pooledObject) throws Exception {
FTPClient ftpClient = pooledObject.getObject();
try {
ftpClient.changeWorkingDirectory(FtpConstants.root);
ftpClient.logout();
if (ftpClient.isConnected()) {
ftpClient.disconnect();
}
} catch (IOException e) {
throw new RuntimeException("Could not disconnect from server.", e);
}
}
// 用于连接池中获取pool属性
public FtpConfig getConfig() {
return ftpConfig;
}
}
ftp yml配置实体类主要获取yml上ftp的相关配置(为了使用方便,我将部分配置分开定义在了常量类中FtpConstants ):
常量类FtpConstants ,当然这部分配置也可以在yml中配置:
package com.zddts.common.contants.ftp;
/**
* 说明:ftp配置类
* Created by luojie on 2019/04/16.
*/
public class FtpConstants {
public static final String root = "/";
public static int MaxTotal = 20;
public static final int MinIdel = 1;
public static final int MaxIdle = 8;
public static final int MaxWaitMillis = 3000;
/**
* 本地字符编码
*/
public static final String LOCAL_CHARSET = "UTF-8";
// FTP协议里面,规定文件名编码为iso-8859-1
public static final String SERVER_CHARSET = "iso-8859-1";
/**
* 各类文件存放规划路径目录名
*/
public static final String WORKDIR_PAT = "/upload/pat";//专利文件主目录
public static final String WORKDIR_PATDATAS = "datas"; // 专利资料存放路径
public static final String WORKDIR_PATIMGS = "imgs"; // 专利图片存放路径
public static final String WORKDIR_PATCONTRACT = "contract"; // 专利合同存放路径
public static final String WORKDIR_PATPAY_ORDER_C = "payorderforc"; // 专利付款单 (对公司)
public static final String WORKDIR_PATPAY_ORDER_P = "payorderforp"; // 专利付款单(对平台)
public static final String WORKDIR_PAT_PROTOCOL_S = "protocols"; // 卖方专利转让协议文件
public static final String WORKDIR_PAT_PROTOCOL_B = "protocolb"; //买方专利转让协议文件
/**
* 专利上传下载分类
*/
public static final String TYPE_PATDATAS = "1"; // 专利资料上传下载
public static final String TYPE_PATIMGS = "2"; // 专利图片上传下载
public static final String TYPE_PATCONTRACT = "3"; // 专利合同上传下载
public static final String TYPE_PATPAY_ORDER_C = "4"; // 专利付款单 (对公司)上传下载
public static final String TYPE_PATPAY_ORDER_P = "5"; // 专利付款单(对平台)上传下载
public static final String TYPE_PAT_PROTOCOL_S = "6"; // 卖方专利转让协议文件上传下载
public static final String TYPE_PAT_PROTOCOL_B = "7"; // 买方专利转让协议文件上传下载
/****
ftp.Host=192.168.xx.xx 本机ip
ftp.Port=21
ftp.UserName=root
ftp.PassWord=root
ftp.workDir=/images
ftp.encoding=utf-8
ftp.root=/
ftp.MaxTotal=100
ftp.MinIdel=2
ftp.MaxIdle=5
ftp.MaxWaitMillis=3000
**/
}package com.zddts.ftp.core;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* 说明:ftp配置
* Created by luojie on 2019/04/16.
*/
@Component
public class FtpConfig {
@Value("${ftp.username}")
private String userName;
@Value("${ftp.password}")
private String passWord;
@Value("${ftp.host}")
private String ip;
@Value("${ftp.port}")
private int port;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
FptPool创建:
package com.zddts.ftp.core;
import com.zddts.common.contants.ftp.FtpConstants;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* fileName:ftpPool
* description:FTP连接池
* 1.可以获取池中空闲链接
* 2.可以将链接归还到池中
* 3.当池中空闲链接不足时,可以创建链接
* author:luojie
* createTime:2019-03-16 9:59
*/
@Component
public class FtpPool {
FtpClientFactory factory;
private final GenericObjectPool<FTPClient> internalPool;
//初始化连接池
public FtpPool(@Autowired FtpClientFactory factory) {
this.factory = factory;
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(FtpConstants.MaxTotal);
poolConfig.setMinIdle(FtpConstants.MinIdel);
poolConfig.setMaxIdle(FtpConstants.MaxIdle);
poolConfig.setMaxWaitMillis(FtpConstants.MaxWaitMillis);
this.internalPool = new GenericObjectPool<FTPClient>(factory, poolConfig);
}
//从连接池中取连接
public FTPClient getFTPClient() {
try {
return internalPool.borrowObject();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
//将链接归还到连接池
public void returnFTPClient(FTPClient ftpClient) {
try {
internalPool.returnObject(ftpClient);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 销毁池子
*/
public void destroy() {
try {
internalPool.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
FtpUtil 操作类:
package com.zddts.ftp.core;
import com.zddts.common.contants.ftp.FtpConstants;
import com.zddts.common.utils.StringUtils;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import static com.zddts.common.contants.ftp.FtpConstants.LOCAL_CHARSET;
/**
* fileName:FTP工具类
* description:提供文件上传和下载
* author:luojie
* createTime:2019-03-16 8:55
*/
@Component
public class FtpUtil {
@Autowired
private ResourceLoader resourceLoader;
@Autowired
FtpPool pool;
@Autowired
FtpConfig ftpConfig;
/**
* Description: 向FTP服务器上传文件
*
* @param file 上传到FTP服务器上的文件
* @return 成功返回文件名,否则返回null
* @Version2.0
*/
public String[] upload(MultipartFile file, String workDirs) throws Exception {
FTPClient ftpClient = pool.getFTPClient();
//开始进行文件上传
String fileName = file.getOriginalFilename();
InputStream input = file.getInputStream();
String[] ret = new String[2];
if (input.available() == 0) {
ret[0] = "0";
ret[1] = "文件大小为0的文件请不要上传哦~~~";
return ret;
}
try {
ftpClient.setControlEncoding(FtpConstants.LOCAL_CHARSET);
String remote = new String(workDirs + "/" + fileName);
// 设置上传目录(没有则创建)
if (!createDir(workDirs, ftpClient)) {
ret[0] = "0";
ret[1] = "切入FTP目录失败:" + workDirs;
return ret;
}
// String remote = workDirs + "/" + fileName;
//上传用被动模式
// ftpClient.enterRemotePassiveMode();
ftpClient.enterLocalPassiveMode(); //设置被动模式
boolean result = ftpClient.storeFile(remote, input);//执行文件传输
if (!result) {//上传失败
ret[0] = "0";
ret[1] = "上传失败文件";
return ret;
}
} catch (Exception e) {
e.printStackTrace();
ret[0] = "0";
ret[1] = "上传失败";
return ret;
} finally {//关闭资源
input.close();
System.out.println("开始归还连接");
pool.returnFTPClient(ftpClient);//归还资源
}
ret[0] = "1";
ret[1] = fileName;
return ret;
}
/**
* Description: 从FTP服务器下载文件
*
* @param pathName FTP服务器中的文件名
* @param request 响应客户的响应体
* @Version1.0
*/
public ResponseEntity<byte[]> downLoad(String pathName, HttpServletRequest request) throws IOException {
FTPClient ftpClient = pool.getFTPClient();
String fileName = pathName.substring(pathName.lastIndexOf("/") + 1);
HttpHeaders headers = new HttpHeaders();
ResponseEntity<byte[]> entity = null;
InputStream in = null;
ByteArrayOutputStream byteOut = null;
try {
// pathName = new String(pathName.getBytes(FtpConstants.LOCAL_CHARSET),
// FtpConstants.SERVER_CHARSET);
//下载用本地模式
ftpClient.enterLocalPassiveMode();
in = ftpClient.retrieveFileStream(pathName);
//可以设置长度 在进行网络操作时往往出错,因为你调用available()方法时,
// 对发发送的数据可能还没有到达,你得到的count是0。
// byte[] bytes = new byte[in.available()];
int count = 0;
while (count == 0) {
count = in.available();
}
byte[] bytes = new byte[count];
byteOut = new ByteArrayOutputStream();
//此处大于0 不然死循环
int bufsize = 0;
while ((bufsize = in.read(bytes, 0, bytes.length)) > 0) {
byteOut.write(bytes, 0, bufsize);
}
bytes = byteOut.toByteArray();
//处理IE下载文件的中文名称乱码的问题
String header = request.getHeader("User-Agent").toUpperCase();
if (header.contains("MSIE") || header.contains("TRIDENT") || header.contains("EDGE")) {
fileName = URLEncoder.encode(fileName, LOCAL_CHARSET);
fileName = fileName.replace("+", "%20"); //IE下载文件名空格变+号问题
} else {
//不转码 下载的文件名中文会变成 "_"
fileName = new String(fileName.getBytes(), FtpConstants.SERVER_CHARSET);
}
headers.add("Content-Disposition", "attachment;filename=" + fileName);
headers.add("filename", fileName);
// headers.add("Access-Control-Expose-Headers", "Content-Disposition");
headers.add("Access-Control-Expose-Headers", "filename");
headers.setContentType(null);
entity = new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 注意要先关闭流 否则会出现卡死问题
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (byteOut != null) {
try {
byteOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("开始归还连接");
long bgn = System.currentTimeMillis();
pool.returnFTPClient(ftpClient);
long end = System.currentTimeMillis();
System.out.println("归还连接耗时:" + (end - bgn));
}
return entity;
}
/**
* Description: 从FTP服务器读取图片
*
* @param fileName 需要读取的文件名
* @return 返回文件对应的Entity
* @Version1.0
*/
public ResponseEntity show(String fileName, String workDir) {
String username = ftpConfig.getUserName();
String password = ftpConfig.getPassWord();
String host = ftpConfig.getIp();
//ftp://root:root@192.168.xx.xx/+fileName
return ResponseEntity.ok(resourceLoader.getResource("ftp://" + username + ":" + password + "@" + host + workDir + "/" + fileName));
}
/**
* 创建目录(有则切换目录,没有则创建目录)
*
* @param dir
* @return
*/
public boolean createDir(String dir, FTPClient ftpClient) {
if (StringUtils.nullOrBlank(dir)) {
return true;
}
String d;
try {
//目录编码,解决中文路径问题
d = new String(dir.toString().getBytes(LOCAL_CHARSET), "iso-8859-1");
//尝试切入目录
if (ftpClient.changeWorkingDirectory(d)) {
return true;
}
dir = StringUtils.trimStart(dir, "/");
dir = StringUtils.trimEnd(dir, "/");
String[] arr = dir.split("/");
StringBuffer sbfDir = new StringBuffer();
//循环生成子目录
for (String s : arr) {
sbfDir.append("/");
sbfDir.append(s);
//目录编码,解决中文路径问题
d = new String(sbfDir.toString().getBytes("GBK"), "iso-8859-1");
//尝试切入目录
if (ftpClient.changeWorkingDirectory(d))
continue;
if (!ftpClient.makeDirectory(d)) {
System.out.println("[失败]ftp创建目录:" + sbfDir.toString());
return false;
}
System.out.println("[成功]创建ftp目录:" + sbfDir.toString());
}
//将目录切换至指定路径
return ftpClient.changeWorkingDirectory(d);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}
以上整合ftp连接池完成,接下来就是Feign提供给其他服务接口FtpServerController :
package com.zddts.ftp.server.controller;
import com.zddts.common.utils.R;
import com.zddts.ftp.core.FtpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
/**
* 说明:
* Created by luojie on 2019/04/16.
*/
@RestController
@RequestMapping("/ftp/pturl")
public class FtpServerController {
//日志
private Logger log = LoggerFactory.getLogger(FtpServerController.class);
@Autowired
FtpUtil ftpUtil;
/**
* 上传
*
* @param file
* @param romte
* @return
* @throws Exception
*/
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R fileUpload(@RequestPart("file") MultipartFile file, @RequestParam("romte") String romte) throws Exception {
//上传
String filName = "";
try {
//上传
filName = ftpUtil.upload(file, romte);
} catch (Exception e) {
log.error("上传失败详情:" + e.getMessage());
return R.error("上传失败");
}
if (!"1".equals(filName)) {
return R.error("上传失败" + filName);
}
return R.ok("上传成功");
}
/**
* 下载
*
* @param romte
* @param request
* @throws Exception
*/
@RequestMapping(value = "/download")
public ResponseEntity<byte[]> download(String romte, HttpServletRequest request) throws Exception {
ResponseEntity<byte[]> rep = null;
try {
//下载
rep = ftpUtil.downLoad(romte, request);
} catch (Exception e) {
log.error("下载失败详情:" + e.getMessage());
}
return rep;
}
}
至此服务提供方代码已经写好!
接下来开始写服务消费方不:
yml 配置:只要涉及到服务间文件传输的都需要配置 也可以配置在启动类中(默认好像是10mb)zuul网关的也需要设置:
http:
multipart:
max-file-size: 20Mb # Max file size,默认1M
max-request-size: 2500Mb # Max request size,默认10M
addts-patmarket:pom中的依赖
<!-- Feign进行跨服务传递文件依赖 -->
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.0.3</version>
</dependency>
feign传输设置类告知对方传输文件类型:
若不配置会报如下错误:
Could not write request: no suitable HttpMessageConverter found for request type [org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile] and content type [multipart/form-data]
package com.zddts.patmarket.client;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Scope;
import javax.servlet.MultipartConfigElement;
/**
* 说明:文件上传下载 feign调用需要配置该文件
* Created by luojie on 2019/04/16.
*/
@Configuration
public class MultipartSupportConfig {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Bean
@Primary
@Scope("prototype")
public Encoder feignEncoder() {
return new SpringFormEncoder(new SpringEncoder(messageConverters));
}
@Bean
public feign.Logger.Level multipartLoggerLevel() {
return feign.Logger.Level.FULL;
}
/**
* 文件上传配置
*
* @return
*/
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
// 单个数据大小
factory.setMaxFileSize("20MB"); // KB,MB
/// 总上传数据大小
factory.setMaxRequestSize("2500MB");
return factory.createMultipartConfig();
}
}
接口类FtpServerClient api
package com.zddts.patmarket.client;
import com.zddts.common.utils.R;
import feign.codec.Encoder;
import feign.form.spring.SpringFormEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.support.SpringEncoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
/**
* 说明:
* Created by luojie on 2019/04/16.
*/
@FeignClient("zddts-ftp")
public interface FtpServerClient {
@PostMapping(value = "/ftp/pturl/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R fileUpload(@RequestPart(value = "file", required = true) MultipartFile file, @RequestParam("romte") String romte) throws Exception;
@PostMapping(value = "/ftp/pturl/download")
public ResponseEntity<byte[]> download(@RequestParam("romte") String romte) throws Exception;
// /**
// * 配置文件
// */
// @Configuration
// class MultipartSupportConfig {
// @Autowired
// private ObjectFactory<HttpMessageConverters> messageConverters;
//
// @Bean
// public Encoder feignFormEncoder() {
// return new SpringFormEncoder(new SpringEncoder(messageConverters));
// }
//
//
// }
}
接下来就是真正调用的时候了:
controller:
package com.zddts.patmarket.filemage.controller;
import com.zddts.common.utils.R;
import com.zddts.patmarket.filemage.service.FileServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* 说明:文件上传功能
* Created by luojie on 2019/04/16.
*/
@RestController
@RequestMapping("/file")
public class FileServerController {
@Autowired
private FileServerService fileServerService;
/**
* 上传文件
* 测试方法:
*
* @param file 待上传的文件
* @return 文件在服务器上的绝对路径
* @throws IOException IO异常
*/
@PostMapping("/upload")
public R fileUpload(@RequestPart("file") MultipartFile file, @RequestParam("type") String type) throws Exception {
return fileServerService.fileUpload(file, type);
}
/**
* 上传文件
* 测试方法:
*
* @param patNo 待上传的文件
* @return 文件在服务器上的绝对路径
* @throws IOException IO异常
*/
@RequestMapping(value = "/download")
@ResponseBody
public Object download(@RequestParam("patNo") String patNo, @RequestParam("consId") String consId, @RequestParam("orgNo") String orgNo, HttpServletRequest request, HttpServletResponse response) throws Exception {
ResponseEntity entity = fileServerService.download(patNo, consId, orgNo, request);
if (entity.getBody() == null) {
return R.error("文件不存在");
}
return entity;
}
}
service:
package com.zddts.patmarket.filemage.service.impl;
import com.zddts.common.contants.ftp.FtpConstants;
import com.zddts.common.utils.R;
import com.zddts.patmarket.client.FtpServerClient;
import com.zddts.patmarket.filemage.service.FileServerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
/**
* 说明:文件上传服务
* Created by luojie on 2019/04/16.
*/
@Service
public class FileServerServiceImpl implements FileServerService {
//日志
private Logger log = LoggerFactory.getLogger(FileServerServiceImpl.class);
@Autowired
FtpServerClient ftpServerClient;
@Override
public R fileUpload(MultipartFile file, String type) throws Exception {
return ftpServerClient.fileUpload(file, FtpConstants.WORKDIR_PATDATAS);
}
@Override
public ResponseEntity<byte[]> download(String patNo, String consId, String orgNo, HttpServletRequest request) throws Exception {
//判断用户是否有权限
String path = "/upload/pat/datas/papatentSort测试.csv";
ResponseEntity<byte[]> entity = ftpServerClient.download(path);
return entity;
}
}
启动服务测试 :
我用的是postman测试,测试完可以直接出接口文旦分享给团队成员很方便:
上传:
下载:
注意:
若ftp乱码上乱码,代码中已经处理了可能是工具有问题:
xftp设置下使用utf-8编码