文章目录

  • 一、遇到的问题
  • 二、将jar导入maven仓库
  • 三、android客户端生成base64
  • 四、Java接口base64转文件
一、遇到的问题

1.Java中直接使用spring框架提供的工具包来实现,Web页面生成的Base64正常解码,但是Android客户端生成的Base64解码报错,错误信息为:Illegal base64 character a, data=null]。
spring 原生框架提供jar将base64转图片核心代码如下:

 byte[] bs = Base64Utils.decodeFromString(data);try{//使用apache提供的工具类操作流FileUtils.writeByteArrayToFile(new File("D:", tempFileName), bs);  }catch(Exception ee){throw new Exception("上传失败,写入文件失败,"+ee.getMessage());}

2.Android客户端提交的Base64使用BASE64Decoder包生成的图片是破损的,原因是可能是没有拼接前缀data:image/jpeg;base64,或者是上传的过程中数据发生了改变。通过浏览器上http://imgbase64.duoshitong.com/,生成base64如下:

生成图片的base64可知,base6前拼接data:image/jpeg;base64,来标识这个base64应该生成什么类型的文件,所以客户端生成的base64也有拼上这段标识,而后台接口接收到数据时先要截取,根据标识去生成文件。

二、将jar导入maven仓库

找了半天找到BASE64Decoder真是太happy了,然而访问到生成图片的代码时却报classNotFoundException,找不到这个包的类,但包明明已经导入到里面去了,编译能通过,但是运行到对应的类就报错了。原因是:通过右键项目Build Path —>Configure Build Path… —>Add External JARS 这样导入的jar包 只存在工作环境当中,当项目部署到tomcat以后,webapp文件夹下的项目文件夹中并不会存在我们的jar包。解决这个问题的方式有两种方法:
1、在WEB-INF下建一个文件夹 lib,把jar包 copy 进去,这样在部署项目的时候就会将jar也部署进去了。
2、将jar导入maven中,生成对应的pom版本。
将jar导入maven的指令:

./mvn install:install-file -Dfile="/Users/linxz/Desktop/jar/sun.misc.BASE64Decoder.jar" -DgroupId=sun.misc.base64decoder -DartifactId=sun.misc.base64decoder -Dversion=1.0.0 -Dpackaging=jar

如果是windows系统,则不要前面的./。

/Users/linxz/Desktop/jar/sun.misc.BASE64Decoder.jar为jar包的位置,DgroupId为项目组ID,DartifactId为项目ID,我这里皆用包名命名,Dversion为当前生成的版本号。这里就有点像android里生成aar部署到Nexus Maven仓库。Nexus搭建Maven私服

执行指令结果如下则表示打包成功:

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] --- maven-install-plugin:2.4:install-file (default-cli) @ standalone-pom ---
[INFO] Installing /Users/linxz/Desktop/jar/sun.misc.BASE64Decoder.jar to /Users/linxz/java/localmaven/sun/misc/base64decoder/sun.misc.base64decoder/1.0.0/sun.misc.base64decoder-1.0.0.jar
[INFO] Installing /var/folders/q9/ysm4v_fx14110jhts8dcw5s00000gn/T/mvninstall3804221028910250225.pom to /Users/linxz/java/localmaven/sun/misc/base64decoder/sun.misc.base64decoder/1.0.0/sun.misc.base64decoder-1.0.0.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.290 s
[INFO] Finished at: 2019-10-12T08:38:08+08:00
[INFO] ------------------------------------------------------------------------
linxzdeMacBook-Pro:bin linxz$ 

Installing /Users/linxz/Desktop/jar/sun.misc.BASE64Decoder.jar to /Users/linxz/java/localmaven/sun/misc/base64decoder为生成的包在我本地maven的路径,可以去该路径下查看是否真的存在:
这时候我们可以在代码中通过maven的方式导入:

