java jdk base64,jdk1.8 Base64Util Illegal base64 character

jdk1.8 base64的编码转码

实用场景

最近工作上有个需求,需要根据图片的url下载到本地,并且客户端无法访问到url只能接收base64图片码。因此决定采用jdk自带的Base64进行编码转码存储。

小插曲

采用了两个工具类:ImageUtil和Base64Util。ImageUtil用于实际操作。Base64Util用于统一编码格式。

由于jdk1.7和jdk1.8内置的Base64遵守的RFC协议不一致,jdk1.7按照照RFC1521实现的,jdk1.8是按照rfc4648和rfc2045两个协议来实现的。具体可以从类注释中查询到。由于协议的不同可能导致jdk1.8的解码jdk1.7编码的数据时抛出java.lang.IllegalArgumentException: Illegal base64 character a异常.因此需要特别注意保持解码编码的一致性。

jdk7的编码结果包含换行;

jdk8的编码结果不包含换行;

jdk8无法解码包含换行的编码结果;

既然得知上述异常产生的由于,故找到解决方案也很简单。

使用apache common包中的org.apache.commons.codec.binary.Base64类进行编码和解码;

编码之后或解码之前去除换行符;

编码和解码使用相同的jdk版本;

附上代码

ImageUtils

import javax.imageio.ImageIO;

import javax.swing.*;

import java.awt.*;

import java.awt.image.BufferedImage;

import java.io.*;

import java.net.HttpURLConnection;

import java.net.URL;

public class ImageUtils {

/**

* base64转文件地址

*

* @param filePath

* @param base64

* @param fileName

*/

public static void base64ToImg(String filePath, String base64, String fileName) {

File file = null;

//创建文件目录

File dir = new File(filePath);

if (!dir.exists() && !dir.isDirectory()) {

dir.mkdirs();

}

BufferedOutputStream bos = null;

java.io.FileOutputStream fos = null;

try {

byte[] bytes = Base64Util.decode(base64);

file = new File(filePath + fileName);

fos = new java.io.FileOutputStream(file);

bos = new BufferedOutputStream(fos);

bos.write(bytes);

} catch (Exception e) {

e.printStackTrace();

} finally {

if (bos != null) {

try {

bos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (fos != null) {

try {

fos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

}

/**

* 通过Toolkit获取base64

*

* @param url

* @return

* @author caoting

* @date 2018年11月21日

*/

public static String getBase64ByImgUrl(String url) {

String suffix = url.substring(url.lastIndexOf(".") + 1);

try {

URL urls = new URL(url);

ByteArrayOutputStream baos = new ByteArrayOutputStream();

Image image = Toolkit.getDefaultToolkit().getImage(urls);

BufferedImage biOut = toBufferedImage(image);

ImageIO.write(biOut, suffix, baos);

String base64Str = Base64Util.encode(baos.toByteArray());

return base64Str;

} catch (Exception e) {

return "";

}

}

public static BufferedImage toBufferedImage(Image image) {

if (image instanceof BufferedImage) {

return (BufferedImage) image;

}

// This code ensures that all the pixels in the image are loaded

image = new ImageIcon(image).getImage();

BufferedImage bimage = null;

GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();

try {

int transparency = Transparency.OPAQUE;

GraphicsDevice gs = ge.getDefaultScreenDevice();

GraphicsConfiguration gc = gs.getDefaultConfiguration();

bimage = gc.createCompatibleImage(image.getWidth(null), image.getHeight(null), transparency);

} catch (HeadlessException e) {

// The system does not have a screen

}

if (bimage == null) {

// Create a buffered image using the default color model

int type = BufferedImage.TYPE_INT_RGB;

bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), type);

}

// Copy image to buffered image

Graphics g = bimage.createGraphics();

// Paint the image onto the buffered image

g.drawImage(image, 0, 0, null);

g.dispose();

return bimage;

}

/**

* 通过下载二进制流的方式获取base64

*

* @param imgUrl 图片url

* @return 返回图片base64的字符串

*/

public static String image2Base64(String imgUrl) {

URL url = null;

InputStream is = null;

ByteArrayOutputStream outStream = null;

HttpURLConnection httpUrl = null;

try {

url = new URL(imgUrl);

httpUrl = (HttpURLConnection) url.openConnection();

httpUrl.connect();

httpUrl.getInputStream();

is = httpUrl.getInputStream();

outStream = new ByteArrayOutputStream();

// 创建一个Buffer字符串

byte[] buffer = new byte[1024];

// 每次读取的字符串长度,如果为-1,代表全部读取完毕

int len = 0;

// 使用一个输入流从buffer里把数据读取出来

while ((len = is.read(buffer)) != -1) {

// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度

outStream.write(buffer, 0, len);

}

// 对字节数组Base64编码

return Base64Util.encode(outStream.toByteArray());

} catch (Exception e) {

e.printStackTrace();

} finally {

if (is != null) {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (outStream != null) {

try {

outStream.close();

} catch (IOException e) {

e.printStackTrace();

}

}

if (httpUrl != null) {

httpUrl.disconnect();

}

}

return imgUrl;

}

}

Base64Util

import sun.misc.BASE64Decoder;

import sun.misc.BASE64Encoder;

import javax.imageio.stream.FileImageInputStream;

import java.io.ByteArrayOutputStream;

import java.io.File;

import java.io.IOException;

import java.util.regex.Matcher;

import java.util.regex.Pattern;

public class Base64Util{

/**

* 字符串转图片

* @param base64Str

* @return

*/

public static byte[] decode(String base64Str){

byte[] b = null;

BASE64Decoder decoder = new BASE64Decoder();

try {

b = decoder.decodeBuffer(replaceEnter(base64Str));

} catch (IOException e) {

e.printStackTrace();

}

return b;

}

/**

* 图片转字符串

* @param image

* @return

*/

public static String encode(byte[] image){

BASE64Encoder decoder = new BASE64Encoder();

return replaceEnter(decoder.encode(image));

}

public static String encode(String uri){

BASE64Encoder encoder = new BASE64Encoder();

return replaceEnter(encoder.encode(uri.getBytes()));

}

/**

*

* @path 图片路径

* @return

*/

public static byte[] imageTobyte(String path){

byte[] data = null;

FileImageInputStream input = null;

try {

input = new FileImageInputStream(new File(path));

ByteArrayOutputStream output = new ByteArrayOutputStream();

byte[] buf = new byte[1024];

int numBytesRead = 0;

while((numBytesRead = input.read(buf)) != -1){

output.write(buf, 0, numBytesRead);

}

data = output.toByteArray();

output.close();

input.close();

} catch (Exception e) {

e.printStackTrace();

}

return data;

}

public static String replaceEnter(String str){

String reg ="[\n-\r]";

Pattern p = Pattern.compile(reg);

Matcher m = p.matcher(str);

return m.replaceAll("");

}

}

bVbqKv3?w=600&h=600

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值