如何使用 JSTL 在 jsp 页 table 中显示多个 MySQL db blob 图像

How to display multiple MySQL db blob images in a jsp page table using JSTL

我的程序中有一个部分执行 http GET 请求,它显示一个 table,其中包含我的 MySQL 数据库中的行。虽然包含文本的每个单元格都显示正常,但 table 的图像单元格显示对象引用,尽管进行了多次搜索和多次尝试,但仍无法正常工作。

我的图像在数据库中存储为 Blob,我的行项目存储在对象列表中,如下面的 'DisplayChefRecipes.java' 代码所示。我在 JSP 页面上使用 EL 访问它。

出于 Whosebug 其他地方所述的原因,我不想在我的 JSP 页面中使用 Scriplet。

Bean Class(仅与图像相关的部分)

private InputStream image;
public InputStream getImage() {
    return image;
}
public void setImage(InputStream sImage) {
    this.image = sImage;
}

DisplayChefRecipes

 public class DisplayChefRecipes extends HttpServlet {

 private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    Chef chef = new Chef();
    int chefIdString = Integer.parseInt(request.getParameter("chef_Id"));
    chef.setId(chefIdString);
    List<Object> resultSet = new ArrayList<Object>();

    // Make a connection to the database
    String url = "jdbc:mysql://localhost/traineechefdb";
    String driver = "com.mysql.jdbc.Driver";
    String user = "root";
    String password = null;

    try {
         Class.forName(driver).newInstance();
         Connection conn = (Connection) DriverManager.getConnection(url, user, password);
         System.out.println("Connection Established");      
         Class.forName("com.mysql.jdbc.Driver");

         Statement stmt = (Statement) conn.createStatement();
         String sql = "SELECT R.NAME, R.DESCRIPTION, R.PREP_TIME, R.INGREDIENTS, R.DIRECTIONS, FO.ORIGIN, FT.TYPE_NAME, R.IMAGE " +
                      "FROM RECIPE AS R " +
                        "INNER JOIN FOOD_ORIGIN AS FO " + 
                            "ON R.FOOD_ORIGIN_ID = FO.FOOD_ORIGIN_ID " +
                        "INNER JOIN FOOD_TYPE AS FT " +
                            "ON R.FOOD_TYPE_ID = FT.FOOD_TYPE_ID " +
                      "WHERE R.CHEF_ID = '" + chef.getId() + "' ";

         ResultSet rs = stmt.executeQuery(sql);

         InputStream sImage = null;

         while(rs.next()){

             Recipe recipe = new Recipe();

             recipe.setRecipeName(rs.getString("R.NAME"));
             recipe.setDescription(rs.getString("R.DESCRIPTION"));
             recipe.setPrepTime(rs.getDouble("R.PREP_TIME"));
             recipe.setIngredients(rs.getString("R.INGREDIENTS"));
             recipe.setDirections(rs.getString("R.DIRECTIONS"));
             recipe.setFoodOrigin(rs.getString("FO.ORIGIN"));
             recipe.setFoodType(rs.getString("FT.TYPE_NAME"));
             sImage = rs.getBinaryStream("R.IMAGE");
             recipe.setImage(sImage);

             resultSet.add(recipe);
             recipe.equals(null);
         }
        request.setAttribute("resultSet", resultSet);

        sImage.close();

        rs.close();
        conn.close();

        }catch(SQLException){
            e.printStackTrace();
        }
           request.getRequestDispatcher("jsp/DisplayChefRecipes.jsp").forward(request, response);
    }

DisplayChefRecipes.jsp(Table节)

<table>
    <thead>
        <tr>
            <th>Recipe Name</th>
            <th>Food Origin</th>
            <th>Food Type</th>
            <th>Description</th>
            <th>Prep Time (Hours/mins)</th>
            <th>Ingredients</th>
            <th>Directions</th>
            <th>Image</th>
        </tr>
    </thead>
    <tbody>
        <c:forEach items="${resultSet}" var="row">
            <tr>
                <td>${row.recipeName}</td>
                <td>${row.foodOrigin}</td>
                <td>${row.foodType}</td>
                <td>${row.description}</td>
                <td>${row.prepTime}</td>
                <td>${row.ingredients}</td>
                <td>${row.directions}</td>
                <td>${row.image}</td> <!-- How to Display each image? -->
            </tr>
        </c:forEach>
    </tbody>
</table>

<br>

<a href="jsp/Menu.jsp">
    <button>Return to Menu</button>
</a>

一种方法是创建一个 servlet,它将 return 具有指定 id 的图像,然后只使用常规的 <img src="/imgserv?${row.imageid}"/>(或按照这些行)。

另一种最近的可能性是使用嵌入的、base64 编码的图像数据,如 Embedding Base64 Images 中所述。虽然这将需要您将字节数据预处理为 Base64,但它可以避免创建一个单独的 servlet 来获取图像数据(并不是说它有任何问题)。当然,如果您有很多大图像,嵌入式 base64 的额外开销可能会成为一个问题。