如何使用 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
的有效设置
我做了一个 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
的有效设置