在我将字节数组保存到数据库之前,如果我打印它的输出new String(data)
会返回一个可读的字符串,例如“foobar”,但是在我将它从数据库中拉出之后,new String(data)
会读起来像一堆乱码,例如“9238929384739427349327 ...”。这里有很多部分,我将尝试将它们全部列出。我正在使用 eclipselink 并且我的数据列已定义:
@Lob
@Column(name = "data")
private byte[] data;
如果我运行此代码:
public static void main(String[] args) {
System.out.println(Charset.defaultCharset());
}
它输出windows-1250
.
我的数据库定义为:
CREATE DATABASE project_trunk
WITH OWNER = project
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'English_United States.1252'
LC_CTYPE = 'English_United States.1252'
CONNECTION LIMIT = -1;
我也在这样定义的数据库上试过这个:
CREATE DATABASE project_trunk
WITH OWNER = project
ENCODING = 'UTF8'
TABLESPACE = pg_default
LC_COLLATE = 'en_US.UTF-8'
LC_CTYPE = 'en_US.UTF-8'
CONNECTION LIMIT = -1;
并且问题仍然存在。
我认为发生的事情是我的数据库与我的应用服务器的编码不同。当我将内容放入数据库并再次将其取出时,它以错误的方式对其进行解码,因此看起来像乱码。我有什么事情吗?
现在,当谈到解决这个问题时,我有点困惑。我认为我应该做的是将我的应用服务器的文件编码更改为与数据库相同。我正在使用 Glassfish 2.1.1。当我application server -> advanced -> domain attributes
将语言环境设置为“UTF8”或“UTF-8”时,它告诉我需要重新启动。重新启动 glassfish 后,该字段仍为空白,并且仍然出现错误。我想也许它没有节省财产。我会手动将它放在配置文件中,但我不知道该放在哪里或放什么。
或者,我尝试使用 ENCODING = 'WIN1250' 创建我的数据库,但是当我这样做时,它说我的 LC_CTYPE 需要是“WIN1252”。当我将 LC_CTYPE 设置为“WIN1252”时,它说编码不存在。
我在这方面花了很多时间,我想知道我是否在这里做一些事情。我的“appserver 和 db 之间的编码不同步”的理论听起来是正确的,还是我在追逐红鲱鱼?如果有人可以帮助我弄清楚如何更改 glassfish 2.1.1 的此设置,那也将非常有帮助。谢谢
编辑:人们问我为什么将字符串存储为原始字节。这不完全是我正在做的事情,有时原始字节代表图像或pdf或二进制文件,有时是文本。我的测试是插入一个纯文本字符串并将其拉回以确保它被正确保存。这个测试通过了我们在 linux 上的 CI 服务器。
EDIT2:我被要求显示原始二进制输入与原始二进制输出。
预期:[116、104、105、115、32、105、115、32、109、121、32、97、116、116、97、99、104、109、101、110、116、32、97、115 , 32, 97, 32, 83, 116, 114, 105, 110, 103]
实际:[60, 54, 56, 54, 57, 55, 51, 50, 48, 54, 57, 55, 51, 50, 48, 54, 100, 55, 57, 50, 48, 54, 49, 55 , 52, 55, 52, 54, 49, 54, 51, 54, 56, 54, 100, 54, 53, 54, 101, 55, 52, 50, 48, 54, 49, 55, 51, 50, 48 , 54, 49, 50, 48, 53, 51, 55, 52, 55, 50, 54, 57, 54, 101, 54, 55]
我给了我在 Mac 上的同事检查字节的相同测试,并且它通过了他。