ページビューの合計

2022年12月28日水曜日

#Magic #xpi を介した #Notes / #Domino と #IBMi の連携

Finally, the year is just a few days away.

I recently wrote an article about converting IBMi data to JSON with Magic xpi for use in DominoLeap.
This time, I report that the data is now available in Notes client using Lotusscript.
There were a few things to note in the JSON specification, which I hope will be helpful.

みなさま、こんにちは。
いよいよ今年もあとわずかですね。

早速ですが、先日

#Magic #xpi を介した #DominoVolt ( #DominoLeap ) と #IBMi の連携

という記事で、IBMiにあるデータをMagic xpiを経由することでJSON化して、DominoVolt(DominoLeap)に取得するという内容を紹介しました。

もちろん弊社にとって、要求された内容ではあったのですが、現状ノーツクライアントに依存している環境から、LeapでなくNotes側でも利用したいということは言うまでもありません。

ノーツクライアントでのREST APIについては、

#郵便番号 から #住所 を取得しよう( #鬼わか の #REST #API を適用したサンプル)

こちらの記事で、提供されたサンプルを紹介しましたので、こちらに割り当てていくことで簡単にできるのではと安易に考えていたのです。

ということで、いざ!!
とまずは鬼わかで利用したフォームごとコピーしてきてテストを開始しました。

ここで今更ながら前段・・・
私はLotusscriptをほとんど使用していない、未熟者になります。

そんな私が、鬼わかのコードを読んでいくと、いろいろと丁寧な処理が含まれていることに気づきました。

私なりにその「丁寧な部分」を外していき、シンプルな構成にしていけるだろうと実行してみたのですが結果はNG。

NotesJSONNavigatorにセットしたいのですが、以下エラーが発生しました。

「JSON 文字列を解析できません: Invalid value. offset 0」

デバッガーで見てもわからず、今回もまたサポートの方の手を煩わせることになってしまいました。

まず指摘があったのが、「レスポンスはバイト配列にはなっていない」との事でした。

そこでChromeの開発者ツールを使用して情報提供の依頼があり、対応しました。
ちなみにこの部分については、以下記事を紹介頂きました。

https://support.hcltechsw.com/csm?id=kb_article&sysparm_article=KB0039010

指示されたデータを提出すると、「レスポンスヘッダが、「Content-Type: text/html」となっている」との指摘がありました。
レスポンスヘッダの「Content-Type」に「application/json」をセットしてくださいとの指示を頂きました。

こちらはMagic側の問題と考え、マジックソフト社のサポートへ連絡して指示を仰ぎました。
そもそもJSONとしてデータを取得しているので、デフォルトでそうなっていないのが少し疑問・・・といいますか、先のDominoLeapは解釈してくれてたんだぁ・・・と違和感の残る結果ではありますが、無事サポートの指示により「Content-Type=pplication/json」をセットすることができました。

その後、再度実行したのですが、今度は以下エラーが表示されました。

「HTTP 応答コンテンツタイプはサポートされません」

上記を報告したところ、テスト用のスクリプトを提供頂き、試すこととなりました。

ここで私のミス1回目

Magic xpi ですが、開発用のサーバーでテストを行っております。
開発用の制限として、プロジェクトは24時間で自動終了するという仕様があることを忘れておりました。
つまり・・・「応答なし」状態で問い合わせを継続していたということです。

・・・申し訳ありません・・・

再度テストを行う際に、Wireshark を使ってネットワークキャプチャしたデータの提供ができないかとの相談がありました。

現時点で私のクライアントにインストールしたV12.0.2(64bit)でテストしていたため、こちらも問題なく対応し、データを提供したところ。

「Content-Type:」 と「application/json」の間に半角スペースが2つあります

との事。
あわててMagicの設定を見ると、確かにスペースが入っています。
私がどこかでコピペしたのですが、そもそもそちらに入っていたようです。

またヘッダ部分とBody部分の間に不要な文字が含まれていることも判明しました。

この文字列については再度マジック社に問い合わせたところ、BOM付きのデータになっているとの事でした。

この時点でBOMは外せなかったので、そのままテストし、Wiresharkのデータを解析して頂きました。

