实际项目中不一样的《桥接模式》

打印 上一主题 下一主题

主题 1016|帖子 1016|积分 3048

图片缩略图功能

必要对图片生产缩略图,压缩并生存到不同的介质中。输入端可能是当舆图片,也可能是网络图片。生存的位置可能是本地,也有可能是第三方的minio、阿里云oss、七牛云oss。并且这些途径可能随时扩展。为了设计的灵活性,这里就要把输入可输出抽象出来,应用层通过抽象层结偶。如许的抽象和实现分离,实现层可以自由扩展,而应用层依赖于抽象层相对稳固。
整体结构是如许的


代码结构是如许的


整体实现是如许的

ThumbLoad   图片的输入信息⬇︎⬇︎⬇︎
点击检察代码
  1. package com.supremind.modules.news.service.impl.thumb;
  2. import com.supremind.modules.news.entity.ImageActionVo;
  3. import lombok.Getter;
  4. import lombok.Setter;
  5. import lombok.extern.slf4j.Slf4j;
  6. import javax.validation.constraints.NotBlank;
  7. import java.net.HttpURLConnection;
  8. import java.net.URL;
  9. /**
  10. * 图片载入
  11. * 1)图片载入过程不涉及到异常处理,异常自行处理,一切结果以isSuccess为准,具体消息去message
  12. */
  13. @Slf4j
  14. public abstract class ThumbLoad {
  15.     @Setter
  16.     @Getter
  17.     protected ThumbSave thumbSave;
  18.     public ThumbLoad(ThumbSave thumbSave) {
  19.         this.thumbSave = thumbSave;
  20.     }
  21.     @Getter
  22.     @Setter
  23.     /*load载入结果,默认为false,免去每次异常都赋值.只有操作成功后进行赋值true*/
  24.     protected Boolean isSuccess=false;
  25.     @Getter
  26.     @Setter
  27.     /*错误消息提醒*/
  28.     protected String message =null;
  29.     public abstract ImageActionVo thumb(String filePath);
  30.     /**
  31.      * 验证网络资源是否可以访问
  32.      * @param url 网络资源地址
  33.      * @param checkIsImage 是否强制检测为image类型的资源
  34.      * @return
  35.      */
  36.     protected Boolean checkUrlIsAccess(@NotBlank String url, Boolean checkIsImage){
  37.         log.debug("checkUrlIsAccess start ...");
  38.         log.debug("url:{}",url);
  39.         URL netUrl = null;
  40.         HttpURLConnection httpURLConnection =null;
  41.         Boolean result = true;
  42.         try {
  43.             netUrl = new URL(url);
  44.             httpURLConnection = (HttpURLConnection)netUrl.openConnection();
  45.             httpURLConnection.setConnectTimeout(2000);
  46.             if (httpURLConnection.getResponseCode()==200) {
  47.                 String contentType = httpURLConnection.getContentType();
  48.                 if (checkIsImage){
  49.                     if (!contentType.split("/")[0].equals("image")) {
  50.                         result = false;
  51.                     }
  52.                 }
  53.             }else{
  54.                 result = false;
  55.             }
  56.         }catch (Exception e){
  57.             log.error("e :{}", e);
  58.             result = false;
  59.         }finally {
  60.             if (httpURLConnection != null) {
  61.                 httpURLConnection.disconnect();
  62.             }
  63.         }
  64.         log.debug("checkUrlIsAccess end.");
  65.         return result;
  66.     }
  67. }
