Как избежать Unicode с методом JSON.toString() в jetty-util-ajax?
Можно ли экранировать символы UTF-8 при использовании? JSON.toString()
метод в пакете jetty-util-ajax?
Я понимаю, что пакет может быть внутренней библиотекой, но до сих пор он хорошо работает для меня в сервлете, который среди прочих задач отправляет push-уведомления на мобильные телефоны через FCM (Firebase Cloud Messaging) и ADM (Amazon Device Messaging).
Однако моя проблема в том, что ADM не принимает символы UTF-8 (в моем случае кириллица) и воспроизводимо завершается с довольновводящим в заблуждение сообщением об ошибке (Amazon говорит о XML во всех своих сообщениях об ошибках, в то время как их API ожидает, что данные JSON будут отправлены):
<SerializationException>
<Message>Could not parse XML</Message>
</SerializationException>
java.lang.IllegalStateException:
unknown char '<'(60) in |||<SerializationException>| <Message>Could
not parse XML</Message>|</SerializationException>||
Так есть ли в Jetty 9.4.8.v20171121 какая-то возможность кодировать символы?
Вот мой код Java:
// this string is POSTed to ADM server
public String toAdmBody() {
Map<String, Object> root = new HashMap<>();
Map<String, String> data = new HashMap<>();
root.put("data", data);
data.put("body", mBody);
// ADM does not accept integers for some reason
data.put("gid", String.valueOf(mGid));
// HOW TO ENCODE UTF-8 CHARS TO \uXXXX HERE?
return JSON.toString(root);
}
private void postMessage(String registrationId, int uid, String jsonStr) {
mHttpClient.POST(String.format("https://api.amazon.com/messaging/registrations/%1$s/messages", registrationId))
.header(HttpHeader.ACCEPT, "application/json; charset=utf-8")
.header(HttpHeader.CONTENT_TYPE, "application/json; charset=utf-8")
.header(HttpHeader.AUTHORIZATION, "Bearer " + mAccessToken)
.header("X-Amzn-Type-Version", "com.amazon.device.messaging.ADMMessage@1.0")
.header("X-Amzn-Accept-Type", "com.amazon.device.messaging.ADMSendResult@1.0")
// add registrationID and notification body - for retrying after fetching token
.attribute("registrationId", registrationId)
.attribute("body", jsonStr)
.content(new StringContentProvider(jsonStr))
.send(mMessageListener);
}
При просмотре исходного кода Jetty JSON.java происходит некоторое декодирование (например, из \uXXXX
до UTF-8 символов):
case 'u':
char uc = (char)((TypeUtil.convertHexDigit((byte)source.next()) << 12)
+ (TypeUtil.convertHexDigit((byte)source.next()) << 8)
+ (TypeUtil.convertHexDigit((byte)source.next()) << 4)
+ (TypeUtil.convertHexDigit((byte)source.next())));
scratch[i++] = uc;
break;
Но как сделать обратное?
1 ответ
ContentProvider являются источником Content-Type
, а не ваш вручную установленный заголовок.
Измени свой...
.content(new StringContentProvider(jsonStr))
чтобы...
.content(new StringContentProvider(jsonStr, "application/json", StandardCharsets.UTF_8))
по умолчанию для StringContentProvider
является text/plain
(не JSON)