问题
Situation
I'm using AppEngine Cloud Endpoints (Java) as backendserver for my Android-application. In a Cron-Job the server regularly downloads new data (String), filters out relevant information and sends it via Firebase Cloud Messaging to different topics (by posting HTTP-Request to https://fcm.googleapis.com/fcm/send).
The (damn simple) Problem
The downloaded text is in German, containing letters like ä,ö,ü,ß and (to not have the famous ?s istead of these characters) I want to change the encoding to UTF-8.
US-ASCII encoding is the default when deployed to AppEngine (why isn't it UTF-8 by default...). When tested locally, the default encoding of my computer is used which is UTF-8 and everything is working just fine.
So all I want is Charset.getDefaultCharset()
to return UTF-8
.
How do I achieve this?
Thanks in advance, all help appreciated.
What I've tried
adding this to appengine-web.xml:
<env-variables> <env-var name="DEFAULT_ENCODING" value="UTF-8" /> </env-variables>
When testing locally I got IncorrectEnvironmentVariableException. When deployed encoding was still ASCII.
adding this to
<system-properties>
-tag in appengine-web.xml:<property name="file.encoding" value="UTF-8" /> <property name="DEFAULT_ENCODING" value="UTF-8" />
changed nothing, not only when deployed but also when I tried to use this to set the encoding to US-ASCII on local developement server, still UTF-8 was returned by
Charset.getDefaultCharset()
even tried to use reflection:
System.setProperty("file.encoding","UTF-8"); Field charset = Charset.class.getDeclaredField("defaultCharset"); charset.setAccessible(true); charset.set(null,null);
(caused IllegalAccessException)
tried setting encoding as content-type-property with the HTTP-post (didn't work):
connection.setRequestProperty("Content-Type", application/json; charset=UTF-8);
回答1:
Short Answer
If you have problems with encoding (i.e. '?'s) and it seems like changing default-charset solves the problem then what you really have to do is to find the code where the default-charset is used for encoding and pass a custom charset to be used instead.
(Like @AndreiVolgin commented: You should never rely on the system default-charset.)
More detailed Answer
A charset specifies how chars are represented as numbers (i.e. bytes).
The internal charset of all Strings in Java is in fact UTF-16 so the only time custom charsets become important is when converting a String to a byte-Array (String.getBytes()
) or vice versa (new String(byte[]
).
This is where the default-charset is used if you don't pass a charset like String.getBytes(Charset)
or new String(byte[], Charset)
.
You get to see '?'s when different charsets are used for encoding (String.getBytes()
) and decoding (new String(byte[]
).
So to get rid of the '?'s replace String.getBytes()
by String.getBytes(Charset)
(or maybe replace new String(byte[])
by new String(byte[], Charset)
but don't know if thats a thing).
For me the encoding problem occured when sending some text via the internet because the String needs to be converted to byte[]
to send it using HttpURLConnection.getOutputStream().write(byte[])
.
To be precise: In class com.google.android.gcm.server.Sender
, method post(java.lang.String, java.lang.String, java.lang.String)
, line 471 was byte[] bytes = body.getBytes();
.
I changed it (overwrote it) to byte[] bytes = body.getBytes("UTF-8");
- solved it for me.
来源:https://stackoverflow.com/questions/41204936/google-appengine-how-to-set-default-charset-file-encoding-to-utf-8-for-goo