java的图片上传详解

1.场景还原

    近期,由于项目需求需要上传图片logo,笔者在探索的过程中遇到过很多坑,今晚就把个人经验分享出来尽量少让博友们脑壳疼

2.准备工作

 ①选择一个专门存储图片的服务器,这里笔者选择了第三方七牛云存储,真心感觉不错!

java的图片上传详解_第1张图片

 ②前端与后台采用Ajax交互

3.前端代码

①代码分析

 




File upload



 

 

 

②重点分析

 

  • append()的第二个参数应是文件对象,即$('#file')[0].files[0]contentType也要设置为‘false’。
  • 从代码$('#file')[0].files[0]中可以看到一个标签能够上传多个文件,只需要在里添加multiplemultiple="multiple"属性。对了这里的dataType一定别忘了写json,不然会解析失败的。
  •  
  • ③看效果
  • java的图片上传详解_第2张图片

 

4.后台代码

①导入相关依赖

 

  


  com.google.code.gson
  gson
  2.8.0



  com.squareup.okhttp3
  okhttp
  3.6.0



  com.squareup.okio
  okio
  1.11.0



  com.qiniu
  qiniu-java-sdk
  7.1.3




  commons-io
  commons-io
  2.3




  commons-fileupload
  commons-fileupload
  1.2.2

②定义七牛上传图片并返回外链的方法

 

 

/**
 * Created by zhangxing on 2017/6/7.
 */
public class QiniuUpload {
    private String picFile;
    private String picUrl = "";
    public QiniuUpload(String path){
        picFile = path;
    }
     private static final String SPOT= "http://om8czer7p.bkt.clouddn.com/";//baseUrl
    //设置好账号的ACCESS_KEY和SECRET_KEY
    String ACCESS_KEY = "你的ACCESS_KEY"; //这两个登录七牛 账号里面可以找到
    String SECRET_KEY = "你的SECRET_KEY";

    //要上传的空间
    String bucketname = "zhangxing"; //填写新建的那个存储空间对象的名称
    //上传到七牛后保存的文件名
    String key = new Date().getTime()+".jpg";
    //上传文件的路径
    //String FilePath = "E:\\1.jpg";  //本地要上传文件路径

    //密钥配置
    Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
    //创建上传对象
    UploadManager uploadManager = new UploadManager();

    //简单上传,使用默认策略,只需要设置上传的空间名就可以了
    public String getUpToken(){
        return auth.uploadToken(bucketname);
    }
    //普通上传
    public String upload() throws IOException {
        try {
            //调用put方法上传
            Response res = uploadManager.put(picFile, key, getUpToken());
            //打印返回的信息
            System.out.println(res.isOK());
            if(res.isOK()){
                picUrl = SPOT+ key;
                System.out.println(picUrl);

            }else{
                System.out.println("上传失败!");
            }
            
            System.out.println(res.bodyString());
        } catch (QiniuException e) {
            Response r = e.response;

            System.out.println(r.url());
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                //响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
        return picUrl;
    }
   
}

 

记住,这个方法返回的是图片访问的外链。

③配置spring-web

 


    
    

将上述代码原原本本贴在spring-web中

 

④上传的controller

 

@RestController
@RequestMapping("qiniu")
public class QinNiuController extends BaseController {

    @RequestMapping(value = "/upload",method = RequestMethod.POST)
    public String upload(HttpServletResponse response,@RequestParam("file") MultipartFile file) throws IOException {
        response.setHeader("Access-Control-Allow-Origin","*");
        String fileName=file.getOriginalFilename();
        File targetFile=new File("F:\\picture",fileName);
        if(!targetFile.exists()){
            targetFile.mkdirs();
        }
        try{
            file.transferTo(targetFile);
        }catch(Exception e){
            e.printStackTrace();
        }
          String str = new QiniuUpload(targetFile.getAbsolutePath()).upload();
        //str得到的是一个七牛返回的外链,然后将str存到自己的服务器
        return success(str);
    }
}

注意:部署到云服务器后,就不存在本地路径F盘了,

ssm项目路径代码:

 

String filePath = "upload/img";
String fileName=file.getOriginalFilename();
File targetFile=new File(filePath,fileName);
if(!targetFile.exists()){
    targetFile.mkdirs();
}

springboot项目中路径代码:

 

 

