用cn.hutool工具包进行图片上传下载示例
生活随笔
收集整理的這篇文章主要介紹了
用cn.hutool工具包进行图片上传下载示例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 實體類
- controller
- service
- 數據轉換的工具類
- file工具類
Hutool-http針對JDK的HttpUrlConnection做一層封裝,簡化了HTTPS請求、文件上傳、Cookie記憶等操作,使Http請求變得無比簡單。
用的是smms圖床。
依賴:
實體類
@Data public class PictureDto implements Serializable {/** ID */private Long id;/** 上傳日期 */private Timestamp createTime;/** 刪除的URL */private String deleteUrl;/** 圖片名稱 */private String filename;/** 圖片高度 */private String height;/** 圖片大小 */private String size;/** 圖片地址 */private String url;/** 用戶名稱 */private String username;/** 圖片寬度 */private String width;/** 文件的MD5值 */private String md5code; }controller
@RestController @RequestMapping("/api/pictures") @Api(tags = "工具:免費圖床管理") public class PictureController {private final IGenerator generator;private final PictureService pictureService;public PictureController(IGenerator generator, PictureService pictureService) {this.generator = generator;this.pictureService = pictureService;}@Log("查詢圖片")@PreAuthorize("@el.check('pictures:list')")@GetMapping@ApiOperation("查詢圖片")public ResponseEntity<Object> getRoles(PictureQueryCriteria criteria, Pageable pageable) {return new ResponseEntity<>(pictureService.queryAll(criteria, pageable), HttpStatus.OK);}@Log("導出數據")@ApiOperation("導出數據")@GetMapping(value = "/download")@PreAuthorize("@el.check('pictures:list')")public void download(HttpServletResponse response, PictureQueryCriteria criteria) throws IOException {pictureService.download(generator.convert(pictureService.queryAll(criteria), PictureDto.class), response);}@Log("上傳圖片")@PreAuthorize("@el.check('pictures:add')")@PostMapping@ApiOperation("上傳圖片")public ResponseEntity<Object> upload(@RequestParam MultipartFile file) {String userName = SecurityUtils.getUsername();Picture picture = pictureService.upload(file, userName);return new ResponseEntity<>(picture, HttpStatus.OK);}@Log("同步圖床數據")@ApiOperation("同步圖床數據")@PostMapping(value = "/synchronize")public ResponseEntity<Object> synchronize() {pictureService.synchronize();return new ResponseEntity<>(HttpStatus.OK);}@Log("多選刪除圖片")@ApiOperation("多選刪除圖片")@PreAuthorize("@el.check('pictures:del')")@DeleteMappingpublic ResponseEntity<Object> deleteAll(@RequestBody Long[] ids) {pictureService.deleteAll(ids);return new ResponseEntity<>(HttpStatus.OK);} }service
package co.yixiang.tools.service.impl;import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import co.yixiang.common.service.impl.BaseServiceImpl; import co.yixiang.common.utils.QueryHelpPlus; import co.yixiang.dozer.service.IGenerator; import co.yixiang.exception.BadRequestException; import co.yixiang.tools.domain.Picture; import co.yixiang.tools.service.PictureService; import co.yixiang.tools.service.dto.PictureDto; import co.yixiang.tools.service.dto.PictureQueryCriteria; import co.yixiang.tools.service.mapper.PictureMapper; import co.yixiang.utils.FileUtil; import co.yixiang.utils.TranslatorUtil; import co.yixiang.utils.ValidationUtil; import co.yixiang.utils.YshopConstant; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.github.pagehelper.PageInfo; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.IOException; import java.util.*;// 默認不使用緩存 //import org.springframework.cache.annotation.CacheConfig; //import org.springframework.cache.annotation.CacheEvict; //import org.springframework.cache.annotation.Cacheable;/*** @author hupeng* @date 2020-05-13*/ @Service //@AllArgsConstructor //@CacheConfig(cacheNames = "picture") @Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class) public class PictureServiceImpl extends BaseServiceImpl<PictureMapper, Picture> implements PictureService {private final IGenerator generator; // IGenerator是一個自定義的數據轉化接口@Value("${smms.token}")private String token;//是用于圖床上傳文件的token //在yml文件中配置: //# sm.ms 圖床的 token //smms: // token: 1oOP3ykFDI0K6ifmtvU7c8Y1eTWZSlylprivate static final String SUCCESS = "success";private static final String CODE = "code";private static final String MSG = "message";public PictureServiceImpl(IGenerator generator) {this.generator = generator;}@Override//@Cacheablepublic Map<String, Object> queryAll(PictureQueryCriteria criteria, Pageable pageable) {getPage(pageable);PageInfo<Picture> page = new PageInfo<>(queryAll(criteria));Map<String, Object> map = new LinkedHashMap<>(2);map.put("content", generator.convert(page.getList(), PictureDto.class));map.put("totalElements", page.getTotal());return map;}@Override//@Cacheablepublic List<Picture> queryAll(PictureQueryCriteria criteria) {return baseMapper.selectList(QueryHelpPlus.getPredicate(Picture.class, criteria));}@Overridepublic void download(List<PictureDto> all, HttpServletResponse response) throws IOException {List<Map<String, Object>> list = new ArrayList<>();for (PictureDto picture : all) {Map<String, Object> map = new LinkedHashMap<>();map.put("上傳日期", picture.getCreateTime());map.put("刪除的URL", picture.getDeleteUrl());map.put("圖片名稱", picture.getFilename());map.put("圖片高度", picture.getHeight());map.put("圖片大小", picture.getSize());map.put("圖片地址", picture.getUrl());map.put("用戶名稱", picture.getUsername());map.put("圖片寬度", picture.getWidth());map.put("文件的MD5值", picture.getMd5code());list.add(map);}FileUtil.downloadExcel(list, response);}@Override@Transactional(rollbackFor = Throwable.class)public Picture upload(MultipartFile multipartFile, String username) {File file = FileUtil.toFile(multipartFile);// 驗證是否重復上傳Picture picture = this.getOne(new LambdaQueryWrapper<Picture>().eq(Picture::getMd5code, FileUtil.getMd5(file)));if (picture != null) {return picture;}HashMap<String, Object> paramMap = new HashMap<>(1);paramMap.put("smfile", file);// 上傳文件String result = HttpRequest.post(YshopConstant.Url.SM_MS_URL + "/v2/upload").header("Authorization", token).form(paramMap)//設置map類型表單數據.timeout(20000).execute().body();//獲取響應主體JSONObject jsonObject = JSONUtil.parseObj(result);if (!jsonObject.get(CODE).toString().equals(SUCCESS)) {throw new BadRequestException(TranslatorUtil.translate(jsonObject.get(MSG).toString()));}picture = JSON.parseObject(jsonObject.get("data").toString(), Picture.class);picture.setSize(FileUtil.getSize(Integer.parseInt(picture.getSize())));picture.setUsername(username);picture.setMd5code(FileUtil.getMd5(file));picture.setFilename(FileUtil.getFileNameNoEx(multipartFile.getOriginalFilename()) + "." + FileUtil.getExtensionName(multipartFile.getOriginalFilename()));this.save(picture);//刪除臨時文件FileUtil.del(file);// FileUtil是PathUtil的子類 是cn.hutool.core.io包下return picture;}@Overridepublic Picture findById(Long id) {Picture picture = this.getById(id);ValidationUtil.isNull(picture.getId(), "Picture", "id", id);return picture;}@Overridepublic void deleteAll(Long[] ids) {for (Long id : ids) {Picture picture = findById(id);try {HttpUtil.get(picture.getDeleteUrl());this.removeById(id);} catch (Exception e) {this.removeById(id);}}}@Overridepublic void synchronize() {//鏈式構建請求//Hutool-http針對JDK的HttpUrlConnection做一層封裝,簡化了HTTPS請求、文件上傳、Cookie記憶等操作,使Http請求變得無比簡單String result = HttpRequest.get(YshopConstant.Url.SM_MS_URL + "/v2/upload_history")//頭信息,多個頭信息多次調用此方法即可.header("Authorization", token).timeout(20000).execute().body();JSONObject jsonObject = JSONUtil.parseObj(result);List<Picture> pictures = JSON.parseArray(jsonObject.get("data").toString(), Picture.class);for (Picture picture : pictures) {if (this.getOne(new LambdaQueryWrapper<Picture>().eq(Picture::getUrl, picture.getUrl())) == null) {picture.setSize(FileUtil.getSize(Integer.parseInt(picture.getSize())));picture.setUsername("System Sync");picture.setMd5code(null);this.save(picture);}}} }數據轉換的工具類
public interface IGenerator {/*** 轉換** @param s 數據對象* @param clz 復制目標類型* @return {@link T}* @Description: 單個對象的深度復制及類型轉換,vo/domain , po* @author banjuer@outlook.com* @Time 2018年5月9日 下午3:53:24*/<T, S> T convert(S s, Class<T> clz);/*** 轉換* @param s 數據對象* @param clz 復制目標類型* @return {@link List<T>}* @Description: list深度復制* @author banjuer@outlook.com* @Time 2018年5月9日 下午3:54:08*/<T, S> List<T> convert(List<S> s, Class<T> clz); } @Component @Lazy(true) public class EJBGenerator implements IGenerator {@Autowiredprotected Mapper dozerMapper;//Mapper 是org.dozer包下的@Overridepublic <T, S> T convert(final S s, Class<T> clz) {return s == null ? null : this.dozerMapper.map(s, clz);}@Overridepublic <T, S> List<T> convert(List<S> s, Class<T> clz) {return s == null ? null : s.stream().map(vs -> this.dozerMapper.map(vs, clz)).collect(Collectors.toList());} }file工具類
/*** File工具類,擴展 hutool 工具包* @author Zheng Jie* @date 2018-12-27*/ public class FileUtil extends cn.hutool.core.io.FileUtil {/*** 定義GB的計算常量*/private static final int GB = 1024 * 1024 * 1024;/*** 定義MB的計算常量*/private static final int MB = 1024 * 1024;/*** 定義KB的計算常量*/private static final int KB = 1024;/*** 格式化小數*/private static final DecimalFormat DF = new DecimalFormat("0.00");/*** MultipartFile轉File*/public static File toFile(MultipartFile multipartFile) {// 獲取文件名String fileName = multipartFile.getOriginalFilename();// 獲取文件后綴String prefix = "." + getExtensionName(fileName);File file = null;try {// 用uuid作為文件名,防止生成的臨時文件重復file = File.createTempFile(IdUtil.simpleUUID(), prefix);// MultipartFile to FilemultipartFile.transferTo(file);} catch (IOException e) {e.printStackTrace();}return file;}/*** 獲取文件擴展名,不帶 .*/public static String getExtensionName(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot > -1) && (dot < (filename.length() - 1))) {return filename.substring(dot + 1);}}return filename;}/*** Java文件操作 獲取不帶擴展名的文件名*/public static String getFileNameNoEx(String filename) {if ((filename != null) && (filename.length() > 0)) {int dot = filename.lastIndexOf('.');if ((dot > -1) && (dot < (filename.length()))) {return filename.substring(0, dot);}}return filename;}/*** 文件大小轉換*/public static String getSize(long size) {String resultSize;if (size / GB >= 1) {//如果當前Byte的值大于等于1GBresultSize = DF.format(size / (float) GB) + "GB ";} else if (size / MB >= 1) {//如果當前Byte的值大于等于1MBresultSize = DF.format(size / (float) MB) + "MB ";} else if (size / KB >= 1) {//如果當前Byte的值大于等于1KBresultSize = DF.format(size / (float) KB) + "KB ";} else {resultSize = size + "B ";}return resultSize;}/*** 將文件名解析成文件的上傳路徑*/public static File upload(MultipartFile file, String filePath) {//String name = getFileNameNoEx(file.getOriginalFilename());String suffix = getExtensionName(file.getOriginalFilename());StringBuffer nowStr = fileRename();try {String fileName = nowStr + "." + suffix;String path = filePath + fileName;// getCanonicalFile 可解析正確各種路徑File dest = new File(path).getCanonicalFile();// 檢測是否存在目錄if (!dest.getParentFile().exists()) {dest.getParentFile().mkdirs();}// 文件寫入file.transferTo(dest);return dest;} catch (Exception e) {e.printStackTrace();}return null;}/*** 導出excel*/public static void downloadExcel(List<Map<String, Object>> list, HttpServletResponse response) throws IOException {String tempPath = System.getProperty("java.io.tmpdir") + IdUtil.fastSimpleUUID() + ".xlsx";File file = new File(tempPath);BigExcelWriter writer = ExcelUtil.getBigWriter(file);// 一次性寫出內容,使用默認樣式,強制輸出標題writer.write(list, true);//response為HttpServletResponse對象response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");//test.xls是彈出下載對話框的文件名,不能為中文,中文請自行編碼response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");ServletOutputStream out = response.getOutputStream();// 終止后刪除臨時文件file.deleteOnExit();writer.flush(out, true);//此處記得關閉輸出Servlet流IoUtil.close(out);}public static String getFileType(String type) {String documents = "txt doc pdf ppt pps xlsx xls docx";String music = "mp3 wav wma mpa ram ra aac aif m4a";String video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg";String image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg";if (image.contains(type)) {return "pic";} else if (documents.contains(type)) {return "txt";} else if (music.contains(type)) {return "music";} else if (video.contains(type)) {return "vedio";} else {return "other";}}public static void checkSize(long maxSize, long size) {// 1Mint len = 1024 * 1024;if (size > (maxSize * len)) {throw new BadRequestException("文件超出規定大小");}}/*** 判斷兩個文件是否相同*/public static boolean check(File file1, File file2) {String img1Md5 = getMd5(file1);String img2Md5 = getMd5(file2);return img1Md5.equals(img2Md5);}/*** 判斷兩個文件是否相同*/public static boolean check(String file1Md5, String file2Md5) {return file1Md5.equals(file2Md5);}private static byte[] getByte(File file) {// 得到文件長度byte[] b = new byte[(int) file.length()];try {InputStream in = new FileInputStream(file);try {in.read(b);} catch (IOException e) {e.printStackTrace();}} catch (FileNotFoundException e) {e.printStackTrace();return null;}return b;}private static String getMd5(byte[] bytes) {// 16進制字符char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};try {MessageDigest mdTemp = MessageDigest.getInstance("MD5");mdTemp.update(bytes);byte[] md = mdTemp.digest();int j = md.length;char[] str = new char[j * 2];int k = 0;// 移位 輸出字符串for (byte byte0 : md) {str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);} catch (Exception e) {e.printStackTrace();}return null;}/*** 下載文件* @param request /* @param response /* @param file /*/public static void downloadFile(HttpServletRequest request, HttpServletResponse response, File file, boolean deleteOnExit) {response.setCharacterEncoding(request.getCharacterEncoding());response.setContentType("application/octet-stream");FileInputStream fis = null;try {fis = new FileInputStream(file);response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());IOUtils.copy(fis, response.getOutputStream());response.flushBuffer();} catch (Exception e) {e.printStackTrace();} finally {if (fis != null) {try {fis.close();if (deleteOnExit) {file.deleteOnExit();}} catch (IOException e) {e.printStackTrace();}}}}public static String getMd5(File file) {return getMd5(getByte(file));}總結
以上是生活随笔為你收集整理的用cn.hutool工具包进行图片上传下载示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 解决配置shiro+jwt后swagge
- 下一篇: 用拦截器+注解+cookie进行简单限流