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

    xiaoxiao2023-09-01  237

    如何读取及展示数据库中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}"/>

     

    最新回复(0)