 String key="";
 String fileName=file.getOriginalFilename();
// file.getInputStream();
 File targetFile=new File(File.separator,fileName);
 /*if(!targetFile.exists()){
     targetFile.mkdirs();
 }*/
 //
 if(fileName.endsWith(".jpg")){
     key = new Date() +".jpg";
 }else if(fileName.endsWith(".png")){
     key = new Date()+".png";
 }else if(fileName.endsWith(".gif")){
     key = new Date()+".gif";
 }

 

这样图片就临时保存在linux下的tomcat的ROOT目录下;

key表示图片的自定义名称;

⑤BaseController

 

public class BaseController {
   protected Logger log = LoggerFactory.getLogger(getClass());
   protected Logger bizErrorLog = LoggerFactory.getLogger("biz_log");
   private final static ThreadLocal request = new ThreadLocal();
   private final static ThreadLocal response = new ThreadLocal();
   protected final Integer DEFAULT_PAGE_SIZE = 20;

   public HttpServletRequest req;
   public HttpServletResponse resp;
   public HttpSession session;

   @ModelAttribute
   public void req(HttpServletResponse response,HttpServletRequest request){
      this.req = request;
      this.resp = response;
      this.session = request.getSession();
   }


   @SuppressWarnings("static-access")
   @ModelAttribute
   public void init(final HttpServletRequest request,
         final HttpServletResponse response) {
      this.response.set(response);
      this.request.set(request);
   }
   protected HttpServletRequest getRequest() {
      return request.get();
   }

   protected HttpServletResponse getResponse() {
      return response.get();
   }
   
   @InitBinder
   protected void initBinder(final HttpServletRequest request,
         final ServletRequestDataBinder binder) throws Exception {
      binder.addValidators(new ParamValidator());
   }
   /**
    * 获取当前用户
    */
   public User getCurrentUser() {
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();

      if (auth != null) {
         Object principal = auth.getPrincipal();
         if (principal instanceof User) {
             User user = (User) principal;
             if (user != null && !user.isAnonymous() ) {
                 return user;
             }
         }

         if (auth.getClass().getSimpleName().indexOf("Anonymous") < 0) {              
             log.error("Unknown authentication encountered, ignore it. " + auth);
         }
      }
      throw new BizException(GlobalErrorCode.UNAUTHORIZED, "need login first.");
   }
   
   /**
    * 成功
    */
   @SuppressWarnings({ "rawtypes", "unchecked" })
   public String  success(Object obj) {
      ResponseObject result = new ResponseObject();  
       result.setData(obj);   
       String  str = JSON.toJSONString(result);
       String callback = getRequest().getParameter("callback");
       if(!SysStringUtils.isEmpty(callback)) {
           str = callback+"("+str+")";
           return str;
       }
       return  str;
   }
   
   public String chinaToUnicode(String str){  
        String result="";  
        for (int i = 0; i < str.length(); i++){  
            int chr1 = str.charAt(i);  
            if(chr1>=19968&&chr1<=171941){//汉字范围 \u4e00-\u9fa5 (中文)  
                result+="\\u" + Integer.toHexString(chr1);  
            }else{  
                result+=str.charAt(i);  
            }  
        }  
        return result;  
    } 
   
   @SuppressWarnings({ "rawtypes", "unchecked" })
   public String  success(Object obj,String score) {
      ResponseObject result = new ResponseObject();
      result.setScore(score);
       result.setData(obj);   
       return  JSON.toJSONString(result);    
   }
   
   public String  convertToJsonp(String str) {
       String callback = getRequest().getParameter("callback");
       if(!SysStringUtils.isEmpty(callback)) {
           str = callback+"("+str+")";
           return str;
       }
       return  str;
   }
   
   @SuppressWarnings({ "rawtypes" })
   public String  success() {
      ResponseObject result = new ResponseObject();         
       return  JSON.toJSONString(result,SerializerFeature.WriteMapNullValue,SerializerFeature.WriteNonStringKeyAsString);    
      
   }
   @SuppressWarnings({ "rawtypes" })
   public String  fail() {
      ResponseObject result = new ResponseObject();         
       return JSON.toJSONString(result);     
   }
   
   /**
    * 参数不正确
    */
   @SuppressWarnings({ "rawtypes" })
   public String argumentError(String msg) {
      ResponseObject result = new ResponseObject(GlobalErrorCode.INVALID_ARGUMENT);
      result.setMoreInfo(msg);
      return JSON.toJSONString(result);  
   }
   /**
    * 逻辑错误
    */
   public String error(String msg) {
      throw new BizException(GlobalErrorCode.UNKNOWN, msg);
   }
}

 

好了,走完整个流程看上传效果:

java的图片上传详解_第3张图片

好了,七牛的图片外链就拿到了,然后记得存一把数据库。

 

补充:字节数组上传

 

①上传类文件

public class QiniuUpload {

