Java 无法在JSP文件上显示使用Hibernate检索的图像

Java 无法在JSP文件上显示使用Hibernate检索的图像,java,spring,hibernate,jsp,Java,Spring,Hibernate,Jsp,我正在开发一个SpringMVC应用程序。我希望将图像保存在数据库中,并在应用程序的JSP页面中显示它们。目前我可以在数据库中保存图像,但无法在前端显示它们。 图像不显示,当我单击view image时,我得到一个Apache错误: HTTP Status 404 - /product/%5BB@a2e6ab9 我通常认为,这将是二进制图像,当单击view时,显示的图像将显示完整的二进制数据,但事实并非如此。现在我将粘贴用于显示的控制器、实体和JSP代码 控制器: @RequestMappi

我正在开发一个SpringMVC应用程序。我希望将图像保存在数据库中,并在应用程序的JSP页面中显示它们。目前我可以在数据库中保存图像,但无法在前端显示它们。 图像不显示,当我单击view image时,我得到一个Apache错误:

HTTP Status 404 - /product/%5BB@a2e6ab9
我通常认为,这将是二进制图像,当单击view时,显示的图像将显示完整的二进制数据,但事实并非如此。现在我将粘贴用于显示的控制器、实体和JSP代码

控制器:

 @RequestMapping(value = "/product/{id}/image")
    public byte[] retrieveimage(@ModelAttribute("product") ProductBasic productBasic,@PathVariable("id")Integer id){
        User user = userService.getCurrentlyAuthenticatedUser();
        ProductBasic productBasic1 = productBasicService.getProductById(id);
        BASE64Encoder base64Encoder = new BASE64Encoder();
        byte[] data =  org.apache.commons.codec.binary.Base64.decodeBase64(productBasic1.getProductimage());
        return data;

    }

@RequestMapping(value="/product/show",method= RequestMethod.GET)
    public String listProducts(@ModelAttribute("product") ProductBasic productBasic,Model model){
        User user = userService.getCurrentlyAuthenticatedUser();
        model.addAttribute("product", new ProductBasic());
        model.addAttribute("listProducts",this.productBasicService.listProduct(user));
       BASE64Encoder base64Encoder = new BASE64Encoder();

        if(productBasic.getProductimage()==null){
            System.out.println("getProductImage is null"); // This is always returning null when I check
            return "product";
        }else {
            String image = "data:image/png;base64," + base64Encoder.encode(productBasic.getProductimage());
            model.addAttribute("saveimage", image);
            return "product";
        }
    }
JSP:

<h3>Product List</h3>
<c:if test="${!empty listProducts}">
    <table class="tg">
        <tr>
            <th width="80">Product ID</th>
            <th width="80">Product image</th>
            <th width="120">Product name</th>
            <th width="120">Product description</th>
            <th width="120">Product condition</th>
            <th width="120">Product age</th>
            <th width="120">Product EAN</th>
            <th width="120">Product ISBN</th>
            <th width="120">Product ordernumber</th>
            <th width="120">Product owners id</th>

            <th width="60">Edit</th>
            <th width="60">Delete</th>
        </tr>

        <c:forEach items="${listProducts}" var="product">
            <tr>
                <td>${product.productid}</td>
                <td>${product.productimage} </td>
                <td>${product.productname}</td>
                <td>${product.productdescription}</td>
                <td>${product.productcondition}</td>
                <td>${product.productage}</td>
                <td>${product.productean}</td>
                <td>${product.productisbn}</td>
                <td>${product.ordernumber}</td>
                <td>${product.user1id}</td>
                <img src="${product.productimage}" height="100" width="100"/>
                <td><a href="<c:url value='/editproduct/${product.productid}' />" >Edit Product</a></td>
                <td><a href="<c:url value='/removeproduct/${product.productid}' />" >Delete Product</a></td>
            </tr>
            <%--<img src="${saveimage}" height="100" width="100">--%>
        </c:forEach>


    </table>
</c:if>
DAOImpl:

 @Override
    public List<byte[]> listImage(User user){
        int id = user.getId();
        if(session == null){
            session = this.sessionFactory.openSession();
        } else{
            session = this.sessionFactory.getCurrentSession();
        }
        Query query = session.createQuery("from ProductBasic as p where p.user1.id=:id order by p.ordernumber");
        query.setParameter("id",id);
        List<ProductBasic> productBasicList= query.list();
        List<byte[]> images=null;
        if(productBasicList.isEmpty()){
            return null;
        } else {
            for (ProductBasic productBasic : productBasicList) {
                images.add(productBasic.getProductimage());  // Here there is nullPointer Exception
            }
            return images;
        }
    }
}
productImage实体中的Getter为:

 public byte[] getProductimage() {
        return productimage;
    }

    public void setProductimage(byte[] productimage) {

        this.productimage = productimage;
    }