复制代码
ThumbSave   图片的输入信息⬇︎⬇︎⬇︎
点击检察代码
  1. package com.supremind.modules.news.service.impl.thumb;
  2. import com.supremind.config.FileServerConfig;
  3. import lombok.AllArgsConstructor;
  4. import lombok.Data;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import java.io.InputStream;
  7. /**
  8. * 文件保存
  9. * 1)文件保存到fileServer ,thumburi是fileserver返回的可以直接访问的地址
  10. * 2)文件保存本地,thumburi表示本地文件的完整路径
  11. * 注:
  12. * 1.文件保存类型取决与具体实现,但结构保持一致。最外层控制逻辑,是isSuccess.
  13. * 2.为了实现最大程度的复用,这里选择使用inputStream 进行对接saveImage.
  14. * 3.在扩展save策略时,注意异常处理,结果都从ImageSaveResult体现说明
  15. */
  16. public abstract class ThumbSave {
  17.     @Autowired
  18.     protected FileServerConfig fileServerConfig;
  19.     protected String bucketName = "thumb_images"; //file server buckete
  20.     protected String saveUri; //处理后的文件保存路
  21.     protected Integer width; //图片压缩宽度
  22.     protected Integer height; //图片压缩高度
  23.     public ThumbSave(String saveUri, Integer width, Integer height) {
  24.         this.saveUri = saveUri;
  25.         this.width = width;
  26.         this.height = height;
  27.     }
  28.     abstract ImageSaveResult save(InputStream imageInputStream);
  29.     @Data
  30.     @AllArgsConstructor
  31.     class ImageSaveResult {
  32.         private Boolean isSuccess = false; //操作是否成功
  33.         private String thumbUri; //缩略图文件地址
  34.         private String msg; //消息
  35.     }
  36. }
复制代码
下面是详细实现
LocalThumbSave 本地生存⬇︎⬇︎⬇︎
点击检察代码
  1. package com.supremind.modules.news.service.impl.thumb;
  2. import lombok.extern.slf4j.Slf4j;
  3. import net.coobird.thumbnailator.Thumbnails;
  4. import java.io.IOException;
  5. import java.io.InputStream;
  6. /**
  7. * 本地保存文件
  8. */
  9. @Slf4j
  10. public class LocalThumbSave extends ThumbSave {
  11.     public LocalThumbSave(String saveUri, Integer width, Integer height) {
  12.         super(saveUri, width, height);
  13.     }
  14.     public ImageSaveResult save(InputStream imageInputStream) {
  15.         try {
  16.             Thumbnails.of(imageInputStream).size(width,height).toFile(saveUri);
  17.             return new ImageSaveResult(true,saveUri,null);
  18.         } catch (IOException e) {
  19.             log.error("Thumbnails toFiles error:{}",e);
  20.             return new ImageSaveResult(false, null, e.getMessage());
  21.         }
  22.     }
  23. }
复制代码
FileServerThumbSave file server生存文件(这里的fileserver又做了一层抽象,可以接入不同的第三方)⬇︎⬇︎⬇︎
点击检察代码
  1. package com.supremind.modules.news.service.impl.thumb;
  2. import com.supremind.common.SpringContextUtil;
  3. import com.supremind.common.utils.R;
  4. import com.supremind.modules.news.feign.FileFeignClient;
  5. import com.supremind.modules.news.service.impl.G;
  6. import lombok.Cleanup;
  7. import lombok.extern.slf4j.Slf4j;
  8. import net.coobird.thumbnailator.Thumbnails;
  9. import org.springframework.http.MediaType;
  10. import org.springframework.mock.web.MockMultipartFile;
  11. import java.io.ByteArrayInputStream;
  12. import java.io.ByteArrayOutputStream;
  13. import java.io.IOException;
  14. import java.io.InputStream;
  15. /**
  16. * file server保存文件
  17. */
  18. @Slf4j
  19. public class FileServerThumbSave extends ThumbSave {
  20.     public FileServerThumbSave(String saveUri, Integer width, Integer height) {
  21.         super(saveUri, width, height);
  22.     }
  23.     public ImageSaveResult save(final InputStream imageInputStream) {
  24.         log.debug("FileServerSaveImage start ......");
  25.         try {
  26.             @Cleanup ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  27.             Thumbnails.of(imageInputStream).size(width,height).toOutputStream(outputStream);
  28.             @Cleanup ByteArrayInputStream swapStream = new ByteArrayInputStream(outputStream.toByteArray());
  29.             FileFeignClient fileFeignClient = SpringContextUtil.getBean(FileFeignClient.class);
  30.             MockMultipartFile mockMultipartFile = new MockMultipartFile("file.jpg","file.jpg", MediaType.IMAGE_JPEG_VALUE,swapStream);
  31.             R image = fileFeignClient.upload(bucketName, mockMultipartFile);
  32.             log.debug("image :{}", image);
  33.             if (G.isSuccess(image)) {
  34.                 return new ImageSaveResult(true, image.get("data").toString(), null);
  35.             }else{
  36.                 return new ImageSaveResult(false, null, G.getMsg(image));
  37.             }
  38.         } catch (IOException e) {
  39.             log.error("FileServerSaveImage IOException :{}",e);
  40.             return new ImageSaveResult(false, null, e.getMessage());
  41.         }finally {
  42.             log.debug("FileServerSaveImage end");
  43.         }
  44.     }
  45. }