<dependency><groupId>sun.misc.base64decoder</groupId><artifactId>sun.misc.base64decoder</artifactId><version>1.0.0</version>
</dependency>
三、android客户端生成base64
 public static String getBase64FromFilePath(String path){InputStream inputStream = null;byte[] data = null;try {inputStream = new FileInputStream(path);data = new byte[inputStream.available()];inputStream.read(data);inputStream.close();} catch (IOException e) {e.printStackTrace();}// 加密BASE64Encoder encoder = new BASE64Encoder();String base64=encoder.encode(data);base64="data:image/jpeg;base64,"+base64;return base64;}
四、Java接口base64转文件

核心代码;

public static boolean base64ToImage(String imgStr,String imgFilePath) {if (StringUtils.isEmpty(imgStr)) return false;File file =new File(imgFilePath);File fileParent=file.getParentFile();if(!fileParent.exists()) {fileParent.mkdirs();}BASE64Decoder decoder = new BASE64Decoder();try {byte[] b = decoder.decodeBuffer(imgStr);for (int i = 0; i < b.length; ++i) {if (b[i] < 0) {// 调整异常数据b[i] += 256;}}OutputStream out = new FileOutputStream(imgFilePath);out.write(b);out.flush();out.close();return true;} catch (Exception e) {e.printStackTrace();return false;}}

将传输过程中发生改变的字符替换回来:

base64=base64.replaceAll(" ","+");
base64=base64.replaceAll("[\\s*\t\n\r]", "");

文件路径不存在则创建对应文件夹:

File file =new File(imgFilePath);
File fileParent=file.getParentFile();
if(!fileParent.exists()) {fileParent.mkdirs();
}

我项目中的业务处理方式:验证base64非空->验证用户token->验证当前用户状态时候可用->将传输过程中被修改的base64替换回来->根据拼接的前缀判断当前base64属于什么类型文件->判断生成文件的地址路径是否存在不存在则生成对应的路径文件夹->base64开始转文件。

@Overridepublic LinxzResult upLoadImg(FileParams fileParams) {try {if (StringUtils.isEmpty(fileParams.getBase64())) {return LinxzResult.build(ResponseCodeUtils.CODE_PARAMS_EMPTY, "长传失败,上传图片不能为空");}//校验用户String token = fileParams.getToken();if(StringUtils.isEmpty(token)){return LinxzResult.build(ResponseCodeUtils.CODE_PERMISSION_ERRO, "token错误");}String userId=TokenUtils.getUserId(token);BaseUser user=baseUserMapper.selectByUserId(userId);if(user==null || !token.equals(user.getToken())){return LinxzResult.build(ResponseCodeUtils.CODE_PERMISSION_ERRO, "token错误");}if(!UserConfig.USER_STATUS_NORMAL.equals(user.getStattus())){return LinxzResult.build(ResponseCodeUtils.CODE_PERMISSION_ERRO, "用户异常");}String base64=fileParams.getBase64();base64=base64.replaceAll(" ","+");base64=base64.replaceAll("[\\s*\t\n\r]", "");System.out.println("上传文件的数据:" + base64);String dataPrix = "";String data = "";String[] d = base64.split("base64,");if (d != null && d.length == 2) {dataPrix = d[0];data = d[1];} else {return LinxzResult.build(ResponseCodeUtils.CODE_UNKNOWED_ERRO, "上传失败,数据不合法");}String suffix = "";if ("data:image/jpeg;".equalsIgnoreCase(dataPrix)) {// data:image/jpeg;base64,base64编码的jpeg图片数据suffix = ".jpg";} else if ("data:image/x-icon;".equalsIgnoreCase(dataPrix)) {// data:image/x-icon;base64,base64编码的icon图片数据suffix = ".ico";} else if ("data:image/gif;".equalsIgnoreCase(dataPrix)) {// data:image/gif;base64,base64编码的gif图片数据suffix = ".gif";} else if ("data:image/png;".equalsIgnoreCase(dataPrix)) {// data:image/png;base64,base64编码的png图片数据suffix = ".png";} else {return LinxzResult.build(ResponseCodeUtils.CODE_UNKNOWED_ERRO, "上传图片格式不合法");}String tempFileName = getRandomFileName() + suffix;String homePath = "/Users/linxz/Pictures/streamlet/";String folderName="";if (!StringUtils.isEmpty(fileParams.getFolderName())) {folderName = fileParams.getFolderName();}homePath = homePath+folderName+"/"+user.getUserId()+"/"+tempFileName;boolean success=Base64Util.base64ToImage(data, homePath);if(success) {System.out.println("生成文件名为:" + homePath);return LinxzResult.build(ResponseCodeUtils.CODE_SUCCESS, "长传成功", folderName + "/" + user.getUserId()+"/"+tempFileName);}else {return LinxzResult.build(ResponseCodeUtils.CODE_UNKNOWED_ERRO, "上传失败,写入文件失败");}} catch (Exception e) {return LinxzResult.build(ResponseCodeUtils.CODE_UNKNOWED_ERRO, "长传失败" + e.getMessage());}}

之前一直觉得,开发接口之后postman请求没问题就证明接口是可用的,剩下的就是客户端的问题,这个图片上传使用Srping的包,postman请求网页生成的base64没问题,可是android原生bas4工具类生成的base64就是死活解码失败,改变了我接口对接的一些看法。

Base64方式上传文件相关推荐

  1. koa2:通过Ajax方式上传文件,使用FormData进行Ajax请求

    koa2通过表单上传的网上很多,但通过Ajax方式上传文件,使用FormData进行Ajax请求,不好找. 参考了这个用base64上传图片的例子.https://github.com/Yuki-Mi ...

  2. jquery ajax java上传文件_jQuery Ajax方式上传文件的方法

    jQuery Ajax方式上传文件用到两个对象 第一个对象:FormData 第二个对象:XMLHttpRequest 目前新版的Firefox 与 Chrome 等支持HTML5的浏览器完美的支持这 ...

  3. 转:vc中如何通过http的post方式上传文件

    文章引自:http://blog.myspace.cn/e/404248359.htm vc中如何通过http的post方式上传文件 HTTP响应     在接收和解释请求消息后,服务器会返回一个HT ...

  4. java序列化表单同步请求_Ajax serialize() 表单进行序列化方式上传文件

    通过传统的 form 表单提交的方式上传文件 上传文件: 不过传统的 form 表单提交会导致页面刷新,但是在有些情况下,我们不希望页面被刷新,这种时候我们都是使用 Ajax 的方式进行请求的. 使用 ...

  5. 前端js以application/octet-stream方式上传文件

    今天又学会了一种上传文件的文件流方法. 本人后端采用了CXF框架实现的 api层 package com.inspur.gs.tax.tbs.utils;import org.glassfish.je ...

  6. python post 上传文件_Python通过POST方式上传文件及提交参数到远程服务器

    前言 在树莓派开发过程中,因为没有公网IP,为了方便访问获取信息,有时候我们需要将树莓派获取到的一些数据或文件上传到云端服务器.这是一个比较简便的方法. Python代码 需要用到requests库, ...

  7. idea构建post请求_IntelliJ IDEA 模拟 POST方式 上传文件

    IntelliJ IDEA 模拟 POST方式 上传文件 IntelliJ IDEA 集成了 HTTP Request,再没有postman的场景下,也可以很方便地模拟各种 HTTP 请求方式的场景. ...

  8. Ajax方式上传文件报错Uncaught TypeError: Illegal invocation

    今天使用ajax上传文件时,出现了错误.数据传输的方式是通过定义formData完成的,提交的文件对象也设置为dom对象,但是还是不能发送请求.F12看到后台报了个错误:Uncaught TypeEr ...

  9. 向PHP使用Post方式上传文件

    1.post-file.html form表单提交方式一定要是post,而且添加属性enctype="multipart/form-data" <!DOCTYPE html& ...

最新文章

  1. 针对IE6\7\8\9\10浏览器的CSS hack大全详解
  2. LeetCode Single Number
  3. Android中TimePicker时间选择器的使用和获取选择的时和分
  4. mac lion 安装 mysql_mac osx下安装mysql
  5. leetcode214. 最短回文串(kmp)
  6. [LeetCode] Plus One
  7. OpenCV实战5: LBP级联分类器实现人脸检测
  8. ubuntu 下安装apache服务器
  9. linux服务器用户组和权限管,linux 用户管理,用户权限管理,用户组管理
  10. MySQL:MySQL InnoDB引擎
  11. 常用技巧性CSS:颜色渐变,截断英文单词,阴影文字.
  12. zoj 3620 Escape Time II dfs
  13. ZeroMQ使用教程
  14. tdk磁材手册_TDK磁性材料市场.ppt
  15. 33个训练大脑的小方法
  16. Stone教程:一行代码就可以把3D场景植入到普通网页中
  17. 6 - 常用模块(os,sys,timedatetime,random,jsonpicle,shelve,hashlib)
  18. 史上最全量化交易资源整理
  19. 连接手表_小米手表配对时间长、断开连接后一直连不上怎么办?
  20. Android 固件,刷固件,ROM包

热门文章

  1. Docker:从入门到入门
  2. java使用465端口发送邮件
  3. PLC工程师必备知识— IO模块选型和使用(上篇)
  4. U盘文件丢失求恢复教程
  5. PE系统下安装windows server 2003
  6. 心态很容易受别人影响_太容易被别人影响,我上辈子可能是个“复印机”
  7. docker _port is already allocated错误
  8. 直面大数据撞击这个时代——畅享网成功举办大数据应用沙龙
  9. 靶机测试-bulldog
  10. python人物抠图算法_Python实现AI自动抠图实例解析