如何使用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)并将它们插入到数据库表covers.cover中,该表的类型为bytea

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

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

然而,数据看起来有点像

'377'330'377'340'000'020JFIF'000'001'001'001'001,'001,'000'000'377'333'000C'000'013'010'010'010'011'010'014'011'011'014'021'013'012'013'021'024'017'014'014'017'024'027'022'022'022'022'022'027'030'023'024'024'024'024'023'030'026'032'033'034'033'032'026""$$"".....0000000000'377'333'000C'001'014'014'014'020'020'020'027'021'021'027'030'024'023'024'030'036'033'034'034'033'036$'036'036'037'036'036$)#    #)&($$$(&++))++000000000000000'377'300'000'021'010'005'200'005'230'003'001'021'000'002'021'001'003'021'001'377'304'000'033'000'000'003'000'003'001'001'000'000'000'000'000'000'000'000'000'000'000'001'002'003'004'006'005'007'377'304'000U'020'000'001'002'004'003'005'004'010'003'006'005'003'003'001'001'021'001'002'021'000!1A'003'022Q'004"2Ba'005'023bq'006CRr'201'221'241'3603'261'301'024#c'202'321

等等,它对我来说不像是有效的数据。我期待一些更统一的东西(不像,, "$这样的特殊字符),像'x01E25A43

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

我想我没有正确使用BYTEA字段,但我不知道我做错了什么。有什么建议吗?

数据库表看起来像:
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;
使用JDBC连接器调用上述数据库函数的Java方法如下所示:
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;
}

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

<?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的有效设置。