しかしながらやはり、BOMが邪魔のようで、Lotusscript側で外すスクリプトの提供を頂きました。

' BOM 除去
 i=0
 ReDim json(UBound(returnValue)-3)
 ForAll x In returnValue
 If i > 2 Then
 json(i-3) = x
 End If
 i = i + 1
 End ForAll

その後、幾度かのやりとりがあったのですが・・・

ここで私のミス・・・2回目

先とまったく同じミス、プロジェクトが停止していました。
何度も申し訳ございません orz   お恥ずかしい限りで・・・

それでも意味の不明な動きなどもあり、最終的に以下スクリプトを頂きテストすることになりました。

Sub Initialize
 Dim ws As New NotesUIWorkspace
 Dim uidoc As NotesUIDocument
 Dim session As New NotesSession
 Dim http As NotesHTTPRequest
 Dim url As String
 Dim returnValue As Variant
 Dim i As Integer
 Dim json As string

 Set uidoc = ws.CurrentDocument
 url = "URLを指定する"
 Set http = session.CreateHTTPRequest()
 Call http.SetHeaderField("Accept", "application/json")
 http.Preferstrings=true
 returnValue = http.Get(url)
 json = Mid(returnValue,2,Len(returnValue))

 Dim jsonNav As NotesJSONNavigator
 Dim jsonElement As NotesJSONElement

 Set jsonNav = session.CreateJSONNavigator(json)
 Set jsonElement = jsonNav.Getelementbyname("JSONのKEY")
 msgbox "value=" + jsonElement.Value + " type=" + CStr(jsonElement.type)
 End Sub

こちらを実行すると、想定されたメッセージボックスが表示されました!!

ここまでくれば、あとはJSONのデータを必要なフィールドに割当てるだけ。

Sub Click(Source As Button)
 Dim ws As New NotesUIWorkspace
 Dim uidoc As NotesUIDocument
 Dim session As New NotesSession
 Dim http As NotesHTTPRequest
 Dim url As String
 Dim returnValue As Variant
 Dim textCode As String
 Dim json As String

 ' "zip"フィールドの値を取得して、リクエストURIを生成
 Set uidoc = ws.CurrentDocument
 textCode = uidoc.FieldGetText("zip")

 url = "REST接続するURLを記述"
 url = url + textCode

 ' Getリクエストを実行し、結果を取得
 Set http = session.CreateHTTPRequest()
 Call http.SetHeaderField("Accept", "application/json")
 http.Preferstrings=True
 returnValue = http.Get(url)
 json = Mid(returnValue,2,Len(returnValue))

 'JSON パース
 Dim jsonNav As NotesJSONNavigator
 Dim jsonElement1 As NotesJSONElement
 Dim jsonElement2 As NotesJSONElement
 Dim jsonElement3 As NotesJSONElement

 ' JSON データを JsonNevigator 型にデータにセットする
 Set jsonNav = session.CreateJSONNavigator(json)
 Set jsonElement1 = jsonNav.Getelementbyname("JSONの値1")
 Set jsonElement2 = jsonNav.Getelementbyname("JSONの値2")
 Set jsonElement3 = jsonNav.Getelementbyname("JSONの値3")

 Call uidoc.FieldSetText("address", jsonElement1.Value)
 Call uidoc.FieldSetText("address_1", jsonElement2.Value)
 Call uidoc.FieldSetText("address_2", jsonElement3.Value)
 Call uidoc.Refresh()
 End Sub

以上で指定した値をそれぞれ準備したaddressフィールドにセットすることができました。

ちなみに今回サポートの方とのやり取りは、約2週間。38回にもわたりました。

・・・本当に申し訳ございません。

ただおかげ様で、やりたかった事が無事実現できました。

ので、正月休みに作業します(汗


長くなりましたが、LotusscriptでJSONを扱い場合、今回の経験で判明した内容です。

-----まとめ-----

  • JSONのレスポンスはバイト配列の必要がある
  • レスポンスヘッダの「Content-Type」は「application/json」であること
  • 文字コードはUTF-8であること
  • (現時点で)BOM付きはエラーになるため、外すこと

単にJSONと侮っていたら、こんなことになるんですね。
皆様もお気をつけください!!

0 件のコメント:

コメントを投稿