思路是先在表单中提交数据和图片,然后给图片创建一个实际的本地路径,然后用这个路径将图片上传到七牛云储存,上传成功后从七牛云返回文件名,将这个文件名存入数据库中。然后读取图片时只需用http://+域名/+文件名就可以成功取到图片。下面给出代码(从项目中抠出来的,可能不完整,但是思路肯定完整)

引入七牛云的依赖:

1
2
3
4
5
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.0</version>
</dependency>

application.properties配置:

这里的ak和sk,在你七牛云账户的密匙管理里面可以看到,bucket是你的对象储存空间名,path是七牛云分配的域名。
1
2
3
4
5
#七牛云配置
qiniu.accessKey=01DnQx9eSgMO0vfp00O0tao8A1lynlnT2O8Koodt
qiniu.secretKey=hcfyRnCoeZEeNQAJsKSDiDsv2rnR_YOI_-0kkjiB
qiniu.bucket=blog_album
qiniu.path=http://poag7m5q9.bkt.clouddn.com

配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.lingfei.admin.config;

import com.google.gson.Gson;
import com.lingfei.admin.utils.QiniuUtil;
import com.qiniu.common.Zone;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.MultipartConfigElement;
import javax.servlet.Servlet;
/**
* @author www.xyjz123.xyz
* @date 2019/3/28 15:41
*/
@Configuration
@ConditionalOnClass({Servlet.class, StandardServletMultipartResolver.class, MultipartConfigElement.class})
@ConditionalOnProperty(prefix = "spring.servlet.multipart", name = "enabled", matchIfMissing = true)
@EnableConfigurationProperties(MultipartProperties.class)
public class FileUploadConfig {
/**
* 七牛云配置
*/
@Autowired
private QiniuUtil qiNiuProperties;
private final MultipartProperties multipartProperties;
public FileUploadConfig(MultipartProperties multipartProperties) {
this.multipartProperties = multipartProperties;
}
/**
* 上传配置
*/
@Bean
@ConditionalOnMissingBean
public MultipartConfigElement multipartConfigElement() {
return this.multipartProperties.createMultipartConfig();
}
/**
* 注册解析器
*/
@Bean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
@ConditionalOnMissingBean(MultipartResolver.class)
public StandardServletMultipartResolver multipartResolver() {
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
multipartResolver.setResolveLazily(this.multipartProperties.isResolveLazily());
return multipartResolver;
}
/**
* 华东 Zone.zone0()
* 华北 Zone.zone1()
* 华南 Zone.zone2()
* 北美 Zone.zoneNa0()
*/
@Bean
public com.qiniu.storage.Configuration qiniuConfig() {
//华东
return new com.qiniu.storage.Configuration(Zone.zone0());
}
/**
* 构建一个七牛上传工具实例
*/
@Bean
public UploadManager uploadManager() {
return new UploadManager(qiniuConfig());
}
/**
* 认证信息实例
*
* @return
*/
@Bean
public Auth auth() {
return Auth.create(qiNiuProperties.getAccessKey(),
qiNiuProperties.getSecretKey());
}
/**
* 构建七牛空间管理实例
*/
@Bean
public BucketManager bucketManager() {
return new BucketManager(auth(), qiniuConfig());
}
/**
* 配置gson为json解析工具
*
* @return
*/
@Bean
public Gson gson() {
return new Gson();
}
}

上传service接口类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.lingfei.admin.service;

import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;

import java.io.File;
/**
* @author www.xyjz123.xyz
* @date 2019/3/28 15:44
*/
public interface UploadService {
/**
* 上传文件
* @param file File
* @return
* @throws QiniuException
*/
Response uploadFile(File file) throws QiniuException;
}

上传service实现类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.lingfei.admin.service.impl;

import com.lingfei.admin.service.UploadService;
import com.lingfei.admin.utils.QiniuUtil;
import com.qiniu.common.QiniuException;
import com.qiniu.http.Response;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;

