如何在jetty-util-ajax的JSON.toString()中转义UTF-8/Unicode字符?
Got it, let's break this down clearly. First, let's confirm the core issue: the default JSON.toString() method from jetty-util-ajax outputs UTF-8 characters directly (like your Cyrillic text) instead of escaping them to Unicode escape sequences (\uXXXX). Since ADM doesn't handle raw UTF-8 well and returns misleading errors, we need to adjust how the JSON is serialized.
Can JSON.toString() escape UTF-8 characters directly?
By default, no. The standard implementation writes UTF-8 characters as-is, which works fine for FCM but fails for ADM. However, jetty's JSON API is flexible enough to let us customize this behavior.
How to escape Unicode characters with jetty-util-ajax
The best approach is to create a custom JSON.Output implementation that overrides the string-writing logic to escape non-ASCII characters. Here's a practical example:
Step 1: Create a custom Unicode-escaping Output class
import org.eclipse.jetty.util.ajax.JSON; import java.io.IOException; import java.io.Writer; public class UnicodeEscapingJsonOutput extends JSON.Output { public UnicodeEscapingJsonOutput(Writer writer) { super(writer); } @Override public void writeString(String s) throws IOException { write('"'); for (char c : s.toCharArray()) { // Handle standard JSON escape characters first if (c == '"' || c == '\\' || c == '/') { write('\\'); write(c); } // Escape control characters (0x00 to 0x1F) else if (c <= 0x1F) { write(String.format("\\u%04x", (int) c)); } // Escape all non-ASCII characters (above 0x7F) else if (c > 0x7F) { write(String.format("\\u%04x", (int) c)); } // Write ASCII characters as-is else { write(c); } } write('"'); } }
Step 2: Use the custom Output to serialize your data
Instead of calling JSON.toString(), use the custom output to generate your JSON string:
import java.io.StringWriter; public class AdmNotificationSerializer { public static void main(String[] args) { // Example content with Cyrillic characters String notificationContent = "Привет, мир!"; StringWriter writer = new StringWriter(); JSON.Output unicodeOutput = new UnicodeEscapingJsonOutput(writer); // Serialize your object/string to JSON with Unicode escaping JSON.get().toJSON(notificationContent, unicodeOutput); String escapedJson = writer.toString(); // Result will be: "\"\\u041F\\u0440\\u0438\\u0432\\u0435\\u0442, \\u043C\\u0438\\u0440!\"" System.out.println(escapedJson); } }
Alternative: Post-process the default JSON output
If you don't want to create a custom Output, you could post-process the string returned by JSON.toString() to escape non-ASCII characters. However, this is riskier because you might accidentally break existing escaped sequences (like \" or \\). The custom Output approach is far more reliable.
Quick check: Double-check your ADM request headers
Before fully committing to escaping, make sure you're setting the Content-Type header correctly in your ADM requests:
connection.setRequestProperty("Content-Type", "application/json; charset=utf-8");
Sometimes raw UTF-8 works if the headers are properly set, but if ADM still rejects it, the Unicode escaping method above will solve the issue.
内容的提问来源于stack exchange,提问作者Alexander Farber

