1. 常见的图片存储方案
方案一:使用nginx搭建图片服务器
方案二:使用开源的分布式文件存储系统,例如Fastdfs、HDFS等(需要运维搭建)
方案三:使用云存储,例如阿里云、七牛云等(目前最流行)
2. 七牛云图片存储
2.1 七牛云依赖坐标
<dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.2.0</version></dependency>
2.2 Java SDK操作七牛云
本章节我们就需要使用七牛云提供的Java SDK完成图片上传和删除,我们可以参考官方提供的例子。
上传文件案例
//构造一个带指定Zone对象的配置类Configuration cfg = new Configuration(Zone.zone0());//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);//...生成上传凭证,然后准备上传String accessKey = "your access key";String secretKey = "your secret key";//存储空间的名称String bucket = "your bucket name";//如果是Windows情况下,格式是 D:\\qiniu\\test.pngString localFilePath = "/home/qiniu/test.png";//默认不指定key的情况下,以文件内容的hash值(七牛云自己命名)作为文件名//设置key的值后,以key值为文件名上传String key = null;Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(localFilePath, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}
删除文件案例
//构造一个带指定Zone对象的配置类Configuration cfg = new Configuration(Zone.zone0());//...其他参数参考类注释String accessKey = "your access key";String secretKey = "your secret key";String bucket = "your bucket name";String key = "your file key";Auth auth = Auth.create(accessKey, secretKey);BucketManager bucketManager = new BucketManager(auth, cfg);try {bucketManager.delete(bucket, key);} catch (QiniuException ex) {//如果遇到异常,说明删除失败System.err.println(ex.code());System.err.println(ex.response.toString());}
封装工具类
为了方便操作七牛云存储服务,我们可以将官方提供的案例简单改造成一个工具类QiniuUtils
package com.itheima.util;import com.google.gson.Gson;import com.qiniu.common.QiniuException;import com.qiniu.common.Zone;import com.qiniu.http.Response;import com.qiniu.storage.BucketManager;import com.qiniu.storage.Configuration;import com.qiniu.storage.UploadManager;import com.qiniu.storage.model.DefaultPutRet;import com.qiniu.util.Auth;/*** 七牛云工具类*/public class QiniuUtils {public static String accessKey = "dulF9Wze9bxujtuRvu3yyYb9JX1Sp23jzd3tO708";public static String secretKey = "vZkhW7iot3uWwcWz9vXfbaP4JepdWADFDHVLMZOe";public static String bucket = "qiniutest";public static void upload2Qiniu(String filePath,String fileName){//构造一个带指定Zone对象的配置类Configuration cfg = new Configuration(Zone.zone0());UploadManager uploadManager = new UploadManager(cfg);Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(filePath, fileName, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);} catch (QiniuException ex) {Response r = ex.response;try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}}//上传文件public static void upload2Qiniu(byte[] bytes, String fileName){//构造一个带指定Zone对象的配置类Configuration cfg = new Configuration(Zone.zone0());//...其他参数参考类注释UploadManager uploadManager = new UploadManager(cfg);//默认不指定key的情况下,以文件内容的hash值作为文件名String key = fileName;Auth auth = Auth.create(accessKey, secretKey);String upToken = auth.uploadToken(bucket);try {Response response = uploadManager.put(bytes, key, upToken);//解析上传成功的结果DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);System.out.println(putRet.key);System.out.println(putRet.hash);} catch (QiniuException ex) {Response r = ex.response;System.err.println(r.toString());try {System.err.println(r.bodyString());} catch (QiniuException ex2) {//ignore}}}//删除文件public static void deleteFileFromQiniu(String fileName){//构造一个带指定Zone对象的配置类Configuration cfg = new Configuration(Zone.zone0());String key = fileName;Auth auth = Auth.create(accessKey, secretKey);BucketManager bucketManager = new BucketManager(auth, cfg);try {bucketManager.delete(bucket, key);} catch (QiniuException ex) {//如果遇到异常,说明删除失败System.err.println(ex.code());System.err.println(ex.response.toString());}}}
3. 图片上传代码实现
3.1 图片上传并回显流程
3.2 在Controller层接收上传的文件
package com.itheima.controller;import com.alibaba.dubbo.config.annotation.Reference;import com.itheima.constant.MessageConstant;import com.itheima.entity.PageResult;import com.itheima.entity.QueryPageBean;import com.itheima.entity.Result;import com.itheima.pojo.CheckGroup;import com.itheima.pojo.Setmeal;import com.itheima.service.CheckGroupService;import com.itheima.service.SetmealService;import com.itheima.utils.QiniuUtils;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import javax.servlet.ServletContext;import javax.servlet.http.HttpServletRequest;import java.io.File;import java.util.List;import java.util.UUID;/*** 套餐管理*/@RestController@RequestMapping("/setmeal")public class SetmealController {@Referenceprivate SetmealService setmealService;//图片上传@RequestMapping("/upload")public Result upload(@RequestParam("imgFile")MultipartFile imgFile){try{//获取原始文件名String originalFilename = imgFile.getOriginalFilename();int lastIndexOf = originalFilename.lastIndexOf(".");//获取文件后缀String suffix = originalFilename.substring(lastIndexOf);//使用UUID随机产生文件名称,防止同名文件覆盖String fileName = UUID.randomUUID().toString() + suffix;QiniuUtils.upload2Qiniu(imgFile.getBytes(),fileName);//图片上传成功Result result = new Result(true, MessageConstant.PIC_UPLOAD_SUCCESS);result.setData(fileName);return result;}catch (Exception e){e.printStackTrace();//图片上传失败return new Result(false,MessageConstant.PIC_UPLOAD_FAIL);}}}
文件上传时,需要对文件名进行处理,保证文件名是唯一的,防止被覆盖。(实现方案:文件名使用UUID)
注意:别忘了在spring配置文件中配置文件上传组件
<!--文件上传组件--><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="104857600" /><property name="maxInMemorySize" value="4096" /><property name="defaultEncoding" value="UTF-8"/></bean>

