問題解決の自己ログ

下位ページ

Content

文字コードが変


問題点

get.phpでタスクを取得すると、日本語が読めない

症状の確認

[{"num":719,"total":719},{"id":111111111,"title":"\u30c6\u30b9\u30c8","modified":1426716138,"completed":1416830400,"folder":0,"priority":2,"star":0},
ブラウザ上で、直接URLに打ち込んで、返ってくるのがこんな状態。

送られてきている文字列のコードを確認

ToodledoのAPIのページを確認

文字コードは全てUTF-8との記述

ヘッダとかに何か無いか?

追加確認

実際はUTF-16ではないかと疑っていたので、
http://encodemaniax.com/
確認した文字列では、UTF-8とUTF-16は同じ結果になったので、Toodledoさんを信じる。でも、
http://so-zou.jp/web-app/text/encode-decode/
ここでやると、正しく見えるのはUTF-16のみになるんだよな。

送られてきた文字列を、直に打って読ませたらどうなるか?

レスポンスで帰ってきた文字列を直打ちしてみた。(当然 " は \" でエスケープ)
String str3 = "{\"id\":164586863,\"title\":\"\u5203\u5177\u7834\u640d\u306e\u7406\u8ad6\",\"modified\":1426716138,\"completed\":1423656000,\"folder\":0,\"priority\":0,\"star\":0}"
結果は、ちゃんと日本語文字列になって出てきた。InputStreamReaderから受けた結果に対して、エスケープシーケンスを認識していないのか?
{"id":164586863,"title":"刃具破損の理論","modified":1426716138,"completed":1423656000,"folder":0,"priority":0,"star":0}

気付き

よくよく見たら、ダブルクォーテーションはエスケープされなければならないはずなのに、されていない。ということは、JSONデータの中の一つとしてとして読み出せば、認識されるのか?

JSONのデータに分解して、それ以外は特に何もせず表示してみる

うまく行きました。

文字化けが起きた(文字コードが変2)

しばらく何事もなかったのに、Toodledoで新しいタスクを作成する処理を行っているときに、iPhone経由でのタスク登録にて文字化けが発生。(iPhone以外では、日本語のタスクを作成しなかった、とかではないと思うが。。。)

確認

  • アラートですぐ表示 OK
  • サーバでの受取での表示 OK
  • Toodledo での受取 NG
なので、servlet→toodledoの送信でだめ?っぽい。

解決まで

どこで文字コードをセットし直すかがよくわからないが、文字コードをセットできる場所としてPrintStream 生成時に UTF-8 を追加
で、正常動作(文字化け回避)になった。

Eclipseが立ち上がらない、うまく動作しない問題

前回、eclipseが立ち上がらず、強制終了。その影響か、eclipseが立ち上がらなくなった。

オプション付きで起動

コマンドプロンプトから、 -clean オプションで起動 → ダメだった。

ロックファイルみたいなもの?を削除

.snapというファイルが、ワークスペースの.metadateフォルダやら、個々のプロジェクトの中にあるが、これを一旦削除して、起動させる。 → 前回より起動時のバーは進んだが、結局ダメだった。

.metadataフォルダを全て消す(というか一時退避)

起動はしたが、プロジェクトなどは全消去。
ファイル→インポートで既存プロジェクトを引っ張る。→フォルダにエラーのマーク
クラスにメインが無い、というエラー。jdkのバージョンをjdk1.7に上げたら、コンパイルは出来たがエラーマークは消えず。
プロパティ→プロジェクト・ファセットでバージョンを合わせたら、エラーマークは消えた。

localhostで動かすとエラー

テストとしてlocalhostで立ち上げたら、localhostでエラー。
javax.servlet.FilterChain is a restricted class.
他のサイトを見ると、jdk1.7にするとか書いてあるが、さっき上げたばっか。同じ1.7でもバージョンに依る、という話もあったり。しょうがないので、google appengineとかjdkとか全て更新。
google appengineは手動ダウンロードで、別のバージョンと同じ階層に解凍して、と頑張ったが、eclipseで更新を掛けたほうでエラーが収まった。その後、jspファイルにエラーがでたが、ライブラリの指定がjreになっていなので、jdkにかえてひとまず一件落着。

JSONデータの吸い出し

ToodledoのGETでデータを取得すると
[{"AAA1":"A1","AAA2":"A2"},{"BBB1":"B11","BBB2":"B21"},{"BBB1":"B12","BBB2":"B22"},{"BBB1":"B13","BBB2":"B23"}]
というならび。タイプAがひとつのあとに、タイプBが複数個続く。どうやって情報を取るか。とりあえず既に入っているJSONICでトライ。

Map(キーと値)をリストにしてみる。

記法がよくわからず。

classの作成

CCCというクラスを作ってみた。CCCはひとつのAAAとListのBBBをもつ。
→JSONExceptionを吐いて、「うまく渡せません」とエラー。

しょうがないので、AAAとBBBの要素を両方持つクラスをつくって、これを配列とした。
AAAPLUSBBB[] ABarray = JSON.decode(str1, AAAPLUSBBB[].class);

ところで全部のキーを準備する必要があるのか?

AAAは実際のところ、使用する予定がほとんどないので、なしにしてみた。特に問題なし。反対に余分なキー(変数)が合っても問題なさそう。

JSPがうまく動かない

症状

ローカル?ではうまく動いていたJSPが、GAEに上げたらうまく動かない

結果的に解決

Java8だとうまく動かないらしい記事を読む。しょうがないのでJava7に落とした。
この際、バージョンダウンしたあと、エラーじるしがつき続けるが、プロジェクト・ファセットというところで、コンパイルバージョン(の情報)がJava8のままになっていた。ここを直して、エラーも消えた。

JSONデータの、JSONICでの取り出し(デコード)その2

{
 "key1" : "String1",
 "key2" : "String2",
 "key3" : [
           ["value00","value01"],
           ["value10","value11"],
           ["value20","value21"]
          ]
}
というデータが来る。たまに
{
 "key1" : "String1",
 "key2" : "String2",
 "key3" : "String3"
}
もある。どのような型を指定して、変換したら良いのか。。。

試した方法(失敗)

HashMap<String, String> map = JSON.decode(response);
実行時に NullPointerException エラー

HashMap<String, String[][]> map = JSON.decode(response);
読み込み時にエラーは出ないが、読み出そうとすると
ArrayListを配列にキャストできない
というエラーが出る。

解決?

HashMap<String, ArrayList<ArrayList<String>>> map = JSON.decode(response);
と指定して、
map.get("key3").get(0).get(0)
としたら取り出せた。で、
System.out.println( map.get("key1") )
は通るのに、ArrayList<ArrayList<String>>にしたよな、と思って
map.get("key1").get(0).get(0)
にしたら
String は ArrayList にキャストできない
とでる。どうなっているのか。

もう少し調べる。

JSONICの説明ページを見たら、配列は(指定しない場合やListを指定した場合は)ArrayListに変換する、とある。なので、 ArrayListに変換されている。さらに、そのリストの要素も、同様のルール(ここでは要素の配列もArrayListに)変換される。ので、上記のとりあえずできた方法の結果になったと推測。
key1の"String1" はそのままString型で取り込まれて、map.get("key1") は ArrayList<ArrayList<String>> を指定しても、結局 String になっている模様。
ならば、最初からMap<String, Object> でよかったのでは?と思ってやったら、key3 の取り出し時に、.get(1) が使えなくて困る。
そこで
ArrayList<ArrayList<String>> a = (ArrayList<ArrayList<String>>)map.get("key3");
としてから取り出す。ただし、「キャストしてもいいの?」と警告はでる。

結局のところ、

JSON.decode の説明の読み方を理解していなかった。ということでしょうか。



Google API のsampleコードをeclipseで動かそうとして、手こずる

gradleの設定がうまくできない。(というか環境変数がよくわかっていない)

症状

環境変数を設定したけど、「設定されてない」と出る。

原因

ユーザー環境変数とシステム環境変数の使い分けをよくわかっていない。
Gradleの設定のためのパスはユーザー環境変数に登録しないとだめ?

対処

環境変数の設定

症状2

環境変数を変えた後、毎回再起動させなくちゃいかんのか?

答え

コマンドプロンプトで作業していたが、コマンドプロンプトを立ち上げ直せばそれでよかった。

必要なjarファイルが揃っていない

症状

eclipseの、google プラグインの Add Google API を使ってsheets API を持ってきたら、足りないクラスがある。

原因

サンプルプログラムをgradleで動かしたときのAPIバージョンと、Add Google API でダウンロードしたAPIバージョンが違う。

対処

サイトからダウンロードした最新版のAPIを使ったら、エラーが消えた。

eclipseでライブラリの参照方法がよくわかっていない

症状

取ってきたライブラリを設定したつもりが、「ライブラリないよ」と言われる。

原因・対処

正直使い分けがわかっていない。ビルドパスの構成で、ライブラリの参照ではなくて、外部jarの参照にしたら反映された。
最終更新:2017年01月22日 11:41