powered by simpleCommunicator - 2.0.38     © 2025 Programmizd 02
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Кодировка в REST
15 сообщений из 15, страница 1 из 1
Кодировка в REST
    #38622583
phomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте, коллеги.

Столкнулись с проблемой при получении данных из REST запроса.

Дана JSON строка:
Код: javascript
1.
{"Param":"русские буквы"}


Из нее необходимо получить объект. $$$THROWONERROR(st,##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(%request.Content,,.obj,1)) 
 W obj.Param
 На выводе:
Код: javascript
1.
фывфывфыв


Посмотрела в описании метода..о кодировке ни слова. Однако в методах обратного преобразования везде указана utf-8.
При передаче запроса от REST клиента, в заголовке Content-Type:"text/json; charset=utf-8"
Клиент на java, хотя не уверена, что это имеет значение.

У меня, к сожалению, нет идей как это исправить. Может кто-то уже работал с этими методами?
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622705
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
phomka ,
 d $system.OBJ.DisplayError(##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject("{""Param"":""русские буквы""}",,.obj,$$$YES))
 w obj.ParamРезультат:

Код: plaintext
1.
USER>d ^test
русские буквы

Проверьте содержимое
  • %request.Content
  • %request.ContentType
  • %request.CharSet
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622740
EvLaUy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
phomka,
в подобных ситуациях лучшими друзьями становятся функции extract, ascii и char. Вам почему-то в кодировке UTF-8 пришла строка "фывфывфыв". Вы именно такую задавали? Нужно пройтись по ней extract'ом и для каждого символа посмотреть его код функцией ascii. У Вас будет что-то типа 209, 148, 209, 155, 208, 178 и т.д. А потом набрать в терминале строку русским буквами, сохранить ее в какой-то переменной, убедиться, что райтом она нормально отображается и посмотреть коды ее байт. Затем сравнить и попытаться объяснить разницу. Когда-то в особо тяжелых случаях я на основании этого анализа просто писал свой конвертор да и всё, но сейчас, думаю, в таком радикальном решении уже нет необходимости, ибо в Cache уже достаточно "рулей", которые Вам указал servit, чтобы решить проблему "малой кровью".
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622776
phomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
4@%CSP.BinaryStream

text/json

UTF-8

И они одинаковы, если я просто вставлю запрос в виде строки, или если получу от клиента. А выводятся по разному.
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622785
phomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
EvLaUy, да, строка там была другая - немного схалтурила...

Воспользуюсь советом, отпишусь что получится.
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622800
phomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
EvLaUy,

Хотя, получается, что проблема в %request.Content...
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622830
EvLaUy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне сложно сказать в чем проблема, у меня сейчас нет под рукой cache. Может быть, всё дело в том, как Вы задаете эту строку перед отправкой запроса? Если это Java, попробуйте задать ее в кодах utf-8. Что-то типа "ĒİŁ\u14f", это кажется строка "Вася". Посмотрите, поможет ли. Во всяком случае, будет уверенность, что она уходит именно в кодировке utf-8.
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622833
EvLaUy
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
"ĒİŁ\u 0 14f"
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622894
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
phomka4@%CSP.BinaryStreamТо, что это поток, и так понятно: каково его содержимое?

##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject("4@%CSP.BinaryStream",,.obj,1)

выдаст ошибку

Код: plaintext
ОШИБКА #5001: Expected { at start of JSON text.

, так же как и

##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject(%request.Content,,.obj,1)

должен выдать эту же ошибку, так как на вход метода ожидается строка, а Вы передаёте поток.
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622989
Александр Коблов
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Насколько я понимаю, сейчас %request.Content игнорирует заголовок ContentType.
То есть вам нужно самой смотреть значение %request.Content.ContentType и в зависимости от charset преобразовывать строку во внутренний формат Caché.

Например, из UTF-8 можно преобразовать следующей командой (первый 100 знаков):Set str = $ZCVT(%request.Content.Read(100),"I","UTF8")
или таким образом:if $isobject(%request.Content) {
   Set %request.Content.Attributes("CharEncoding")="UTF8"
   Set stream=##class(%IO.MetaCharacterStream).%New(%request.Content)
   Set ^lastRequestContent = stream.Read()
} Заметьте, что %request.Content типа %CSP.BinaryStream, то есть это бинарный, а не символьный поток.

##class(%ZEN.Auxiliary.jsonProvider).%ConvertJSONToObject может принимать на вход и строки и потоки.
http://docs.intersystems.com/cache20141/csp/documatic/%CSP.Documatic.cls?PAGE=CLASS&LIBRARY=%SYS&CLASSNAME=%ZEN.Auxiliary.jsonProvider#%ConvertJSONToObject
...
Рейтинг: 0 / 0
Кодировка в REST
    #38622991
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
phomka ,

Код: plaintext
1.
USER>w $zcvt($zcvt("фывфывфыв","O","CP1251"),"I","UTF8")
фывфывфыв

соответственно

Код: plaintext
1.
USER>w $zcvt($zcvt("фывфывфыв","O","UTF8"),"I","CP1251")
фывфывфыв

Итого где-то происходит конвертация в кодировку Windows-1251.

PS: какую версию Caché используете: Unicode или 8-битную?
...
Рейтинг: 0 / 0
Кодировка в REST
    #38623024
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Александр Коблов%ConvertJSONToObject может принимать на вход и строки и потоки.Ценное замечание: по сигнатуре метода и соответственно подсказке кода этого и не скажешь.
...
Рейтинг: 0 / 0
Кодировка в REST
    #38623896
phomka
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Коллеги, спасибо!
Я вчера все прочитала и все сделала.
Очень ценные советы.

servit, использую 8-битную версию.
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Кодировка в REST
    #39001996
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
phomkaУ меня, к сожалению, нет идей как это исправить.В будущих версиях можно будет включить автоматическую конвертацию тела запроса, а пока можно воспользоваться следующим кодом: If $IsObject(%request.Content),$zcvt(%request.Content.ContentType,"L")["charset=utf-8" {
  Set contentTmp=%request.Content.%ConstructClone(-1)
  Set contentTmp.Attributes("CharEncoding")="UTF8"

  ; сохраняем переданные атрибуты
  Merge attr=%request.Content.Attributes
  Do %request.Content.Clear()
  Merge %request.Content.Attributes=attr
  
  Do %request.Content.CopyFrom(##class(%IO.MetaCharacterStream).%New(contentTmp))
 }, который лучше поместить в метод OnPreDispatch .

Далее работаете с %request.Content как обычно.

PS: спасибо Александр Коблов за наводку на %IO.MetaCharacterStream.
...
Рейтинг: 0 / 0
Кодировка в REST
    #39102700
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
servitВ будущих версиях можно будет включить автоматическую конвертацию тела запросаВ 2016.1 уже добавили эту возможность, проверил - работает.
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Кодировка в REST
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]