【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}"/>


 

相关文章
|
3天前
|
监控 数据可视化 Java
【JAVA】分布式链路追踪技术概论
【JAVA】分布式链路追踪技术概论
14 2
|
1天前
|
前端开发 Java 数据安全/隐私保护
计算机Java项目|基于Andriod技术“厕ce”APP
计算机Java项目|基于Andriod技术“厕ce”APP
|
1天前
|
数据可视化 Java
Java语言使用DL4J实现图片分类
【6月更文挑战第14天】Java语言使用DL4J实现图片分类
12 3
|
2天前
|
druid Java 关系型数据库
JAVA *数据库连接池 * 接JDBC
JAVA *数据库连接池 * 接JDBC
|
4天前
|
Cloud Native Java Devops
【Quarkus 技术系列】「云原生架构体系」在云原生时代下的 Java“拯救者”是 Quarkus,那云原生是什么呢?
【Quarkus 技术系列】「云原生架构体系」在云原生时代下的 Java“拯救者”是 Quarkus,那云原生是什么呢?
17 3
|
5天前
|
SQL Java 数据库
Java一分钟之-Spring Data JPA:简化数据库访问
【6月更文挑战第10天】Spring Data JPA是Spring Data项目的一部分,简化了Java数据库访问。它基于JPA,提供Repository接口,使开发者能通过方法命名约定自动执行SQL,减少代码量。快速上手包括添加相关依赖,配置数据库连接,并定义实体与Repository接口。常见问题涉及主键生成策略、查询方法命名和事务管理。示例展示了分页查询的使用。掌握Spring Data JPA能提升开发效率和代码质量。
25 0
|
8天前
|
Java 机器人 API
JAVA实现自动打开URL对应的网页并保存为图片-不借助第三方API
JAVA实现自动打开URL对应的网页并保存为图片-不借助第三方API
19 9
|
9天前
|
开发框架 前端开发 JavaScript
JSP技术已死 ? (Java Server Page technology will die) ?
JSP技术已死 ? (Java Server Page technology will die) ?
11 0
|
10天前
|
存储 SQL 缓存
Java性能优化(十)-数据库调优-数据库参数设置优化
Java性能优化(十)-数据库调优-数据库参数设置优化
11 0
|
1天前
|
存储 关系型数据库 MySQL
MySQL周内训参照1、ER实体关系图与数据库模型图绘制
MySQL周内训参照1、ER实体关系图与数据库模型图绘制
6 1