【发布时间】:2013-02-12 19:09:07
【问题描述】:
在我将字节数组保存到数据库之前,如果我打印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或二进制文件,有时是文本。我的 test 正在插入一个纯文本字符串并将其拉出以确保它被正确保存。该测试通过了我们在 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 的同事进行了同样的测试,检查字节,他通过了。
【问题讨论】:
-
使用 [
String(byte[] bytes, Charset charset)](docs.oracle.com/javase/7/docs/api/java/lang/…, java.nio.charset.Charset)) 构造函数。 -
你的字节数组真的代表文本吗?如果是这样,您为什么将它放在
byte[]中?如果没有,您不应该使用String... -
另外...为什么将
Strings存储为原始字节? -
@jlordo 我在我的代码
new String(attachment.getData(), Charset.lookup("UTF8"))中做了这个,它仍然打印出“87474703a2f2f6269742e6c792f617948363977”。 -
我已经编辑了底部以解释为什么我将字符串保存为字节数组。
标签: java postgresql character-encoding file-encodings glassfish-2.x