先看效果
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