在firefox中单击“查看图像”时,出现以下错误:

java.lang.IllegalArgumentException: Unknown return value type [[B]
    org.springframework.util.Assert.notNull(Assert.java:112)
    org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:70)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
HTML img标记不能处理二进制字节数据。它有一个src属性,该属性接受一个URL,它使用该URL通过一个单独的GET请求检索图像二进制字节数据

您可以使用控制器方法返回二进制字节数据,如

/product/{id}/image
当与{id}一起提供时,它必须返回二进制字节数据

有了它,您可以像下面这样更改代码

产品清单 产品ID 产品形象 产品名称 产品说明 产品状况 产品时代 产品EAN 产品ISBN 产品订单号 产品所有者id

        <th width="60">Edit</th>
        <th width="60">Delete</th>
    </tr>

    <c:forEach items="${listProducts}" var="product">
        <tr>
            <td>${product.productid}</td>
            <td>${product.productimage} </td>
            <td>${product.productname}</td>
            <td>${product.productdescription}</td>
            <td>${product.productcondition}</td>
            <td>${product.productage}</td>
            <td>${product.productean}</td>
            <td>${product.productisbn}</td>
            <td>${product.ordernumber}</td>
            <td>${product.user1id}</td>
            <!-- This Changed -->
            <img src="/product/${product.productid}/image" height="100" width="100"/>
            <td><a href="<c:url value='/editproduct/${product.productid}' />" >Edit Product</a></td>
            <td><a href="<c:url value='/removeproduct/${product.productid}' />" >Delete Product</a></td>
        </tr>
        <%--<img src="${saveimage}" height="100" width="100">--%>
    </c:forEach>


</table>

我认为我们应该从${product.productimage}而不是二进制数据获取图像的url。
因此Product的属性productimage可以是字符串类型。我们可以将url存储在DB中,例如/xxx/xxx.Jpg

如果有人想知道为什么我不使用Bob或Clob进行图像持久化,我在使用PGAdmin3添加列时只看到OID选项。我正在Ubuntu上使用Postgresql 9.3。那我该怎么做呢?我第一次做图像的工作,我发现所有的参考文献都不适合。你能告诉我Productbasic类的getter和setter在哪里吗?@DeepakTiwari getter和setters添加到了主帖子中。你好,Shazin,谢谢你的回答,正如你所看到的,我试图用Base64Encoder对图像进行编码,但是字符串image=data:image/png;base64,+Base64Encoder.encodeproductBasic.getProductimage;当getProductImage总是返回null时,抛出一个nullPointerException。正如您所说,我已经在controller中添加了该方法,请查看更新的帖子。它仍然无法显示图像。是否确定productBasic1.getProductimage返回字节数组?在保存数组之前是否进行Base64编码?是的。请转到文章的结尾,我已经更新了用户界面的帖子,我想把它们存储在数据库中并显示出来,我不明白你们刚才说的。我的意思是,我们可以在数据库中保存图片的url。我们可以从数据库中获取字符串形式的url。然后可以使用src显示图片。
/product/{id}/image
        <th width="60">Edit</th>
        <th width="60">Delete</th>
    </tr>

    <c:forEach items="${listProducts}" var="product">
        <tr>
            <td>${product.productid}</td>
            <td>${product.productimage} </td>
            <td>${product.productname}</td>
            <td>${product.productdescription}</td>
            <td>${product.productcondition}</td>
            <td>${product.productage}</td>
            <td>${product.productean}</td>
            <td>${product.productisbn}</td>
            <td>${product.ordernumber}</td>
            <td>${product.user1id}</td>
            <!-- This Changed -->
            <img src="/product/${product.productid}/image" height="100" width="100"/>
            <td><a href="<c:url value='/editproduct/${product.productid}' />" >Edit Product</a></td>
            <td><a href="<c:url value='/removeproduct/${product.productid}' />" >Delete Product</a></td>
        </tr>
        <%--<img src="${saveimage}" height="100" width="100">--%>
    </c:forEach>


</table>