[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を解析して文字コードを取得するかどっちかだと思う。