    private String SPOT= Constant.QINIU_BASE_URL; //七牛baseUrl
    private String ACCESS_KEY = Constant.QINIU_AK; //设置账号的ACCESS_KEY
    private String SECRET_KEY = Constant.QINIU_SK; //设置账号的SECRET_KEY
    private String bucketname = Constant.QINIU_DOMAIN;//要上传的存储空间对象的名称

    private byte[] data;
    private String picUrl = "";
    private String key = "";
    public QiniuUpload(byte[] mData, String ikey){
        data = mData;
        key = ikey;
    }
    //密钥配置
    Auth auth = Auth.create(ACCESS_KEY, SECRET_KEY);
    //创建上传对象
    UploadManager uploadManager = new UploadManager();

    //简单上传,使用默认策略,只需要设置上传的空间名就可以了
    public String getUpToken(){
        return auth.uploadToken(bucketname);
    }
    //普通上传
    public String upload() throws IOException {
        try {
            //调用put方法上传
            Response res = uploadManager.put(data, key, getUpToken());
            //打印返回的信息
            System.out.println(res.isOK());
            if(res.isOK()){
                picUrl = SPOT+ key;
                System.out.println("图片链接:"+picUrl);

            }else{
                System.out.println("上传失败!");
            }

            System.out.println(res.bodyString());
        } catch (QiniuException e) {
            Response r = e.response;

            System.out.println(r.url());
            // 请求失败时打印的异常的信息
            System.out.println(r.toString());
            try {
                //响应的文本信息
                System.out.println(r.bodyString());
            } catch (QiniuException e1) {
                //ignore
            }
        }
        return picUrl;
    }

}
②七牛静态配置信息
//七牛相关配置信息
public static final String QINIU_DOMAIN="zhangxing";
public static final String QINIU_BASE_URL = "http://oihgq7pcj.bkt.clouddn.com/";
public static final String QINIU_AK = "Qg59MUtOKqiz-uvynQIakrJg4o7t9-LVy-0WmRto";
public static final String QINIU_SK = "XytEWfSlh3Wb7BgFQDSo7OYVNT7QOApiMQlRdzG3";
③controller代码
@CrossOrigin
@CommonsLog
@RestController
@RequestMapping("/qiniu")
public class QiNiuController extends BaseController{
    private static final Logger logger = LoggerFactory.getLogger("qiniu_log");

    @Autowired
    private CompanyService companyService;

    @PostMapping(value = "/upload/{companyId}")
    public ResultInfo upload(@RequestParam("file") MultipartFile file,@PathVariable("companyId") Integer companyId) throws IOException {
        String key;
        if(file != null){
            key = judgeFileName(file.getOriginalFilename());
        }else{
            return success("文件未选中");
        }

        String str = new QiniuUpload(file.getBytes(),key).upload();
        //str得到的是一个七牛返回的外链,然后将str存到自己的服务器
       int i = 0;
       if(companyId != null && companyId >0){
           Company company = companyService.selectByPrimaryKey(companyId) ;
           company.setThumbnails(str);
            i=  companyService.updateByPrimaryKeySelective(company);
           log.info("图片外链地址为"+str);
       }
        return i>0?success(str):success("上传失败");
    }

    /**
     * 根据后缀格式定义图片名称
     * @param fileName
     * @return
     */
    public String judgeFileName(String fileName){
        if(fileName.endsWith(".jpg")){
            return new Date().getTime()+".jpg";
        }else if(fileName.endsWith(".png")){
            return new Date().getTime()+".png";
        }else if(fileName.endsWith(".gif")){
            return new Date().getTime()+".gif";
        }else{
            return "请上传图片格式的文件";
        }
    }
}

效果图:

java的图片上传详解_第4张图片

另外一种方案:将临时文件暂储在linux中/tmp下

           // 获取文件名
            String fileName = file.getOriginalFilename();
            // 获取文件后缀
            String prefix = fileName.substring(fileName.lastIndexOf("."));
            // 用uuid作为文件名,防止生成的临时文件重复
            File localFile = File.createTempFile(UUID.randomUUID().toString(), prefix);
            // MultipartFile to File
            file.transferTo(localFile);

然后引用loclFile进行真正的file上传

上传完后删除loclFile

private void deleteFile(File... files) {
        for (File file : files) {
            if (file.exists()) {
                file.delete();
            }
        }
    }

 

这样就不用为图片的临时存储路径发愁了,笔者建议使用补充形式的图片上传;好了,我是张星,欢迎加入博主技术交流群,群号:313145288

 

你可能感兴趣的:(java)