質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.34%

Lambda + API Gateway でjsonを返そうとすると文字化けする。

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,708

Otazoman

score 39

AWSおよびPython初心者です。簡単なことなのかもしれませんがはまってしまって
困っています。ぜひお力をお貸しください。

サーバレスの勉強をしようとLambda+APIGateWayでサンプルを
作ろうとしています。Dynam-DBを使用せずLambdaでjsonを返すだけの
単純なものです。2つつまづいている点があります。対処方法をご教示
いただけますでしょうか。お願いいたします。

1.APIGateWay経由で返してきているjsonの日本語が取れない。
APIGateWayからブラウザで取得しようとする値が下図の様になっていて
日本語が正しく取得できません。
どの様にすれば数値列でない状態で日本語を取得できるでしょうか。

イメージ説明
 
APIGateWayでテストした際には以下の様に日本語ベースで取れているように
見受けられます。APIGateWayのメソッドレスポンス等で文字コードを足したり
Python側でも色々してみましたが上図のままでした。
 
APIテスト結果
イメージ説明

Lambdaコードは以下の通りです。

# coding: utf-8
import json
from urllib.parse import parse_qs

def lambda_handler(event, context):
    try:
#      params = parse_qs(event['body'].encode('utf-8'))
      print (json.dumps(event,indent=2))
      user_object = """{  
                         {
                           "id" : 12345,
                           "name":"山下 清",
                           "age" : 30,
                           "url": "http://www.yahoo.co.jp/"
                         },
                         {
                           "id" : 22222,
                           "name":"上田 尊司",
                           "age" : 45,
                           "url": "http://www.google.co.jp/"
                         },
                         {
                            "id" : 55555,
                            "name":"清宮 仁郎",
                            "age" : 28,
                            "url": "http://www.yahoo.co.jp/"
                         }
                   }"""

      # return json
      return {
              'statusCode' :200,
              'headers' : {'content-type' : 'application/json'},
              'body': json.dumps(user_object,ensure_ascii=False)
             }
    except Exception as e:
      print(e)
      raise e

2.json形式で取得した特定の値のキーが表示できない
1のLambdaおよびAPIGateWayで返されてきたjsonをパースして
idの値を取ろうとしているのですがエラーとなってしまい。
値が取れません。data[0].idの箇所です。どうやらNullの様です。
data自体はobjectとして認識されているようではありました。

    <script>
    function getJSON(){
      var req = new XMLHttpRequest();
      req.open('GET', "APIGAteWayのURI"); 
      req.send(null);                        

      req.onreadystatechange = function() {          
        if(req.readyState == 4 && req.status == 200){ 
          var data = JSON.parse(req.responseText);
          alert(data[0].id);
        }
          }
      };

下記の記事を参考にしてみたのですが意図したとおりに動いてくれません。
https://qiita.com/1mada/items/9a48f7053a6016b5fd5a

色々と試行錯誤してみましたが調べ方もわからない状態です。
周りにAWSに精通している方もいらっしゃらないので申し訳ないですが
ご教示よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

すでにJSON文字列になっているもの(user_object)を、
さらにdumpsでJSONシリアライズしているからでは?
2の部分でオブジェクトとしてパースできないのは、二重にJSONシリアライズされているからだと考えられます。

掲載されているコード中で、
user_objectを文字列ではなくlistにして再度やってみてください。
その際、{}[]になおすのを忘れずに。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/27 11:28 編集

    ひとまず下記のコードでNull値とならずundefindながら呼出せるレベルまでは
    来ました。日本語がUTF-8のコードで表示される件は解決していませんが
    ご回答ありがとうございます。


    user_object ={
    'statusCode' :200,
    'headers' : {'content-type' : 'application/json'},
    'body':[
    {
    'id' : 12345,
    'name':'山下 清',
    'age' : 30,
    'url': 'http://www.yahoo.co.jp/&#039;
    },
    {
    'id' : 22222,
    'name':'上田 尊司',
    'age' : 45,
    'url': 'http://www.google.co.jp/&#039;
    },
    {
    'id' : 55555,
    'name':'清宮 仁郎',
    'age' : 28,
    'url': 'http://www.yahoo.co.jp/&#039;
    }
    ]
    }
    # return json
    return json.dumps(user_object,ensure_ascii=False)

    キャンセル

0

  1. 文字化けしてるように見えますが、それは文字化けではなく、ユニコード文字列が16進表示されているだけです。
  2. user_object = """{の部分はuser_object = """[の間違いではないですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/26 17:49 編集

    早速のご回答ありがとうございます。

    1.
     ご指摘ありがとうございます。16進表示のままで戻ってきているので
     何とか漢字表示でうまく取得できないかと考えている次第です。
     ensure_ascii=False
    上記をLambdaに追加してみたり、APIGateWayのレスポンス本文に
     application/json;charset=UTF-8
    を追加しましたが状況は変わりません。

    2.
     user_objectの箇所を訂正しましたが。結果はやはりNullのままの
     様でした。jsonオブジェクトがうまくperseできていないようです。

    たびたびすいませんがよろしくお願いいたします。

    キャンセル

0

ひとまず解決しました。TKatayamaさんアドバイスありがとうございます。
json.dumpsせずにそのまま返してあげればidも取ることができました。
今後ともpython頑張らねば

import json
# -*- coding:utf-8 -*-
from urllib.parse import parse_qs

def lambda_handler(event, context):
    try:
      user_object =[
                         {
                           'id' : 12345,
                           'name':'山下 清',
                           'age' : 30,
                           'url': 'http://www.yahoo.co.jp/'
                         },
                         {
                           'id' : 22222,
                           'name':'上田 尊司',
                           'age' : 45,
                           'url': 'http://www.google.co.jp/'
                         },
                         {
                            'id' : 55555,
                            'name':'清宮 仁郎',
                            'age' : 28,
                            'url': 'http://www.yahoo.co.jp/'
                         }
                   ]
      # return json
      return user_object
     except Exception as e:
      print(e)
      raise e

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る