复制代码
UriThumbLoad 读取本地资源文件⬇︎⬇︎⬇︎
点击检察代码
  1. package com.supremind.modules.news.service.impl.thumb;
  2. import com.supremind.modules.news.entity.ImageActionVo;
  3. import com.supremind.modules.news.enums.ErrorMsgEnum;
  4. import lombok.Cleanup;
  5. import lombok.extern.slf4j.Slf4j;
  6. import java.io.File;
  7. import java.io.FileInputStream;
  8. import java.io.InputStream;
  9. /**
  10. * 本地文件载入
  11. */
  12. @Slf4j
  13. public class UriThumbLoad extends ThumbLoad {
  14.     public UriThumbLoad(ThumbSave thumbSave) {
  15.         super(thumbSave);
  16.     }
  17.     public ImageActionVo thumb(String filePath) {
  18.         //文件检查
  19.         File file = new File(filePath);
  20.         if (!file.exists()) {
  21.             return new ImageActionVo(filePath,false,null, ErrorMsgEnum.FILE_NOT_FIND.getValue());
  22.         }
  23.         try {
  24.             @Cleanup InputStream inputStream = new FileInputStream(file);
  25.             ThumbSave.ImageSaveResult save = thumbSave.save(inputStream);
  26.             return new ImageActionVo(filePath, save.getIsSuccess(), save.getThumbUri(), save.getMsg());
  27.         } catch (Exception e) {
  28.             log.error("FileNotFoundException :{}",e);
  29.             return new ImageActionVo(filePath,false,null,e.getMessage());
  30.         }
  31.     }
  32. }
复制代码
UrlThumbLoad 读取网络资源文件⬇︎⬇︎⬇︎点击检察代码
  1. package com.supremind.modules.news.service.impl.thumb;
  2. import com.supremind.modules.news.entity.ImageActionVo;
  3. import com.supremind.modules.news.enums.ErrorMsgEnum;
  4. import lombok.Cleanup;
  5. import lombok.extern.slf4j.Slf4j;
  6. import java.io.InputStream;
  7. import java.net.HttpURLConnection;
  8. import java.net.URL;
  9. /**
  10. * 网络图片载入
  11. */
  12. @Slf4j
  13. public class UrlThumbLoad extends ThumbLoad {
  14.     public UrlThumbLoad(ThumbSave thumbSave) {
  15.         super(thumbSave);
  16.     }
  17.     public ImageActionVo thumb(String filePath) {
  18.         HttpURLConnection urlConnection;
  19.         if (!checkUrlIsAccess(filePath,true)) {
  20.             return new ImageActionVo(filePath, false, null, ErrorMsgEnum.FILE_NOT_ACCESS.getValue());
  21.         }
  22.         try {
  23.             URL url = new URL(filePath);
  24.             urlConnection = (HttpURLConnection)url.openConnection();
  25.             urlConnection.setConnectTimeout(5000);
  26.             @Cleanup InputStream inputStream = urlConnection.getInputStream();
  27.             ThumbSave.ImageSaveResult save = thumbSave.save(inputStream);
  28.             return new ImageActionVo(filePath, save.getIsSuccess(), save.getThumbUri(),save.getMsg());
  29.         } catch (Exception e) {
  30.             log.error("FileNotFoundException :{}",e);
  31.             return new ImageActionVo(filePath,false,null,e.getMessage());
  32.         }
  33.     }
  34. }
复制代码
文件压缩也是同样的实现



免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

知者何南

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表