JSONのエンコード
とても参考になったサイト:
1.encode() 時は、ハッシュ内の全ての非 ASCII 文字列は、必ず予め utf8 フラグ ON にしておく。
2.encode() で出力される JSON 文字列の utf8 フラグは、予め utf8() メソッドで指定できる。
3.decode() 時は、入力する JSON 文字列の utf8 フラグの状態を、必ず utf8() メソッドで指定する。
4.decode() で出力されるハッシュ内の文字列の utf8 フラグの状態は、文字列の内容(ASCII/非ASCII)に依存する。
詳しく。。
JSON モジュールで utf8 を扱う際の注意点
入力ハッシュが日本語などの非 ASCII 文字列を含む場合は、
必ず utf8 フラグ ON (string) である必要があります。
utf8 フラグ OFF (octets) の日本語を含むハッシュを入力すると、文字化けします。
utf8 フラグ OFF (octets) の ASCII 文字のみの場合は、問題は起こりません。
- encode 時に出力される JSON 文字列の utf8 フラグの状態は、utf8() メソッドの指定通りになります。
- JSON->new->encode($hash) ⇒ 常に utf8 フラグ ON(デフォルト)
- JSON->new->utf8(0)->encode($hash) ⇒ 常に utf8 フラグ ON
- JSON->new->utf8(1)->encode($hash) ⇒ 常に utf8 フラグ OFF
入力する JSON に日本語などの非 ASCII 文字列を含む場合は、
->utf8(0) してから、utf8 フラグを ON にした JSON を入力するか、または
->utf8(1) してから、utf8 フラグを OFF にした JSON を入力する必要があります。
それ以外の組み合わせでは、エラーが発生するか、文字化けします。
- JSON->new->utf8(0)->decode($string) ⇒ OK!
- JSON->new->utf8(1)->decode($string) ⇒ エラー!
- JSON->new->utf8(1)->decode($octets) ⇒ OK!
- JSON::XS->new->utf8(0)->decode($octets) ⇒ 文字化け!
- JSON::PP->new->utf8(0)->decode($octets) ⇒ 全て utf8 フラグ OFF で返ります(例外)
- decode 時に生成される Perl オブジェクト中の文字列の utf8 フラグの状態は、
- 文字列の内容に依存します。
- ASCII 文字のみの文字列は、常に utf8 フラグ OFF になります。
- 非 ASCII 文字を含む文字列は、常に utf8 フラグ ON になります。
#!/usr/bin/perl use JSON; use Data::Dumper; my %allList; my $hs = { 'ip' => '', 'lter' => '0', 'indate' => '2010-04-01', 'outdate' => '0000-00-00', 'nm_no' => '344', 'name' => '廣中', 'grp' => 'VM' }; my $hss = { 'lter' => '0', 'indate' => '2007-04-02', 'name_ff' => 'てつや', 'outdate' => '0000-00-00', 'nm_no' => '101', 'grp' => 'OSS' }; my $ldaprel = { 'pkiflag' => '1', 'manager' => [ ], 'TelephoneNumber' => '', 'postalCode' => '' }; #-- JSONに変換する前に Encode::decode_utf8 --- $hs->{$_} = Encode::decode_utf8($hs->{$_}) foreach keys %$hs; $hss->{$_} = Encode::decode_utf8($hss->{$_}) foreach keys %$hss; $ldaprel->{$_} = Encode::decode_utf8($ldaprel->{$_}) foreach keys %$ldaprel; $allList{0} = {'mysql' => $hs, 'postgres' => $hss, 'ldap' => $ldaprel}; # print Dumper(%allList); #-- JSONに変換 --- my $allList_json = JSON->new->encode(\%allList); # print Dumper($allList_json); #================================ #-- JSONから変換 --- my $allList_j = JSON->new->utf8(0)->decode($allList_json); print scalar(keys(%$allList_j)); #-- ハッシュに戻したあとに Encode::encode_utf8 --- foreach my $keyno( keys %$allList_j){ foreach my $keydb( keys %{$allList_j->{$keyno}}){ my $dbeach = $allList_j->{$keyno}->{$keydb}; $dbeach->{$_} = Encode::encode_utf8($dbeach->{$_}) foreach keys %$dbeach; } } # print Dumper($allList_j);