【JAVA秒会技术之搞定BLOB数据类型】如何读取及展示数据库中BLOB类型的图片-阿里云开发者社区

开发者社区> 开发与运维> 正文

【JAVA秒会技术之搞定BLOB数据类型】如何读取及展示数据库中BLOB类型的图片

简介: 如何读取及展示数据库中BLOB类型的图片    【前言】最近在做某一需求时,需要从Oracle数据库读取图片。本以为数据库存储的会是一个简单的url,前台可以直接展示,结果却发现是BLOB二进制类型,于是乎,百度/Google了关键字“二进制图片读取及展示”,发现有很多“抄来抄去”的文章或博客,但是文章的质量都很低,而且结构比较混乱,看完之后仍然是“不明所以”。     最后,花了近2

如何读取及展示数据库中BLOB类型的图片

   【前言】最近在做某一需求时,需要从Oracle数据库读取图片。本以为数据库存储的会是一个简单的url,前台可以直接展示,结果却发现是BLOB二进制类型,于是乎,百度/Google了关键字“二进制图片读取及展示”,发现有很多“抄来抄去”的文章或博客,但是文章的质量都很低,而且结构比较混乱,看完之后仍然是“不明所以”。

    最后,花了近2个小时,耐心研究了一下,终于成功。于是总结如下,供大家参考,也作为自己积累备份所用!

      【核心点

       1.在PO类中用byte[]类型直接接受BLOB类型;

       2.将二进制转为Base64格式字符串(不要用sun.misc.BASE64Encoder类);

       3.前台html页面通过<img src="data:image/png;base64,{图片字段}"/>标签展示。

        1.需求概述

        ①从Oracle数据库的表中读取BLOB类型图片;

        ②在前端页面将图片展示出来。

        2.创建PO类,PO类中用byte[]类型直接接受BLOB类型 

package com.netease.numen.plus.netease.model;
import java.io.Serializable;
/**
 * 读取二进制blob类型图片
 * <p>Title: PhotoBytes</p>
 * @author  Liyan
 * @date    2017年3月6日 下午5:02:22
 */
public class PhotoBytes implements Serializable {
	private static final long serialVersionUID = -8775612234303127935L;
	/**二进制图片*/
	private byte[] photoBytes;
	public byte[] getPhotoBytes() {
		return photoBytes;
	}
	public void setPhotoBytes(byte[] photoBytes) {
		this.photoBytes = photoBytes;
	}	
}

        3.编写Mapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.**.netease.mapper.WorkCardMapper">

	<resultMap id="photoBytes" type="com.**.netease.model.PhotoBytes">
		<result column="PHOTO" property="photoBytes" />
	</resultMap>

	<!-- 根据员工工号查询照片 -->
	<select id="getPhoto" resultMap="photoBytes">
		SELECT
			PHOTO as photoBytes
		FROM
			EHRINBOUND.EHR_EMPLOYEE_PHOTO_V
		<where>
			<if test="jobNumber!=null">
				AND EHR_EMPLOYEE_CODE = #{jobNumber} 
			</if>
		</where>
	</select>
	
</mapper>

        4.编写Mapper.java文件

@Repository
public interface WorkCardMapper {
	public PhotoBytes getPhoto(Map<String, Object> param) throws Exception;
}

        5.编写Service.java文件

public interface WorkCardService {	
	public PhotoBytes getPhoto(final String jobNumber) throws Exception;
}

        6.编写ServiceImpl.java文件

@Service("workCardService")
public class WorkCardServiceImpl implements WorkCardService{
	@Inject
	WorkCardMapper mapper;
	@Override
	public  PhotoBytes getPhoto(String jobNumber) throws Exception {
        Map<String, Object> param = new HashMap<String, Object>(0);
	    param.put("jobNumber", jobNumber);
	}
}

        7.编写二进制流转Base64字符串的工具类

package com.netease.numen.plus.netease.util;
import java.io.IOException;
import org.apache.commons.codec.binary.Base64;
public class Base64ImageUtil {
	/**
	 * 二进制流转Base64字符串
	 * <p>Title: byteArr2String</p>
	 * @author Liyan
	 * @date   2017年3月6日 下午3:04:47
	 * @param data
	 * @return String
	 * @throws IOException    
	 */
	public static String byteArr2String(byte[] byteArr) throws Exception {
		String stringBase64 = null;		
		try {
			 Base64 encoder = new Base64();
			 stringBase64 =(byteArr != null ? encoder.encodeToString(byteArr) : "");
		} catch (Exception e) {
			throw new Exception("byteArr2String转换异常:"+e);
		}
		return stringBase64;
    }
}

      【引申:为什么不要使用sun.misc.BASE64Encoder类?

      很多人在使用Base64进行加密解密时,都是使用sun.misc包下的BASE64Encoder及BASE64Decoder。但是,可能会出现这样的状况:换了JDK后发现提示找不到该类!

      网上有办法说重新配置jre就行了。但事实上不是这么简单的,这是要看配置的jre的类型是execution environment(执行环境),还是alternate jre(替代jre)。

      这两种方法中,如果是第一种就不行,因为是执行环境,也就是不会含JDK的一些额外类,rt.jar中的很多包都会因为jre与jdk权限不同而导致被限定权限,其中就包含了sun包。

     如果是第二种方法,即JDK替代jre,这就没问题,因为使用的是jdk的权限,所以不会报这类的错误。

     但是,事实上,这两个方法都是sun公司的内部方法,并没有在java api中公开过,所以使用这些方法是不安全的,将来随时可能会从中去除,所以应该使用相应的替代对象及方法!【参考:http://fableking.iteye.com/blog/1426410】

       8.编写Controller.java文件

   以下为简写,主要步骤是将byte[]型转Base64的字符串,并返回给前端。实际还需要加上参数校验,异常处理,记录日志等逻辑。

package com.netease.numen.plus.netease.controller;
@Controller
@RequestMapping(value = "/workcard")
public class WorkCardController {
	@Inject
	WorkCardService service;
	
	@RequestMapping(value = "/getWorkCardInfo" )
	public String getWorkCardInfo(String jobNumber) {
		//根据员工工号,获取照片(byte[]类型)	
		PhotoBytes photoBytes = service.getPhoto(jobNumber);
		byte[] photoBytes2 = photoBytes.getPhotoBytes();
		//将二进制转为Base64格式字符串
		String photo64 = Base64ImageUtil.byteArr2String(photoBytes2);
		result = new ResultInf(200, "获取照片信息成功", photo64);
		SpringMvcUtil.renderJson(response, result);
		return null;
	}
}

       9.前台html页面展示

<img src="data:image/png;base64,{photo}"/>


 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章