【问题标题】:Retrieving bytearray from database in servlet and in jsp在 servlet 和 jsp 中从数据库中检索字节数组
【发布时间】:2012-02-03 20:59:02
【问题描述】:

我真的不了解字节数组...可能是因为我是第一次处理图像所以需要你的帮助

我有base64字符串R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN​​48CXF8m2iQ3YmmKqVlRtW4MLwWACH H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==

我正在解码并将其存储在 MySql 数据库中,然后我在我的 servlet 端使用以下代码

if ( request.getParameter("imgID") != null )
    {

      iNumPhoto = Integer.parseInt(request.getParameter("imgID")) ;   


      try
      {  
                Class.forName("com.mysql.jdbc.Driver").newInstance();
               conn=DriverManager.getConnection("jdbc:mysql://localhost:9191/mbcss","root","admin");
               stmt= conn.createStatement();

         //conn.setAutoCommit (false);  

         // get the image from the database
         byte[] imgData = GetPhoto.getPhoto( conn, iNumPhoto );   
         System.out.println("imgData="+imgData);
         // display the image
         response.setContentType("image/gif");
         OutputStream o = response.getOutputStream();
         o.write(imgData);

         o.flush(); 
         o.close();
      }
      catch (Exception e)
      {
        e.printStackTrace();

      }
    }
         }

这里是getPhoto方法

public static byte[] getPhoto (Connection conn, int iNumPhoto)
throws Exception, SQLException
{
 String req = "" ;
 Blob img ;
 byte[] imgData = null ;
 Statement stmt = conn.createStatement ();

 // Query
 req = "Select image From visit";

 ResultSet rset  = stmt.executeQuery ( req ); 

 while (rset.next ())
 {    
  img = rset.getBlob(1);
  imgData = img.getBytes(1,(int)img.length());
 }    

 rset.close();
stmt.close();

 return imgData ;
}

访问表只有 1 条记录,但是每当我执行调用 servlet 类 imgData 的 jsp 文件时,我在控制台上打印的每次刷新都会打印不同的值,并且图像也不会显示在 JSP 上

  1. 每次显示不同的值是编码错误或字节数组的特征。
  2. 为什么不显示图片帮帮我

【问题讨论】:

  • 解码图像可能是图像无法正确显示在 JSP 中的原因。尝试将图像数据直接存储到数据库中而不进行解码。
  • @Ravindra Gullapalli 你的意思是说我应该只将图像存储为base64字符串......这对我来说效率太低了......

标签: java image jsp jakarta-ee


【解决方案1】:

您需要检查以下内容:

  1. 在您的查询“从访问中选择图像”中,我没有看到用于限制结果的 WHERE 子句,因此如果您有很多行,则可能是每次刷新页面时获得不同结果的原因.

  2. 数据库中的字段图像是BLOB类型的?

编辑:

检查 MySQL 的文档你需要遵循一些规则。首先方法必须是getBytes 而不是getBlob。其他规则是:

从 Connector/J 版本 3.1.0 开始,您可以模拟 BLOB 通过将属性 emulateLocators=true 添加到 JDBC URL 来定位器。 使用这种方法,驱动程序会延迟加载实际的 BLOB 数据 直到您检索其他数据,然后使用检索方法 (getInputStream()、getBytes() 等)在 blob 数据流上。

您必须使用列别名,该列的值与实际值一致 BLOB 的名称,例如:

SELECT id, 'data' as blob_data from blobtable 您还必须遵循 这些规则:

SELECT 必须只引用一个表。表必须有 主键。

SELECT 必须为原始 blob 列名设置别名,指定为 字符串,为备用名称。

SELECT 必须覆盖构成主键的所有列。

BLOB 实现不允许就地修改(它们是 副本,由 DatabaseMetaData.locatorsUpdateCopies() 报告 方法)。因此,使用相应的 PreparedStatement.setBlob() 或 ResultSet.updateBlob()(在 可更新的结果集)方法将更改保存回数据库。

您可以通过以下方式查看更多信息:http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-implementation-notes.html

【讨论】:

  • 我已经提到只有 1 行,因为我也使用 where 子句进行了测试,但随后删除了除 1 之外的所有行进行测试..所以只有 1 行,数据类型为 BLOB
  • 我在访问表中没有主键..你能告诉我我应该做什么...从你上面的文件中我现在应该做些什么改变
  • 您必须创建一个PK,如果您不想使用它们,您可以创建一个具有自动增量功能的“id”列。如果您有生产中的数据,您可以使用 PK 创建一个临时表,然后从旧表加载数据,最后重命名该表。
【解决方案2】:

您将看到来自 blob 数据库的记录中的最后一个图像文件,因为 byat 数组将其刷新出每条新记录并将新图像文件替换到 jsp 页面中的修复位置,您需要将文件写入本地目录和需要给出该位置的路径

【讨论】:

  • 首先,我的数据库中只有 1 条记录。其次,我尝试使用 fileoutputstream 将图像先保存到驱动器中。正在创建一些 9 字节的文件,但其中没有图像
【解决方案3】:

您需要确保正确解码 Base64 编码的图像,并且将图像添加到数据库的代码没有问题。

执行相反的过程:
(1) 从数据库中检索字节数组图像表示
(2) 对字节数组做Base64编码
(3) 从 Base64 编码的字节数组创建一个字符串。

您通过此操作获得的字符串必须与原始字符串具有相同的值: R0lGODlhDwAPAKECAAAAzMzM/////wAAACwAAAAADwAPAAACIISPeQHsrZ5ModrLlN​​48CXF8m2iQ3YmmKqVlRtW4MLwWACH H09wdGltaXplZCBieSBVbGVhZCBTbWFydFNhdmVyIQAAOw==

如果是这样,那么您就知道您正在正确地进行解码和数据库存储;否则,如果值不同,则需要修复解码或数据库存储代码。

【讨论】:

    猜你喜欢
    • 2012-01-14
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-03-02
    • 2018-10-30
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多