1、通过测试方法将图片上传到本地服务器中
在实现类中修改ShoppingStorage findByKey方法
@Override
public ShoppingStorage findByKey(String key) {
ShoppingStorageExample example = new ShoppingStorageExample();
ShoppingStorageExample.Criteria criteria = example.createCriteria();
criteria.andKeyEqualTo(key)
List<ShoppingStorage> shoppingStorages = shoppingStorageMapper.selectByExample(example);
if (null != shoppingStorages && shoppingStorages.size()>0){
return shoppingStorages.get(0);
}
return null;
}
同时进行测试:找到ShoppingStorageMapper的
int insert(ShoppingStorage record);
右键,点击Generate》Test,把要进行测试的方法打勾,就可与生成测试方法了
创建之后进行修改
package com.neu.shopping.test.mapper;
import com.neu.shopping.entity.admin.AdminUserExample;
import com.neu.shopping.entity.admin.ShoppingStorage;
import com.neu.shopping.entity.admin.ShoppingStorageExample;
import com.neu.shopping.mapper.ShoppingStorageMapper;
import com.neu.shopping.test.SpringbootApplicationBaseTest;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.*;
class ShoppingStorageMapperTest extends SpringbootApplicationBaseTest {
@Autowired
private ShoppingStorageMapper mapper;
@Test
void insert() {
ShoppingStorage st = new ShoppingStorage();
//模拟上传数据
st.setName("cat.jpg");
st.setKey("tu1kdyo0kfmkfphebsxo.jpeg");//我们昨天上传图片时随机重命名的k文件名就是key
st.setType("image/jpeg");
st.setSize(12123);
st.setUrl("http://localhost:8888/mobile/storage/fetch/tu1kdyo0kfmkfphebsxo.jpeg");
mapper.insert(st);
System.out.println("---新增成果---");
}
}
因为数据库的限制设定了不为空,所以我们需要将ShoppingStorageMapper.xml文件中的
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.neu.shopping.entity.admin.ShoppingStorage" useGeneratedKeys="true">
<!--@mbg.generated-->
insert into shopping_storage (`key`, `name`, `type`, `size`, url, add_time, update_time, deleted
)
values (#{key}, #{name}, #{type}, #{size}, #{url}, #{addTime}, #{updateTime}, #{deleted}
)
</insert>
进行修改
<insert id="insert" keyColumn="id" keyProperty="id" parameterType="com.neu.shopping.entity.admin.ShoppingStorage" useGeneratedKeys="true">
<!--@mbg.generated-->
insert into shopping_storage (`key`, `name`, `type`, `size`, url)
values (#{key}, #{name}, #{type}, #{size}, #{url})
</insert>
此时运行测试类,就可发现已经成功上传到数据库中
2、通过测试方法查询之前上传服务器中的图片
在测试方法中,再添加一个测试查询图片的方法
@Test//查询出来
void selectByExample(){
ShoppingStorageExample example = new ShoppingStorageExample();
ShoppingStorageExample.Criteria criteria = example.createCriteria();
criteria.andKeyEqualTo("tu1kdyo0kfmkfphebsxo.jpeg");//这里就放数据库中的key,
ShoppingStorage ss=null;
List<ShoppingStorage> shoppingStorages = mapper.selectByExample(example);
if (null != shoppingStorages && shoppingStorages.size()>0){
ss = shoppingStorages.get(0);
}
System.out.println(ss);
}
查询结果:
ShoppingStorage(id=1, key=tu1kdyo0kfmkfphebsxo.jpeg, name=cat.jpg, type=image/jpeg, size=12123, url=http://localhost:8888/mobile/storage/fetch/tu1kdyo0kfmkfphebsxo.jpeg, addTime=Wed Nov 24 12:08:43 CST 2021, updateTime=Wed Nov 24 12:08:43 CST 2021, deleted=0)
到这里,我们上传储存对象到服务器已经完成了。
此时访问http://localhost:8888/fileUpload.html,进行上传,在我们的storage目录下面就会多一个图片,同时数据库(服务器)中也会多出一条数据
3、对访问数据库存储代码进行优化
在MobileStorageController中
我们将获取的类型写死了,这在上线的时候是错误的,所以我们需要进行优化。
@GetMapping("/fetch/{key:.+}") // 组成储存对象文件名 /fetch/abcdef123hjkl.jpeg
public ResponseEntity<Resource> fetch(@PathVariable String key) {
ShoppingStorage shoppingStorage = shoppingStorageService.findByKey(key);//根据key到数据库中查询
if (null == key && null == shoppingStorage) {
return ResponseEntity.notFound().build();
}
String type = shoppingStorage.getType();
// String type = "image/jpeg";//将获取的类型写死
MediaType mediaType = MediaType.parseMediaType(type);//解析类型
System.out.println("------key:"+key);
Resource file = storageService.loadAsResource(key);//把获取到的key映射为本地的路径
System.out.println("------file:"+file.toString());
if (file == null) {
return ResponseEntity.notFound().build();//为空出错
}
return ResponseEntity.ok().contentType(mediaType).body(file);//不为空就进行响应
}
通过判断获取的key是否为空值,来返回不同的响应
4、如果我们储存的服务器不是本地的,该如何修改?
1、定义属性的配置类
package com.neu.shopping.common.storage.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "shopping.storage")
public class StorageProperties {
private String active; // 激活模式
private Local local; // 本地对象存储
private Aliyun aliyun;// 阿里云OSS
private Tencent tencent; // 腾讯OSS
private Qiniu qiniu; // 七牛OSS (免费)
public String getActive() {
return active;
}
public void setActive(String active) {
this.active = active;
}
public Local getLocal() {
return local;
}
public void setLocal(Local local) {
this.local = local;
}
public Aliyun getAliyun() {
return aliyun;
}
public void setAliyun(Aliyun aliyun) {
this.aliyun = aliyun;
}
public Tencent getTencent() {
return tencent;
}
public void setTencent(Tencent tencent) {
this.tencent = tencent;
}
public Qiniu getQiniu() {
return qiniu;
}
public void setQiniu(Qiniu qiniu) {
this.qiniu = qiniu;
}
public static class Local {
private String address;
private String storagePath;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getStoragePath() {
return storagePath;
}
public void setStoragePath(String storagePath) {
this.storagePath = storagePath;
}
}
public static class Tencent {
private String secretId;
private String secretKey;
private String region;
private String bucketName;
public String getSecretId() {
return secretId;
}
public void setSecretId(String secretId) {
this.secretId = secretId;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getRegion() {
return region;
}
public void setRegion(String region) {
this.region = region;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
}
public static class Aliyun {
private String accessKeyId; // 访问秘钥-用户名
private String accessKeySecret; // 访问秘钥-密码
private String endpoint; // 访问域名:http://oss.cn-hangzhou.aliyun.com/
private String bucketName; // 存储空间(存储对象的容器)
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKeyId() {
return accessKeyId;
}
public void setAccessKeyId(String accessKeyId) {
this.accessKeyId = accessKeyId;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
}
public static class Qiniu {
private String accessKey;
private String secretKey;
private String endpoint;
private String bucketName;
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
}
}
如果这个代码提示Spring Boot Configuration Annotation Processor not configured 缺少一个处理器。
那么我们就在pom.xml中加一个依赖。代码如下
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2、定义自动配置类
package com.neu.shopping.common.storage.config;
import com.neu.shopping.common.storage.LocalStorage;
import com.neu.shopping.common.storage.StorageService;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(StorageProperties.class)
public class StorageAutoConfiguration {
private final StorageProperties properties;
public StorageAutoConfiguration(StorageProperties properties) {
this.properties = properties;
}
@Bean
public StorageService storageService() {
StorageService storageService = new StorageService();
String active = this.properties.getActive();
storageService.setActive(active);
if (active.equals("local")) {
storageService.setStorage(localStorage());
}else {
throw new RuntimeException("当前存储模式 " + active + " 不支持");
}
return storageService;
}
@Bean
public LocalStorage localStorage() {
LocalStorage localStorage = new LocalStorage();
StorageProperties.Local local = this.properties.getLocal();
localStorage.setAddress(local.getAddress());
localStorage.setStoragePath(local.getStoragePath());
return localStorage;
}
}
3、application.yml中的配置
shopping:
# 对象存储配置
storage:
# 当前工作的对象存储模式,分别是:local、aliyun、tencent、qiniu
active: local
# 本地对象存储配置信息
local:# 本地的 ,如果是阿里云的就写aliyun ,下面就是他的参数
storagePath: storage
# 这个地方应该是wx模块的WxStorageController的fetch方法对应的地址
address: http://localhost:8888/mobile/storage/fetch/
此时我们的配置内容在application.yum中已经设置好了,那我们之前的LocalStorage中写死的address就没用了,这是就可通过自定义配置的appliction中调用配置好的信息。不过我们在这里的定义自动配置类StorageAutoConfiguration只写了本地的储存配置,如果是七牛云或者阿里云的话,就在下面再写七牛云或者阿里云的LocalStorage方法。
因为我们已经写好配置类了,所以StorageService、LocalStorage中的@Component就可以不用了,将其注释掉,还有StorageService中的
@Autowired
private Storage storage;
可以把 @Autowired注释掉,因为我们已经注解了
这时就可以正常运行了,而且使用起来也方便很多
5、对上传文件进行配置
1、方法一:application.yml中的文件大小对应配置如下:
spring:
servlet:
#上传文件的配置
multipart:
max-file-size: 10KB
max-request-size: 10KB
2、方法二:在SpringBoot项目的启动类中,加入如下代码:
@Bean
public MultipartConfigElement multipartConfigElement() {
MultipartConfigFactory factory = new MultipartConfigFactory();
//文件大小
factory.setMaxFileSize(DataSize.ofMegabytes(1)); //1MB
factory.setMaxRequestSize(DataSize.ofMegabytes(10)); //10MB
return factory.createMultipartConfig();
}