Прежде чем я сохраню массив байтов в базу данных, если я распечатаю вывод 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
и устанавливаю Locale на UTF8 или UTF-8, он говорит мне, что требуется перезагрузка. После перезапуска Glassfish это поле по-прежнему остается пустым, и я все еще получаю сообщение об ошибке. Я думаю, может быть, это не спасает собственность. Я бы вручную поместил его в файл конфигурации, но я не знаю, куда и что поставить.
В качестве альтернативы я попытался создать свою базу данных с ENCODING = 'WIN1250', но когда я это делаю, он говорит, что мой LC_CTYPE должен быть WIN1252. Когда я устанавливаю LC_CTYPE в WIN1252, он говорит, что кодировка не существует.
Я трачу много времени на это, я хотел бы знать, если я на что-то здесь. Правильно ли звучит моя теория рассинхронизированных кодировок между appserver и db, или я гоняюсь за отвлекающим маневром? Если бы кто-нибудь мог помочь мне понять, как изменить этот параметр для Glassfish 2.1.1, это также было бы очень полезно. Спасибо
РЕДАКТИРОВАТЬ: Люди спрашивают, почему я храню строки в виде необработанных байтов. Это не совсем то, что я делаю, иногда необработанные байты представляют собой изображение, PDF или двоичный файл, иногда это текст. Мой тест вставляет простую текстовую строку и извлекает ее обратно, чтобы убедиться, что она правильно сохранена. Этот тест проходит на нашем CI-сервере, работающем под Linux.
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)) конструктор. - person jlordo   schedule 12.02.2013byte[]
? Если нет, вам не следует использоватьString
... - person Jon Skeet   schedule 12.02.2013Strings
в виде необработанных байтов? - person Brian Roach   schedule 12.02.2013new String(attachment.getData(), Charset.lookup("UTF8"))
, и он все равно распечатал 87474703a2f2f6269742e6c792f617948363977. - person Daniel Kaplan   schedule 12.02.2013http://bit.ly/ayH69w
- person Daniel Kaplan   schedule 12.02.2013Charset.lookup(String)
в JavaDoc... откуда взялся этот метод? - person jlordo   schedule 12.02.2013forName
и получил ту же тарабарщину. - person Daniel Kaplan   schedule 12.02.2013