如何使用 Java 将 JPEG 图像插入 PostgreSQL bytea 字段,然后使用 PHP 显示在网站上?

How do I insert a JPEG image into a PostgreSQL bytea field using Java and then display on a website using PHP?

我做了一个 Java 小程序,它读取图像文件 (jpg/jpeg) 并将它们插入 table covers.cover 类型的数据库 [=18] =].

我相当确定传递给 Java addCover(int riddim_id, byte[] cover, byte[] thumbnail) 方法的 byte[] cover 参数包含有效的 jpeg 数据(我已经通过将其写入 .jpeg 进行了测试文件,显示正常)。

数据库函数add_cover(riddim INT, cover BYTEA, thumbnail BYTEA)似乎被正确调用;通话后 table 中有数据,我没有收到任何 SQL 错误。

不过,数据有点像

7070[=12=]00JFIF[=12=]0[=12=]1[=12=]1[=12=]1[=12=]1,[=12=]1,[=12=]0[=12=]073[=12=]0C[=12=]03000104114132314744747222227034444306234326""$$"".....000000000073[=12=]0C[=12=]1444000711704340634436$66766$)#    #)&($$$(&++))++00000000000000070[=12=]010[=12=]50[=12=]50[=12=]3[=12=]11[=12=]0[=12=]21[=12=]1[=12=]31[=12=]174[=12=]03[=12=]0[=12=]0[=12=]3[=12=]0[=12=]3[=12=]1[=12=]1[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]0[=12=]1[=12=]2[=12=]3[=12=]4[=12=]6[=12=]5[=12=]774[=12=]0U0[=12=]0[=12=]1[=12=]2[=12=]4[=12=]3[=12=]5[=12=]40[=12=]3[=12=]6[=12=]5[=12=]3[=12=]3[=12=]1[=12=]11[=12=]1[=12=]21[=12=]0!1A[=12=]32Q[=12=]4"2Ba[=12=]53bq[=12=]6CRr11103114#c21

等等,在我看来这不是有效数据。我期待一些更统一的东西(较少的特殊字符,如 ,"$),如 \x01E25A43.

当我转到 http://foo.bar/image.php,即下面显示的 PHP 脚本时,Firefox 告诉我无法显示图像,因为它包含错误数据。

我假设我没有正确使用 BYTEA 字段,但我无法弄清楚我做错了什么。有什么建议吗?

数据库table看起来像:

CREATE TABLE covers (
    cover_id              SERIAL      PRIMARY KEY,
    riddim_id             SERIAL      UNIQUE REFERENCES riddims (riddim_id),
    coverhash             VARCHAR(32) NOT NULL UNIQUE,
    cover                 BYTEA       NOT NULL,
    thumbnail             BYTEA       NOT NULL
);

我用 java 调用的 数据库函数 看起来像:

CREATE OR REPLACE FUNCTION add_cover(_riddim_id INT, _cover BYTEA, _thumbnail BYTEA) RETURNS INTEGER AS $$
DECLARE
    _cover_id INT;
BEGIN
    SELECT cover_id INTO _cover_id FROM covers WHERE riddim_id = _riddim_id;

    IF (_cover_id IS NULL) THEN
        INSERT INTO covers (riddim_id, coverhash, cover, thumbnail) VALUES (
            _riddim_id,
            md5(_cover),
            _cover,
            _thumbnail
        ) RETURNING cover_id INTO _cover_id;
    END IF;

    RETURN _cover_id;
END;
$$ LANGUAGE plpgsql;

Java 方法 使用 JDBC 连接器调用上面的数据库函数,如下所示:

private int addCover(int riddim_id, byte[] cover, byte[] thumbnail) 
        throws SQLException {    
    int cover_id;

    try (CallableStatement cs = conn.prepareCall("{ ? = call add_cover(?, ?, ?) }")) {
        cs.registerOutParameter(1, Types.INTEGER);
        cs.setInt(2, riddim_id);
        cs.setBytes(3, cover);
        cs.setBytes(4, thumbnail);
        cs.execute();
        cover_id = cs.getInt(1);
    }

    return (cover_id != 0) ? cover_id : -1;
}

将数据作为 image/jpeg 发送到浏览器的 PHP 脚本(我在 Google 某处找到的):

<?php
  // Connect to the database
  $dbconn = pg_connect("<censored>");

  // Get the bytea data
  $res = pg_query("SELECT cover FROM covers WHERE cover_id = 11");
  $raw = pg_fetch_result($res, 'cover');

  // Convert to binary and send to the browser
  header('Content-type: image/jpeg');
  echo pg_unescape_bytea($raw);
?>

我是 运行 PostgreSQL 版本 9.4.4,使用 postgresql-9.4-1202.jdbc41.jar.

查询失败但没有给出错误消息(更准确地说,查询总是返回一个空结果集)因为我使用的是 pg_connect("host=foo.bar ...")pg_hba.conf 未配置为允许从本地主机发送的外部连接,显然。将 host=foo.bar 更改为 host=localhost 解决了问题。

我不太清楚为什么$dbconn返回true,我在检查/var/log/postgresql/postgresql-9时发现连接出了问题。4-main.log 这告诉我,我尝试连接的用户没有针对 pg_hba.conf.

中指定的 host 的有效设置