[RESTeasy]JSONのアンマーシャルと文字判定
RESTeasyでJSONをUnmarshalしようとするとして文字化けが起こりパースに失敗する。
RESTeasyではデフォルトでJSONのマーシャル、アンマーシャルにはjettisonを使っている。
jettisonには問題なさそうなのでで、RESTeasyからjettisonに渡す配管コードを追いかけてみた。
JettisonMappedUnmarshallerクラスがjettisonのunmarshallerに投げているのだが、これがよろしくないようだ。
public Object unmarshal(Source source)
throws JAXBException {
if (!(source instanceof StreamSource)) {
throw new UnsupportedOperationException("Expecting a StreamSource");
}
StreamSource stream = (StreamSource) source;
XMLStreamReader reader = getXmlStreamReader(new InputStreamReader(stream.getInputStream()));
return unmarshal(reader);
}
InputStreamをReaderに食べさせているのだが、文字コードの指定がない。
InputStreamReaderのコンストラクタは第二引数の文字コードの指定が省略された場合にStreamDecoder.forInputStreamReader()を使い文字コードを決定する。この、文字コードの判定がVM引数の”file.encoding”をみている。”file.encoding”はWindows系だとMS932とか使われる場合がある。つまり、OSに依存するって話だ。
もちろん、Tomcatなりglassfishなりで起動オプションで指定すればいいのだが、RESTのとあるデータ形式からのアンマーシャルで使っていいような環境変数ではない気がする。
ここは、リクエストのContent-Typeからひっぱてくるか、InputStreamを解析して文字コードを取得するかどっちかだと思う。