PerlとJavaで異言語Webサービス連携
Download
Report
Transcript PerlとJavaで異言語Webサービス連携
PerlとJavaで異言語Webサービス連携
- SOAP/WSDLの光と影 Shibuya Perl Mongers テクニカルトーク #5
株式会社ドリーム・アーツ 広島ラボ
竹迫 良範
<[email protected]>
2004/12/16
1
Perl と Java で異言語 Web サービス連携
はじめに
1. Perl で SOAP::Lite を使う
2.
Perl と Java の業務アプリケーション
3.
各種 Adapter の紹介
Apache Axis で Java と連携
2004/12/16
株式会社ドリーム・アーツでの事例紹介
DA::API フレームワーク
4.
SOAP, 日本語文字コード
WSDL, WSDL2Java, Type Mapping 問題
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
2
1. Perl で SOAP::Lite を使う
Shibuya Perl Mongers テクニカルトーク #5
“Lite”な割には「軽く」ない…
2004/12/16
3
SOAP とは?
SOAP (Simple Object Access Protocol → SOAP1.2より固有名詞)
XMLを利用してRPCやメッセージングの機能を実現するための仕様
軽量で特定のプラットフォームに依存しないのが特徴
SOAPによるRPCは、Webサービスの中核技術
SOAPは、データ構造のみが定義されており、
転送手段としては既存の通信プロトコルを使用(主にHTTP)
(例)
SOAP
メッセージ
(XML)
リクエスト
SOAP over HTTP
network
クライアント
Windows Java
(Apache Axis)
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
レスポンス
SOAP
メッセージ
(XML)
サーバ
Linux mod_perl
(SOAP::Lite)
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
4
tcpmon で SOAPメッセージをキャプチャ
TCPモニタを起動する
java org.apache.axis.utils.tcpmon
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
5
Perlクライアントの例 (SOAP::Lite)
#!/usr/bin/perl
use SOAP::Lite();
my $soap = SOAP::Lite
->uri('urn:DA/API/Tests')
->proxy('http://localhost:8001/service/soap/')
->new;
local $@;
my $som = eval {
$soap->add({
a => 123,
b => 456,
c => 789,
});
};
if ($@) { die $@; }
if ($som->fault) { die $som->faultstring; }
my $result = $som->result;
print "result='$result'\n";
exit(0);
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
6
SOAP::Lite で日本語を扱うと・・・
日本語を扱うと・・・
なぜか文字化けしてしまうことが
文字化けの原因
Base64 でエンコードされている
Devel::Peek::Dump で確認
2004/12/16
SOAP::Lite の typelookup が原因
XML Parser から取り込んだ文字列に
UTF8フラグが立っている!
ISO-8859-1 → UTF-8 へ自動変換(文字化け)
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
7
SOAP::Lite の typelookup
Perl : 型のない言語
_typelookup => {
base64 => [10, sub {$_[0] =~ /[^\x09\x0a\x0d\x20-\x7f]/}, 'as_base64'],
'int' => [20, sub {$_[0] =~ /^[+-]?(\d+)$/ && $1 <= 2147483648;}, 'as_int'],
float => [30, sub {$_[0] =~ /^(-?(?:\d+(?:\.\d*)?|\.\d+|NaN|INF)|
([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)$/}, 'as_float'],
string => [40, sub {1}, 'as_string'],
'long' => [25, sub {$_[0] =~ /^[+-]?(\d+)$/ && $1 <= 9223372036854775807;}, 'as_long'],
},
【マルチバイトでもbase64エンコードせず強制的に文字列として返す】
$self->{_typelookup}->{string} = [ 1, sub {1}, 'as_string'];
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
8
通常の回避策(UTF8フラグの除去)
文字列 $_ 中のUTF8フラグを除去する
[1] unpack して pack する
$_ = pack ( 'C*', unpack ( 'C*', $_ ) );
もっと
効率的
[2] pack 'C0' を使う
$_ = pack 'C0A*', $_;
from MT/XMLRPCServer.pm at www.movabletype.org.
## The following subroutine strips the UTF8 flag from a string, thus
## forcing it into a series of bytes. "pack 'C0'" is a magic way of
## forcing the following string to be packed as bytes, not as UTF8.
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
9
強硬な回避策(UTF8フラグの除去)
XML-Parser にパッチを当てる(荒技)
--- XML-Parser-2.34-orig/Expat/Expat.xs Mon Jul 28 23:41:10 2003
+++ XML-Parser-2.34/Expat/Expat.xs
Fri Aug 27 08:36:39 2004
@@ -17,6 +17,8 @@
#undef convert
+#undef SvUTF8_on
+
#include "patchlevel.h"
#include "encoding.h"
# patch –p1 < XML-Parser-2.34-no_utf8.patch
→ ややこしいことは考えなくて済む!
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
10
2. Perl と Java の業務アプリケーション
Shibuya Perl Mongers テクニカルトーク #5
株式会社ドリーム・アーツでの事例紹介
http://www.dreamarts.co.jp/
2004/12/16
11
株式会社ドリーム・アーツの主力製品
【インスイート エンタープライズ】
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
12
「INSUITE Enterprise」と「ひびき」の位置付け
エンドユーザ
外部
内部
EIP : 情 報 ・ 知識ポータル(モバイル対応)
(シングル・サイン・オン、 パーソナライズ、 グループ・部門・役職単位のポータル設定、アクティブ・ノーティス(通達機能)・・・etc.)
在庫管理
ニュース
クリッピング
ポートレット
マーケット
プレース
人事総務
eラーニング
パートナー
サイト
グループウエア
スケジューラ
施設予約
掲示板
ファイル共有Box
ToDoリスト
ホームページ作成
検索機能
アドレス帳
ワークフロー
高速全文検索エンジン(アクセス・コントロール対応)
ユーザ・グループ管理
セキュリティ
【ひびき】は、INSUITE®のポータル機能はじめ全文検索、ユーザ管理、セキュリティ機能を有効利用
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
13
「INSUITE Enterprise」と「ひびき」の比較
INSUITE Enterpirse
カテゴリ
EIP, グループウェア
開発言語
Perl, C
開発環境
vi
開発者
oldtype
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
ひびき
業務アプリ
異言語連携
(SOAP)
PROJECT
SALES
Java
Eclipse
異文化交流
(相互理解)
newtype
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
14
4. DA::API フレームワーク
Shibuya Perl Mongers テクニカルトーク #5
各種 Adapter の紹介
2004/12/16
15
DA::API フレームワークの構成図
Web I/F
layer
POST-XML
Adapter
sudo
require user & group
Shibuya Perl Mongers テクニカルトーク #5
SOAP
Adapter
Authz
layer
DA::Adapter::BasicAuth
スケジュール
登録・更新
削除・検索
ユーザ・グループ
情報の参照
:
Authen
layer
DA::Adapter::CreateSession
Command
Adapter
DA::API
modules
Web I/F の実装
2004/12/16
Adaptation
layer
DA::Adapter
DA::Adapter::API
HTML::Template
cgi-bin
Web
Browser
Implementation
layer
cmd
tools
SOAP
Client
HTTP
Client
実装(メンテナンス)する部分はここだけ
各Adapterがインタフェースを自動生成
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
16
DA::API::Tests モジュールの書き方
インタフェースの実装(例)
# ▼ 足し算
#-------------------------------------------------------------------------sub add {
my $get = new DA::Adapter::API(@_);
#
my $session = $get->session();
my $a
= $get->require("a" => t_("引数 a (必須項目)"),
my $b
= $get->require("b" => t_("引数 b (必須項目)"),
my $c
= $get->options("c" => t_("引数 c (省略可能)"),
my $d
= $get->options("d" => t_("引数 d (省略可能)"),
$get->summary(t_("足し算(a+b+c+d)の結果を返す"));
$get->end();
入力パラメータの定義
(決まった書き方)
"int");
"int");
"int");
"int");
if (!defined $c) { $c = 0; };
if (!defined $d) { $d = 0; };
my $result = $a + $b + $c + $d;
return $result;
}
HTTP/POST-XML Adapter が
インタフェースの入力仕様を元に
サンプルHTMLフォームを自動生成
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
17
DA::Adapter 機能説明 (1)
コアモジュール
DA::Adapter::API
DA::Adapter::Command
HTTP/POST-XML の機能を提供するモジュール
HTMLフォームの自動生成、APIの自動リストアップ機能を持つ
DA::Adapter::SOAP
2004/12/16
api コマンドの機能を提供するモジュール
自動 sudo 機能を持つ(wwwユーザで実行)
DA::Adapter::CGI
DA::APIを利用するためのコアモジュール
HTTP/SOAP の機能を提供する wrapper モジュール
Apache::SOAP の代わりに呼び出す
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
18
DA::Adapter 機能説明 (2)
内部モジュール(カスタマイズ可能な領域)
DA::Adapter::BasicAuth
DA::Adapter::CreateSession
フック関数の提供(pre, post, commit, rollback)→暫定
DA::Adapter::Sudo
2004/12/16
SOAP::Lite の改変版(auto encoding機能などを追加)
DA::Adapter::Hook
API単位で同期実行(排他実行)機能を提供する
1つのAPIが同時に(並列に)複数実行されないことを保証
DA::Adapter::MySOAP
認証されたユーザでセッションを生成する
DA::Adapter::Synchronized
Cookie を用いない HTTP Basic 認証を提供
実行ユーザ権限のチェックや、環境変数、umask の設定など
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
19
Webサービスの設定方法
.htaccess (httpd.conf) で設置可能に
<Location /service/soap/>
order deny,allow
IPアドレスの制限
deny from all
allow from 127.0.0.1 192.168.
AuthName HTTP_Basic_Authentication
ユーザ認証の設定
AuthType Basic
PerlModule
DA::Adapter::BasicAuth
PerlAuthenHandler DA::Adapter::BasicAuth
require valid-user
SetHandler perl-script
PerlModule DA::Adapter::SOAP
SOAP Service の設定
PerlHandler DA::Adapter::SOAP
PerlSetVar dispatch_to "DA::API::Tests, DA::API::Sample"
PerlSetVar options "compress_threshold => 10000"
Options +ExecCGI
PerlSetVar SOAP_default_ie UTF-8
PerlSetVar SOAP_default_oe UTF-8
入出力エンコーディング設定
PerlSetVar SOAP_typelookup string
</Location>
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
20
4. Apache Axis で Java と連携
Shibuya Perl Mongers テクニカルトーク #5
WSDLファイルとJavaスタブコード
2004/12/16
21
Apache Axis
インストールするソフトウェア群
(1) J2SDK 1.4.2_05
... j2sdk-1_4_2_05-windows-i586-p.exe
(2) Jakarta Tomcat 4.1.31
... jakarta-tomcat-4.1.31.exe
(3) Apache Axis 1.2RC1
... axis-1_2RC1-bin.zip
(4) JAF 1.0.2
... jaf-1_0_2-upd.zip
(5) javamail 1.3.1
... javamail-1_3_1.zip
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
22
Javaクライアントの例 (Apache Axis)
import
import
import
import
import
org.apache.soap.Constants;
org.apache.soap.rpc.*;
org.apache.soap.transport.http.SOAPHTTPConnection;
java.net.URL;
java.util.Vector;
// javac SOAPClientTests.java
// java SOAPClientTests
public class SOAPClientTests {
public static void main(String[] args) {
try {
// URLの指定
URL url = new URL("http://localhost:8001/service/soap/");
// Callオブジェクトを生成
Call call = new Call();
// ユーザ認証の設定
org.apache.soap.transport.http.SOAPHTTPConnection soapTransport
= new org.apache.soap.transport.http.SOAPHTTPConnection();
soapTransport.setUserName(“username");
soapTransport.setPassword("password");
call.setSOAPTransport(soapTransport);
// ターゲットとなるURIを指定
call.setTargetObjectURI("urn:DA/API/Tests");
// ターゲットとなるメソッドを指定
call.setMethodName("add");
// 直列化のスタイルを指定
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
// パラメータの設定
Vector params = new Vector();
params.addElement(new Parameter("a", String.class, "123", null));
params.addElement(new Parameter("b", String.class, "456", null));
params.addElement(new Parameter("c", String.class, "789", null));
call.setParams(params);
// 呼び出しを実行
String SOAPActionURI = "";
Response resp = call.invoke(url, SOAPActionURI);
// 戻り値を取得
Parameter ret = resp.getReturnValue();
System.out.println(ret.getValue());
} catch (Exception e) {
e.printStackTrace();
}
}
2004/12/16
}
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
23
WSDL2Java
WSDLファイルからJavaのスタブコードを自動作成
java org.apache.axis.wsdl.WSDL2Java ISAPI.wsdl
Javaクライアント
./jp/co/dreamarts/insuite/DA/API/WSDL/FacilityInfo.java
./jp/co/dreamarts/insuite/DA/API/WSDL/FaScheduleInfo.java
./jp/co/dreamarts/insuite/DA/API/WSDL/GroupInfo.java
./jp/co/dreamarts/insuite/DA/API/WSDL/ISAPI.java
./jp/co/dreamarts/insuite/DA/API/WSDL/ISAPIBindingStub.java
./jp/co/dreamarts/insuite/DA/API/WSDL/ISAPIService.java
./jp/co/dreamarts/insuite/DA/API/WSDL/ISAPIServiceLocator.java
./jp/co/dreamarts/insuite/DA/API/WSDL/ScheduleInfo.java
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
24
WSDL とは?
WSDL (Web Services Description Language)
Webサービスを記述するための外部仕様(入出力仕様書)
サービスのインターフェースや、提供場所、実行方法などの情報を記述
(例)
SOAP
メッセージ
(XML)
WSDL
ファイル
(XML)
リクエスト
入出力仕様書
network
クライアント
Windows Java
(Apache Axis)
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
レスポンス
SOAP
メッセージ
(XML)
サーバ
Linux mod_perl
(SOAP::Lite)
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
25
WSDLファイルの例
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
26
Apache Axis (Java) の Type Mapping 問題
2004/12/16
WSDL type
Java Type
xsd:string
java.lang.String
xsd:int
int
java.lang.Integer
xsd:long
long
java.lang.Long
xsd:short
short
java.lang.Short
xsd:float
float
java.lang.Float
xsd:double
double
java.lang.Double
xsd:boolean
boolean
java.lang.Boolean
xsd:byte
byte
java.lang.Byte
xsd:integer
java.math.BigInteger
xsd:decimal
java.math.BigDecimal
Shibuya Perl Mongers テクニカルトーク #5
Java Type (nillable)
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
27
何が問題か?
xsd:integer
無条件で java.math.BigInteger にマッピング
多倍長整数なのでパフォーマンス悪化
xsd:int
nillable=“false” では int 宣言となる
nillable=“true” では java.lang.Integer 型を使用する
(nullを許可するため)
int配列で nillable=false を指定する方法が不明
int配列の要素にnullを許可したい場合…
xsd:int が使えないので
xsd:integer を使うしかない?
2004/12/16
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
28
SOAP/WSDLのまとめ
2004/12/16
疎結合な技術でどんなプラットフォーム同士でも連携できる
(Perl, Java, Ruby, Python, C++, .NET C#…)
言語「非依存」と言いつつ、実際は言語「依存」である
(Type Mapping, プロシジャコール…)
規格は「厳格」なようで、実は「曖昧」である
(規格の範囲内であれば、どんな実装でもOK)
WSDLを自動生成するツールの精度はまだ良くない
(手作業でWSDLファイルを作成するのが安全)
構造化データ:ツールによってうまく扱えないものがある
(SOAP::Lite の WSDL サポートはまだ不完全)
WSDLでは、例外条件や入力文字列幅などを定義できない
<!-- コメントの中に書いて人間がわかるようにする -->
うまく動くようになると爽快!(バッドノウハウの塊かも?)
Shibuya Perl Mongers テクニカルトーク #5
Copyright © 2004 DreamArts Corporation. All Rights Reserved.
29