/**
* @author www.xyjz123.xyz
* @date 2019/3/28 15:46
*/
@Service
public class UploadServiceImpl implements UploadService, InitializingBean {
@Autowired
private UploadManager uploadManager;
@Autowired
private Auth auth;
@Autowired
private QiniuUtil qiNiuProperties;
private StringMap putPolicy;
String key = null;
@Override
public Response uploadFile(File file) throws QiniuException {
Response response = this.uploadManager.put(file, key, getUploadToken());
int retry = 0;
while (response.needRetry() && retry < 3) {
response = this.uploadManager.put(file, key, getUploadToken());
retry++;
}
return response;
}
@Override
public void afterPropertiesSet() throws Exception {
this.putPolicy = new StringMap();
putPolicy.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"width\":$(imageInfo.width), \"height\":${imageInfo.height}}");
}
/**
* 获取上传凭证
*
* @return
*/
private String getUploadToken() {
return this.auth.uploadToken(qiNiuProperties.getBucket(), null, 3600, putPolicy);
}
}

control类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
/**
* 接受post方法,将表单传来的数据插入
* @param announce com.lingfei.admin.entity.Announce
* @return 服务端跳转到announce.html
*/
@ApiOperation("插入数据")
@PostMapping("/addContent")
public String addContent(Announce announce, HttpServletRequest request,
@RequestParam("file") MultipartFile file, Model model){
try{
//根据时间戳创建文件名
String fileName = System.currentTimeMillis() + file.getOriginalFilename();
//创建文件的实际路径
String destFileName = request.getServletContext().getRealPath("") + "uploaded" + File.separator + fileName;
//根据文件路径创建文件对应的实际文件
File destFile = new File(destFileName);
//创建文件实际路径
destFile.getParentFile().mkdirs();
//将文件传到对应的文件位置
file.transferTo(destFile);
Response response = qiNiuService.uploadFile(destFile);
//解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
announce.setPicture(putRet.key);//这个就是从七牛云获取的文件名
}catch (IOException e){
e.printStackTrace();
}
announceService.save(announce); //存入数据库
return "redirect:announce";
}

我的entity类:(用了大量的注解,这个不解释,有兴趣的可以翻我的博客)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.lingfei.admin.entity;

import cn.afterturn.easypoi.excel.annotation.Excel;
import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
import com.gitee.sunchenbin.mybatis.actable.command.BaseModel;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.sql.Timestamp;

/**
* @author 熊义杰
* @date 2019-3-17
*/

@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "announce")
public class Announce extends BaseModel implements Serializable {

@Excel(name = "序号", orderNum = "0")
@Column(name = "id",type = MySqlTypeConstant.INT, length = 10,isKey = true,isAutoIncrement = true)
private int id;

@Excel(name = "内容", orderNum = "1")
@Column(name = "content",type = MySqlTypeConstant.VARCHAR,length = 400)
private String content;

@Column(name = "picture",type = MySqlTypeConstant.VARCHAR,length = 30)
private String picture;

@Excel(name = "时间", exportFormat = "yyyy-MM-dd hh:mm" ,orderNum = "2")
@Column(name = "date",type = MySqlTypeConstant.DATETIME)
private Timestamp date;
}

thymeleaf主要文件:

1
2
3
4
5
6
7
8
<form action="/admin/addContent" method="post" enctype="multipart/form-data">
<div class="form-group purple-border">
<label for="content">内容(两百字以内)</label>
<textarea class="form-control" id="content" name="content" rows="3"></textarea>
</div>
<input type="file" name="file"/>
<input type="submit" class="btn btn-primary" value="发布">
</form>

展示文件我只贴上一个显示图片的:

1
<td><img class="img-size" th:src="@{http://poag7m5q9.bkt.clouddn.com/{fileName}(fileName=${page.picture})}"></td>  //page就是这个类的对象名