通过servlet在JSP页面上显示图像

时间:2014-12-11 13:18:56

标签: java jsp servlets

我正在尝试使用Jstl在Jsp页面中显示图像,并且图像路径由servlet传递。 Jsp页面实际上只显示一个检索到的图像并抛出NullPointerException。

Jsp看起来像这样:

<c:forEach items="${images}" var="img">
    <div class="col-md-3">
        <img src="displayImg?imageId=${img.imageId}">
    </div>
</c:forEach>

servlet doGet方法如下所示:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    int imageId = Integer.parseInt(request.getParameter("imageId"));
    Image img = imageDao.getImageById(imageId);
    response.setContentType("image/" + img.getImageType());

    File f = new File(img.getImagePath());
    BufferedImage bi = ImageIO.read(f);
    OutputStream out = response.getOutputStream();
    ImageIO.write(bi, img.getImageType(), out);
    out.close();
}

我无法理解为什么当请求参数正确时,这个servlet会设法为一个映像提供服务而在其他映像上失败并且使用NullPointerException失败。我有一种印象,因为它是并发问题,因为Jsp显示任意图像。

请帮忙吗?

这是DAO:

public Image getImageById(int imageId) {
        String query = "SELECT * FROM images WHERE imageId=?";
        Image img = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            connection = ConnectionManager.getConnection();
            ps = connection.prepareStatement(query);
            ps.setInt(1, imageId);
            rs = ps.executeQuery();
            if (rs.next()) {
                img = new Image();
                img.setImageId(rs.getInt("imageId")); //NPE thrown here
                img.setImagePath(rs.getString("imagePath"));
                img.setImageType(rs.getString("imageType"));
                ...
                img.setDescription(rs.getString("description"));
                img.setCreatedOn(rs.getTimestamp("createdOn"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            close(rs);
            close(ps);
            close(connection); //Removed this and problem disappears
        }
        return img;
    }

解决!! 这很奇怪,但我只是避免关闭与数据库的连接,我的所有图像都正确显示,没有错误。我想在每次单独的数据库访问之后关闭连接是有问题的,因为它无法在你想要它的确切时间关闭,但可能在另一次调用DB的过程中。现在我想知道,根本没有关闭连接也是有问题的。在那种情况下该怎么办?

3 个答案:

答案 0 :(得分:0)

只需阅读堆栈跟踪:

at com.mysql.jdbc.ResultSetImpl.buildIndexMapping(ResultSetImpl.java:674)
at com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1029) 
at com.mysql.jdbc.ResultSetImpl.getInt(ResultSetImpl.java:2566) 
at be.kayiranga.daoImpl.ImageDaoImpl.getImageById(ImageDaoImpl.java:114)

因此,

抛出了异常
rs.getInt("imageId")

表示结果集中没有名为"imageId"的列。

你永远不应该使用select *。使用显式列名,并在从结果集中获取数据时使用这些显式列名:

select imageId, imagePath, imageType, description, createdOn from ...

答案 1 :(得分:0)

很奇怪,因为imageId在查询中用作列名,并且有一条记录rs.next()。 也许它不是int而是long或SQL VARCHAR。 也许MySQL非常聪明,因为在WHERE中指定了imageId? 或者在某种程度上,您需要使用rs.getInt("images.imageId")

            img.setImageId(rs.getInt("imageId")); //NPE thrown here
然而,

可以写成(规避)

            img.setImageId(mageId);

我会检查没有狡猾的错字:í(重音),西里尔e(如果你是东欧)或tab char。老实说你的代码看起来整洁,但类似的错误发生在更简洁的代码上:ps,ps2,rs,rs2 as fields,对并发使用造成严重破坏,并且易于打字错误。

使用更少的内存资源可以更快地完成BTW写作:

Path path = Paths.get(img.getImagePath());
OutputStream out = response.getOutputStream();
Files.copy(path, out);

在搜索错误时:

调查错误似乎是唯一的选择:

ResultSetMetaData meta = rs.getMetaData();
int numberOfColumns = meta.getColumnCount();
for (int i = 1; i <= numberOfColumns; ++i) {
    log(... i, meta.getColumnName(i), meta.getColumnLabel(i) ...);
}

答案 2 :(得分:0)

这个答案可能对你没有任何帮助,因为没有人相信你完全理解你在做什么。我假设你有一个JSP页面和一个表单,我可以告诉你如何将图像显示为字符串。

public showImage(){
  BASE64Encoder base64Encoder = new BASE64Encoder();
 // your method to retreive the image
 if(image == null){
   File imagePath = new File("/home/akshay/images.jpeg"); // display alternate image
      try {
          BufferedImage bufferedImage = ImageIO.read(imagePath);
          ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
   //Below person is the main object model, and String is the image in string
        person.setProfilePhotoString("data:image/png;base64," +   base64Encoder.encode(byteArrayOutputStream.toByteArray()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
  } else{
         person1.setProfilePhotoString("data:image/png;base64," +  base64Encoder.encode(person1.getProfilephoto()));
}
}

JSP页面:

<form:form action="${showAction}" commandName="person">
    <table>
 <tr>
            <td><img src= "${person.profilePhotoString}"  height=100 width=100/>
        </tr>
</table>
</form>