Reputation: 22958
Is it please possible to escape UTF-8 characters when using JSON.toString()
method in jetty-util-ajax package?
I understand that the package might be an internal library, but until now it works well for me in a servlet which among other tasks sends push notifications to mobile phones via FCM (Firebase Cloud Messaging) and ADM (Amazon Device Messaging).
However my problem with is that ADM does not accept any UTF-8 chars (in my case Cyrillic) and reproducibly fails with the rather misleading error message (Amazon talks about XML in all its error messages while their API expects JSON data being POSTed):
<SerializationException>
<Message>Could not parse XML</Message>
</SerializationException>
java.lang.IllegalStateException:
unknown char '<'(60) in |||<SerializationException>| <Message>Could
not parse XML</Message>|</SerializationException>||
So is there maybe some possibility in Jetty 9.4.8.v20171121 to encode the chars?
Here is my Java code:
// 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", "[email protected]")
.header("X-Amzn-Accept-Type", "[email protected]")
// add registrationID and notification body - for retrying after fetching token
.attribute("registrationId", registrationId)
.attribute("body", jsonStr)
.content(new StringContentProvider(jsonStr))
.send(mMessageListener);
}
When looking at the Jetty source code JSON.java there is some decoding happening (i.e. from \uXXXX
to UTF-8 chars):
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;
But how to do the reverse thing?
Upvotes: 0
Views: 342
Reputation: 49452
The ContentProvider's are the source of the Content-Type
, not your manually set header.
Change your ...
.content(new StringContentProvider(jsonStr))
to ...
.content(new StringContentProvider(jsonStr, "application/json", StandardCharsets.UTF_8))
as the default for StringContentProvider
is text/plain
(not JSON)
Upvotes: 1