赞
踩
最近项目的需要,用户在上传图片时需要将图片保存在服务器某个目录下,由于项目是导成jar包直接使用springboot内嵌的Tomcat部署的,没有war包那么方便可以直接上传至Tomcat的webapp目录下,所以我采用了另一种方式上传图片及访问图片。
项目环境:
1.springboot1.5.9(使用内嵌Tomcat8)
2.mysql5.6
3.centerOS7
4.jdk1.8
一、创建获取服务器目录工具类GetServerRealPathUnit.java
import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion; import org.springframework.util.ResourceUtils; import java.io.File; import java.io.FileNotFoundException; /* **author:weijiakun *获取目录工具类 */ public class GetServerRealPathUnit { public static String getPath(String subdirectory){ //获取跟目录---与jar包同级目录的upload目录下指定的子目录subdirectory File upload = null; try { //本地测试时获取到的是"工程目录/target/upload/subdirectory File path = new File(ResourceUtils.getURL("classpath:").getPath()); if(!path.exists()) path = new File(""); upload = new File(path.getAbsolutePath(),subdirectory); if(!upload.exists()) upload.mkdirs();//如果不存在则创建目录 String realPath = upload + "/"; return realPath; } catch (FileNotFoundException e) { throw new RuntimeException("获取服务器路径发生错误!"); } } }
二、创建图片上传工具类SaveImgUnit.java
import org.springframework.web.multipart.MultipartFile; import sun.misc.BASE64Decoder; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Random; /* **author:weijiakun *上传图片工具类 */ public class SaveImgUnit { //以base64编码格式上传,将照片转成字节流 public static Map<String,String> getImg(String imageFile,String subdirectory){ // 通过base64来转化图片 String type = imageFile.substring(imageFile.indexOf("/")+1,imageFile.indexOf(";")); if (type.equals("png")){ imageFile = imageFile.replaceAll("data:image/png;base64,", ""); } if (type.equals("jpeg")){ imageFile = imageFile.replaceAll("data:image/jpeg;base64,", ""); } BASE64Decoder decoder = new BASE64Decoder(); // Base64解码 byte[] imageByte = null; try { imageByte = decoder.decodeBuffer(imageFile); for (int i = 0; i < imageByte.length; ++i) { if (imageByte[i] < 0) {// 调整异常数据 imageByte[i] += 256; } } } catch (Exception e) { e.printStackTrace(); } type = "." + type; return saveImg(imageByte,subdirectory,type); } //存储照片到服务器 private static Map<String,String> saveImg(byte[] imageByte,String subdirectory,String type){ // 生成文件名及文件类型 String files = new SimpleDateFormat("yyyyMMddHHmmssSSS") .format(new Date()) + (new Random().nextInt(9000) % (9000 - 1000 + 1) + 1000) + type; Map<String,String> map = new HashMap<>(); //获取跟目录---与jar包同级目录并生成文件路径 String filename = GetServerRealPathUnit.getPath(subdirectory) + files; try { // 生成文件 File imageFile = new File(filename); imageFile.createNewFile(); if(!imageFile.exists()){ imageFile.createNewFile(); } OutputStream imageStream = new FileOutputStream(imageFile); imageStream.write(imageByte); imageStream.flush(); imageStream.close(); map.put("res","success"); map.put("url",files); return map; } catch (Exception e) { e.printStackTrace(); map.put("res","error"); return map; } } //以MultipartFile方式上传到服务器 public static Map<String,String> saveMultFile(MultipartFile file,String subdirectory){ //上传文件路径 String path = GetServerRealPathUnit.getPath(subdirectory); //重新修改文件名防止重名 String filename = new SimpleDateFormat("yyyyMMddHHmmssSSS") .format(new Date()) + (new Random().nextInt(9000) % (9000 - 1000 + 1) + 1000) + file.getOriginalFilename(); File filepath = new File(path, filename); //判断路径是否存在,没有就创建一个 if (!filepath.getParentFile().exists()) { filepath.getParentFile().mkdirs(); } //将上传文件保存到一个目标文档中 Map<String ,String> map = new HashMap<>(); File file1 = new File(path + File.separator + filename); try { file.transferTo(file1); map.put("res","success"); map.put("url",filename); return map; } catch (IOException e) { map.put("res","error"); return map; } } }
需要注意的是,这里我通过base64编码格式上传图片只写了jpg和png格式的转换判断,如需支持更多图片格式只需在getImg()方法中添加图片类型判断即可。
三、创建图片上传controller接口
这里只举例以base64编码格式上传
/** **author:weijiakun */ @RestController public class GoodsImgController { @Autowired private GoodsImgService goodsImgService; /** **author:weijiakun **date:2018-09-11 * 上传以base64编码格式图片 */ @RequestMapping(value = "/addGoodsImg",method = RequestMethod.POST) public Map<String,Object> addGoodsImg(MultipartFile file){ if (file != null){ //上传文件 Map<String,String> map = goodsImgService.uploadGoodsImg(file); if (map.get("res").equals("success")){ //上传成功返回图片URL return ReturnMapUtil.getReturnMap(0,"success",map); }else{ return ReturnMapUtil.getReturnMap(1,"error"); } } } }
四、创建图片上传服务service
public interface GoodsImgService {
/**
**author:weijiakun
* 上传商品图片
*/
Map<String,String> uploadGoodsImg(MultipartFile file);
}
/** **author:weijiakun */ @Service(value = "goodsImgService") public class GoodsImgServiceImpl implements GoodsImgService { //注入配置文件application.yml中设置的图片存放子目录名 @Value("${upload.path.goodsImg}") private String GOODS_IMG_PATH; /** **author:weijiakun * 上传以base64编码格式图片 */ @Override public Map<String,String> uploadGoodsImg(MultipartFile file){ if (file != null){ //上传文件 Map<String,String> map = SaveImgUnit.saveMultFile(file,GOODS_IMG_PATH); return map; }else { Map<String,String> map = new HashMap<>(); map.put("res","error"); return map; } } }
至此,图片通过base64编码方式或MultipartFile方式上传至服务器与jar包同级的目录下。
五、访问服务器上的图片
由于图片上传的Linux目录存在权限问题,不允许用户随意访问,所以采用将图片转换为io流传输至服务器显示。
1.在上面创建的controller中添加一个/showImg接口
/**
*author:weijiakun
* IO流读取图片
* @param imgUrl 图片url
*/
@RequestMapping(value = "/showImg",method = RequestMethod.GET)
public void IoReadImage(String imgUrl HttpServletResponse response)throws IOException {
goodsImgService.IoReadImage(imgUrl,response);
}
2.添加服务层service业务方法IoReadImage()
/** *author:weijiakun * IO流读取图片 * @param imgUrl 图片url,即图片保存在服务器上的名称 */ @Override public void IoReadImage(String imgUrl, HttpServletResponse response) throws IOException { ServletOutputStream out = null; FileInputStream ips = null; String upload = null; //获取商品图片目录 upload = GetServerRealPathUnit.getPath(GOODS_IMG_PATH); try { //获取图片存放路径 String imgPath = upload + "/" + imgUrl; ips = new FileInputStream(new File(imgPath)); String type = imgUrl.substring(imgUrl.indexOf(".")+1); if (type.equals("png")){ response.setContentType("image/png"); } if (type.equals("jpeg")){ response.setContentType("image/jpeg"); } out = response.getOutputStream(); //读取文件流 int len = 0; byte[] buffer = new byte[1024 * 10]; while ((len = ips.read(buffer)) != -1){ out.write(buffer,0,len); } out.flush(); }catch (Exception e){ e.printStackTrace(); }finally { out.close(); ips.close(); } }
3.在前端中使用<img src="http://localhost:端口/showImg?imgUrl=xxx" />
即可访问并在浏览器显示图片。
六、参考资料
https://blog.csdn.net/qq_39529566/article/details/81872062
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。