如何在JSP中利用HeidiSQL BLOB十六进制代码还原并显示图片
嘿,我来帮你搞定这个问题!你用BLOB存储图片的思路完全没问题,HeidiSQL里显示的十六进制字符串其实就是图片二进制数据的文本化表现形式。下面分两部分给你讲清楚怎么还原图片,以及怎么在JSP里直接展示:
一、从HeidiSQL的BLOB中还原图片(测试/手动处理用)
如果你只是想把数据库里的BLOB数据导出成图片,有两种方式:
直接导出(最方便):
在HeidiSQL里选中对应的BLOB单元格,右键点击选择「导出BLOB」,然后设置保存路径和文件名(比如my-image.jpg),确认后就能直接得到原图片了,这是日常测试最快捷的方法。手动处理十六进制字符串:
如果你想自己把复制的十六进制代码转成图片,可以写个简单的Java小工具:import java.io.FileOutputStream; import java.io.IOException; public class HexToImage { public static void main(String[] args) { // 替换成你从HeidiSQL复制的十六进制字符串 String hexString = "FFD8FFE000104A46494600010101004800480000FFDB0043000302020302020303030304030304050805050404050A070706080C0A0C0C0B0A0B0B0D120F0D110E0F11111012141515150C0E171816141812141514FFDB00430103040405040509050509140D0B0D141414141414141414141414141414141414141414141414141414141414141414141FFC00011080010001003012200021101031101FFC4001F0000010501010101010100000000000000000102030405060708090A0BFFC400B5100002010303020403050504040000017D01020300041105122131410613516107227114328191A1082342B1C11552D1F02433627282090A161718191A25262728292A3435363738393A434445464748494A535455565758595A636465666768696A737475767778797A838485868788898A92939495969798999AA2A3A4A5A6A7A8A9AAB2B3B4B5B6B7B8B9BAC2C3C4C5C6C7C8C9CAD2D3D4D5D6D7D8D9DAE1E2E3E4E5E6E7E8E9EAF1F2F3F4F5F6F7F8F9FAFFDA000C0301000210031000050C040102070102110341042131055106610F127113223281144291A1B1C1071552D1F023336272824453E124F116621772188219921AA2082534435464748494A5565758595A66768696A778797A8898A99AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7C8C9CACBCCCDCECFD0D1D2D3D4D5D6D7D8D9DADBDCDDDEDFE0E1E2E3E4E5E6E7E8E9EAEBECEDEEEFF0F1F2F3F4F5F6F7F8F9FAFBFCFDFEFFD9"; byte[] imageBytes = hexStringToByteArray(hexString); try (FileOutputStream fos = new FileOutputStream("output.jpg")) { fos.write(imageBytes); System.out.println("图片还原成功!"); } catch (IOException e) { e.printStackTrace(); } } private static byte[] hexStringToByteArray(String hex) { int length = hex.length(); byte[] result = new byte[length / 2]; for (int i = 0; i < length; i += 2) { result[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i+1), 16)); } return result; } }把复制的十六进制字符串替换进去,运行这个程序就能得到还原后的图片了。
二、在JSP项目中读取BLOB并展示图片(实际开发场景)
实际项目里不能手动导出,得让JSP页面直接从数据库读取BLOB并展示。这里推荐用Servlet来处理图片的输出,然后在页面里用img标签引用这个Servlet:
步骤1:编写处理图片的Servlet
创建一个ImageServlet.java,负责从数据库读取BLOB并输出到响应流:
import java.io.IOException; import java.io.OutputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/getImage") public class ImageServlet extends HttpServlet { private static final long serialVersionUID = 1L; // 替换成你的数据库配置 private static final String DB_URL = "jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTC"; private static final String DB_USER = "your_username"; private static final String DB_PASS = "your_password"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 获取图片ID(假设你的表用id作为图片的唯一标识) String imageId = request.getParameter("id"); if (imageId == null || imageId.trim().isEmpty()) { response.sendError(HttpServletResponse.SC_BAD_REQUEST, "缺少图片ID"); return; } Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { // 加载JDBC驱动 Class.forName("com.mysql.cj.jdbc.Driver"); // 获取数据库连接(实际项目建议用连接池,比如Tomcat JDBC Pool) conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASS); // 查询图片的BLOB数据和MIME类型(建议把MIME类型存在数据库里) String sql = "SELECT image_blob, content_type FROM images WHERE id = ?"; stmt = conn.prepareStatement(sql); stmt.setString(1, imageId); rs = stmt.executeQuery(); if (rs.next()) { // 设置响应的内容类型,比如image/jpeg、image/png String contentType = rs.getString("content_type"); response.setContentType(contentType); // 读取BLOB数据并输出到响应流 byte[] imageData = rs.getBytes("image_blob"); OutputStream out = response.getOutputStream(); out.write(imageData); out.flush(); } else { // 没找到图片返回404 response.sendError(HttpServletResponse.SC_NOT_FOUND, "图片不存在"); } } catch (ClassNotFoundException | SQLException e) { e.printStackTrace(); response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "服务器错误"); } finally { // 关闭数据库资源 try { if (rs != null) rs.close(); } catch (SQLException ignored) {} try { if (stmt != null) stmt.close(); } catch (SQLException ignored) {} try { if (conn != null) conn.close(); } catch (SQLException ignored) {} } } }
步骤2:在JSP页面中引用图片
在你的展示页面(比如index.jsp)里,用img标签指向这个Servlet的路径,传递对应的图片ID:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>展示数据库中的图片</title> </head> <body> <!-- 这里的id=1是示例,实际可以从数据库查询动态生成 --> <h2>我的图片</h2> <img src="getImage?id=1" alt="数据库存储的图片" width="300"> </body> </html>
额外注意事项
- 存储MIME类型:建议把图片的MIME类型(比如
image/jpeg、image/png)和BLOB数据一起存在数据库里,这样响应时能正确设置contentType,避免浏览器无法识别图片格式。 - 使用连接池:上面的代码直接创建数据库连接,实际项目中一定要用连接池(比如Tomcat自带的JDBC Pool、Apache Commons DBCP),提升性能和稳定性。
- 上传图片的正确姿势:上传图片到BLOB时,要用
PreparedStatement的setBinaryStream方法,确保二进制数据正确写入:// 上传示例代码片段 String uploadSql = "INSERT INTO images (image_blob, content_type) VALUES (?, ?)"; PreparedStatement uploadStmt = conn.prepareStatement(uploadSql); // 假设file是上传的文件对象 uploadStmt.setBinaryStream(1, file.getInputStream(), file.getSize()); uploadStmt.setString(2, file.getContentType()); uploadStmt.executeUpdate();
内容的提问来源于stack exchange,提问作者Иван Стоилов
相关产品推荐
相关产品推荐

