如何将MySQL中的Blob转换并在JSP页面显示?Spring MVC场景
完善DAO代码(补全资源关闭逻辑)
首先先把你未完成的DAO代码补全,避免数据库连接泄漏:
public List<PhotoResponseDTO> getAllPhoto() throws IOException { List<PhotoResponseDTO> photos = new ArrayList<>(); String sql = "SELECT * FROM photot"; PreparedStatement ps = null; ResultSet rs = null; try { ps = con.prepareStatement(sql); rs = ps.executeQuery(); while(rs.next()) { PhotoResponseDTO photo = new PhotoResponseDTO(); photo.setId(rs.getInt("id")); photo.setImage(rs.getBytes("image")); // 将Blob转为字节数组 photo.setDate(rs.getString("date")); photos.add(photo); } } catch (SQLException e) { e.printStackTrace(); // 实际项目建议抛自定义业务异常或统一处理 } finally { // 按顺序关闭资源,避免内存泄漏 try { if (rs != null) rs.close(); if (ps != null) ps.close(); // 若con是局部变量需关闭,Spring连接池管理的连接无需手动关闭 } catch (SQLException e) { e.printStackTrace(); } } return photos; }
两种在JSP显示Blob图片的方案
方案一:转Base64直接嵌入页面(适合小图片)
这种方式无需额外HTTP请求,直接把图片编码成字符串嵌入页面。
- Controller层处理编码
在Controller中把图片字节数组转成Base64字符串,传递给JSP:
@Controller @RequestMapping("/photos") public class PhotoController { @Autowired private PhotoDAO photoDAO; @GetMapping("/list") public String getPhotoList(Model model) throws IOException { List<PhotoResponseDTO> photos = photoDAO.getAllPhoto(); // 为每个图片生成Base64编码字符串 for (PhotoResponseDTO photo : photos) { byte[] imageBytes = photo.getImage(); if (imageBytes != null) { // 前缀需匹配图片类型,png则改为image/png String base64Image = "data:image/jpeg;base64," + Base64.getEncoder().encodeToString(imageBytes); photo.setBase64Image(base64Image); // 需在DTO中新增base64Image字段及getter/setter } } model.addAttribute("photos", photos); return "photoList"; // 对应你的JSP文件名 } }
在PhotoResponseDTO中新增字段:
public class PhotoResponseDTO { private int id; private byte[] image; private String date; private String base64Image; // 新增字段 // 原有getter/setter public String getBase64Image() { return base64Image; } public void setBase64Image(String base64Image) { this.base64Image = base64Image; } }
- JSP页面渲染
在photoList.jsp中遍历显示:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>图片列表</title> </head> <body> <h1>图片列表</h1> <c:forEach items="${photos}" var="photo"> <div> <p>上传日期:${photo.date}</p> <img src="${photo.base64Image}" alt="图片" width="200" height="200"> </div> <hr> </c:forEach> </body> </html>
方案二:单独Controller输出图片流(适合大图片)
这种方式通过独立的接口返回图片流,更符合HTTP规范,避免页面加载过慢。
- 新增图片流接口
在Controller中添加根据ID返回图片的方法,同时DAO新增单图查询逻辑:
@Controller @RequestMapping("/photos") public class PhotoController { @Autowired private PhotoDAO photoDAO; // 列表页跳转 @GetMapping("/list") public String getPhotoList(Model model) throws IOException { List<PhotoResponseDTO> photos = photoDAO.getAllPhoto(); model.addAttribute("photos", photos); return "photoList"; } // 输出图片流 @GetMapping("/image/{photoId}") public void getImage(@PathVariable("photoId") int photoId, HttpServletResponse response) throws IOException { PhotoResponseDTO photo = photoDAO.getPhotoById(photoId); // DAO需新增该方法 if (photo != null && photo.getImage() != null) { byte[] imageBytes = photo.getImage(); response.setContentType("image/jpeg"); // 匹配图片实际类型 response.setHeader("Cache-Control", "max-age=3600"); // 可选缓存设置 ServletOutputStream outputStream = response.getOutputStream(); outputStream.write(imageBytes); outputStream.flush(); outputStream.close(); } } }
DAO新增单图查询方法:
public PhotoResponseDTO getPhotoById(int photoId) throws SQLException { String sql = "SELECT * FROM photot WHERE id = ?"; PreparedStatement ps = null; ResultSet rs = null; PhotoResponseDTO photo = null; try { ps = con.prepareStatement(sql); ps.setInt(1, photoId); rs = ps.executeQuery(); if (rs.next()) { photo = new PhotoResponseDTO(); photo.setId(rs.getInt("id")); photo.setImage(rs.getBytes("image")); photo.setDate(rs.getString("date")); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭资源 try { if (rs != null) rs.close(); if (ps != null) ps.close(); } catch (SQLException e) { e.printStackTrace(); } } return photo; }
- JSP页面渲染
通过img标签指向图片流接口:
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <title>图片列表</title> </head> <body> <h1>图片列表</h1> <c:forEach items="${photos}" var="photo"> <div> <p>上传日期:${photo.date}</p> <img src="${pageContext.request.contextPath}/photos/image/${photo.id}" alt="图片" width="200" height="200"> </div> <hr> </c:forEach> </body> </html>
注意事项
- 图片类型:若数据库存储的是png/gif等格式,需对应调整
Content-Type和Base64前缀。 - 异常处理:实际项目中不要直接打印StackTrace,建议统一捕获异常并跳转错误页面。
- 框架整合:后续可以学习Spring JdbcTemplate或MyBatis,它们会自动管理数据库连接,比原生JDBC更简洁安全。
内容的提问来源于stack exchange,提问作者Ashlen
相关产品推荐
相关产品推荐

