ひみつのPDFフォーム(その7)

あなたは 人目の訪問者です。
あなたは 人目の訪問者です。

[exclamation]このブログの内容は、アドビ社から公開されている情報に基づき、個人の趣味で記述しています。
PDFフォームに入力したデータを、Web画面表示を更新せずにWebサーバへ送信するには、Webサービスを使えば簡単にできます。
※OS: Windows 7 Ultimete SP1
※Java SE: Java SE SDK 6 Update 32
※Java IDE: Eclipse 3.7.2 Indigo SR2
※ + Pleiades All in One e3.7
※Webサーバ/APサーバ: JBoss AS 7.1.1.Final “Brontes”
※Webブラウザ: IE 9.0.5
※PDF表示: Adobe Reader X 10.1.3
※PDF作成: Adobe Acrobat X Pro 10.1.3
※PDFフォーム作成: Adobe LiveCycle Designer ES2 9.0.0
LiveCycle ES2 Designerの送信ボタンを使うことにより、PDFフォーム上のフィールドの値をWebサーバへ送信できますが、HTTPプロトコルはリクエストに対してレスポンスが返る同期通信プロトコルであるため、HTTP POSTで送信してしてしまうと、PDFフォーム画面が書き換わってしまいます。
サーバ側で、同じPDFフォームを生成して返す方法もありますが、PDFフォームの生成処理時間が、少なからずかかってしまいます。
入力途中のPDFフォームを、画面を書き換えずに一時保存するには、Acrobat SDKのマニュアルに記載されているWebサービスを活用すればよいのです。
Acrobat SDKで同期型のWebサービスを、SOAP over HTTPで用いるには、Net.SOAPオブジェクトを用います。
【コラム】
ただし、Acrobat SDKのNet.SOAP(以前のバージョンでは、SOAP)オブジェクトは、JAX-RPC(Java API for XML Based RPC) 1.1が基本でしたが、現在のバージョンでは、JAX-WS(Java API for XML-Based Web Services) 2.0 → JAX-RPCのサポートになっており、JAXB(Java Architecture for XML Binding)を用いてしてデータ バインディングを管理するようになっており、XMLBeanを用いてのバインディングが deplicatedです。
したがって、Axis 1.xではJAX-RPCをサポートしているのですが、使わないでください。WS-I Basic Profile 2.0および1.2は、JAX-WSにのみ適用されることに注意してください。

では、LiveCycle ES2 Designerを用いて、今まで作ってきたPDFフォームに『一時保存』ボタン(tempSaveBtn)を追加します。
『一時保存ボタン』を追加
Scriptエディタを開き、『一時保存ボタン』ボタンのclickイベント処理の JavaScriptを書きます。
ポイントは、Page1上の全てのfieldオブジェクトを列挙し、そのオブジェクトがボタン(”button”クラス)でなければ、値をSOAPリクエスト文字列に連結していきます。(ボタンは、送信しても邪魔なため外します)
このとき、各フィールド名はPDFフォームのXFA XMLにおいて、UTF-8の1バイトコードなので、そのままでよいでのすが、fieldオブジェクトの値は、UTF-8のマルチバイト文字を含むため、URLEncodeします。
また、URLEncodeの連結文字「&」は、XFA XMLでは「&」でエスケープする必要があります。
SOAPリクエスト文字列ができたら、Net.SOAPオブジェクトのconnectメソッドを使い、WebサービスのWSDLを取得して、動的にプロキシーオブジェクトを生成し、リモートメソッドをコールします。
WSDLのURLは、とりあえずダミーにしておき、Webサービスが完成した後に、置き換えます。(この例では、すでに置き換えてあります)
せっかくなので、うまくいった場合には、SOAPレスポンスの文字列を表示するよう、メッセージボックスを入れておきます。

topmostSubform.Page1.tempSaveBtn::click - (JavaScript, client)
// Page1上の全てのフィールドを列挙してURLエンコード文字列を作成
var objects = xfa.layout.pageContent(0, "field", false);
var cnt, req = "";
for (cnt = 0; cnt < objects.length; cnt++) {
if (objects.item(cnt).ui.nodes.item(0).className != "button") {
if (cnt > 0) { req += "&amp;"; }
req += objects.item(cnt).name + "=" + encodeURIComponent(objects.item(cnt).rawValue);
}
}
// SOAP over HTTPで Webサービスを呼び出す
var proxy = Net.SOAP.connect("http://localhost:8080/WS4PDF_JBOSS/services/ExportPdfForm?wsdl");
var res = proxy.exportData(req);
xfa.host.messageBox("保存結果は " + res + "でした。");

これで、PDFフォームは完成です。できあがったPDFフォームを、ローカルファイルに保存します。
WebサービスクライアントのPDFフォームができたところで、Webサービスを実装します。
PDFフォームのスクリプトのWSDLのURLでお気づきかと思いますが、今回は、APサーバに、いつものTomcat 6.0ではなく、JBoss APサーバの最新版: JBoss AS 7.1.1.Final “Brontes”を使いました。
EclipseからJBoss ASを使えるようにするためには、新規にサーバーを登録します。
下部のサーバータブで右クリックしてコンテキストメニューを表示して、「新規」-「サーバー」を選択して、「新規サーバーの定義」ウィンドウを表示します。
「サーバーのタイプを選択」で、『JBoss AS 7.1』を選択します。
サーバーのタイプは、『JBoss AS 7.1』を選択
「JBoss Runtime」ウィンドウで、適当なRuntimeの名前を付けて、ホームディレクトリーには、JBoss AS 7.1.1.Final “Brontes”をインストールしたディレクトリ(例えば、“c:\jboss-as-7.1.1.Final”)を入力します。
JREは、必ず、最新のJDKのJREを指定してください。(ここ、重要)
JBoss 7.1サーバーの設定 /><br />
アドレス(127.0.0.1)、ポート(8080)などは、デフォルトのままです。<br />
完了すると、<strong><span style=『JBoss 7.1 Runtime Server』という表示が、「ローカル・ホストの Tomcat v6.0サーバー」に加わります。
では、Eclipse上に、JBoss AS 7.1用のWebサービスを作成します。
方法としては、(1)JBossWSを用いる方法、(2) Axisを用いる方法、(3) Axis2を用いる方法の 3通りありますが、Acrobat SDKのAPIは、基本的にJAX-RPCと初期のJAX-WSしかサポートしていないため、『(2) Axisを用いる方法』を用います。(Axisのバージョンは、v1.4)
Eclipseの「ファイル」-「新規」-「動的Webプロジェクト」で、「新規動的Webプロジェクト」を表示し、プロジェクト名を“WS4PDF_JBOSS”にします。
プロジェクト・エクスプローラの”Java Resource/src”で右クリックして「新規」で、“com.motosoft.ws4pdf.web.service”パッケージを作成します。
作成したパッケージで右クリックで「新規」-「クラス」で、“ExportPdfForm.java”を作成します。

package com.motosoft.ws4pdf.web.service;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import javax.jws.WebMethod;
import javax.jws.WebService;
@WebService
public class ExportPdfForm {
@WebMethod
public String exportData(String req) throws UnsupportedEncodingException {
// URLEncodeされたパラメタを分解して表示する
String[] params = req.split("&");
for (int i=0; i < params.length; i++) {
String[] kv = params[i].split("=");
System.out.println("Key=" + kv[0] + ", " + "value=" +  URLDecoder.decode(kv[1],"utf-8"));
}
return "OK";
}
}

"WS4PDF_JBOSS"プロジェクトで右クリックして「新規」-「Webサービス」から、Webサービスウィザードを表示し、「Webサービス・タイプ」で『ボトムアップ Java bean Webサービス』を選択し、「サービス実装」で、今回作成した「ExportPdfForm」クラスを指定します。
「構成」で、「サーバー・ランタイム」を 『JBoss AS 7.1』、「Webサービス・ランタイム」を『Apache Axis』に設定し、サービスEARプロジェクト(デプロイするEAR格納用)に『WS4PDF_JBOSS_EAR』を指定し、他はデフォルトにします。
JBoss AS 7.1上でAxis 1.4の設定を行う
「Webサービス Java Beanの識別」ウィンドウで、"exportData"メソッドを選択し、「スタイルおよび使用」で『文書/リテラル』をチェックします。
「サーバーを始動」ボタンをクリックすると、ローカルホスト上でJBoss AS 7.1が起動し、Webサービスが使えるようになります。
忘れないうちに、『WS4PDF_JBOSS_EAR』プロジェクトを JBoss AS 7.1サーバに追加しておきます。
JBoss AS 7.1サーバにWebサービスがデプロイできている
Webブラウザから、WebサービスのWSDLを取得するURL(http://localhost:8080/WS4PDF_JBOSS/services/ExportPdfForm?wsdl)を開き、WSDLが表示されることを確認します。
IE9上で、WSDLが表示されることを確認
ここまでの作業で、Webサービスを呼び出すAcrobat ScriptによるクライアントとなるPDFフォームと、JBoss AS 7.1.1でホスティングされたWebサービスができあがりました。
しかし、Acrobat ScriptによるクライアントとなるPDFフォームを、Adobe Reader Xで表示させても、セキュリティ上の制限によりWebサービスを呼び出すことができません。
これは、うっかり、悪意があるWebサービスへ接続するAcrobat Scriptを含むPDFフォームを開くことによるセキュリティリスクから保護するためです。
Adobe Reader Xから、Webサービスを呼び出すには、アドビ社が販売するサーバ製品「Adobe LiveCycle Reader Extensions ES3」を購入し、『Webサービスの実行を許可』する隠し権限を付与する必要があります。
しかし、Acrobat X Proを保有していれば、「Adobe LiveCycle Reader Extensions ES3」付与できる隠し権限をオールマイティで許可できてしまうため、これを利用して、PDFフォームからWebサービスを呼び出してみましょう。
LiveCycle ES2 DesignerでPDFフォームに追加した、『一時保存』ボタンをクリックすると、PDFフォームのAcrobat ScriptがSOAP over HTTPで、JBoss AS 7.1.1上のAxisサーブレットを経由し、JAX-WSでWebサービスと通信し、レスポンスを返します。
PDFフォームからWebサービスを呼び出し
上記のように、、Acrobat X Proを保有していれば、何でもアリなので、PDFフォームの開発にも有益です。
JBoss AS 7.1.1のコンソールログは、以下のように、PDFフォームに入力された値がアップロードされます。

20:24:34,534 INFO  [org.apache.coyote.http11.Http11Protocol] (MSC service thread 1-5) Coyote HTTP/1.1を http-localhost-127.0.0.1-8080 で起動します
20:24:34,566 INFO  [org.jboss.as.remoting] (MSC service thread 1-5) JBAS017100: Listening on localhost/127.0.0.1:4447
20:24:34,566 INFO  [org.jboss.as.remoting] (MSC service thread 1-6) JBAS017100: Listening on /127.0.0.1:9999
20:24:34,566 INFO  [org.jboss.as.server.deployment.scanner] (MSC service thread 1-4) JBAS015012: Started FileSystemDeploymentService for directory C:\jboss-as-7.1.1.Final\standalone\deployments
20:24:34,581 INFO  [org.jboss.as.server.deployment.scanner] (DeploymentScanner-threads - 1) JBAS015003: Found WS4PDF_JBOSSEAR.ear in deployment directory. To trigger deployment create a file called WS4PDF_JBOSSEAR.ear.dodeploy
20:24:34,628 INFO  [org.jboss.as.connector.subsystems.datasources] (MSC service thread 1-6) JBAS010400: Bound data source [java:jboss/datasources/ExampleDS]
20:24:34,659 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-5) JBAS015876: Starting deployment of "WS4PDF_JBOSSEAR.ear"
20:24:34,675 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-3) JBAS015876: Starting deployment of "WS4PDF_JBOSS.war"
20:24:35,252 INFO  [org.jboss.wsf.stack.cxf.metadata.MetadataBuilder] (MSC service thread 1-4) Add Service
id=com.motosoft.ws4pdf.web.service.ExportPdfForm
address=http://localhost:8080/WS4PDF_JBOSS/ExportPdfForm
implementor=com.motosoft.ws4pdf.web.service.ExportPdfForm
invoker=org.jboss.wsf.stack.cxf.JBossWSInvoker
serviceName={http://service.web.ws4pdf.motosoft.com/}ExportPdfFormService
portName={http://service.web.ws4pdf.motosoft.com/}ExportPdfFormPort
wsdlLocation=null
mtomEnabled=false
20:24:35,440 情報    [org.apache.cxf.service.factory.ReflectionServiceFactoryBean] (MSC service thread 1-4) Creating Service {http://service.web.ws4pdf.motosoft.com/}ExportPdfFormService from class com.motosoft.ws4pdf.web.service.ExportPdfForm
20:24:35,878 情報    [org.apache.cxf.endpoint.ServerImpl] (MSC service thread 1-4) Setting the server's publish address to be http://localhost:8080/WS4PDF_JBOSS/ExportPdfForm
20:24:35,987 INFO  [org.jboss.wsf.stack.cxf.deployment.WSDLFilePublisher] (MSC service thread 1-4) WSDL published to: file:/C:/jboss-as-7.1.1.Final/standalone/data/wsdl/WS4PDF_JBOSSEAR.ear/WS4PDF_JBOSS.war/ExportPdfFormService.wsdl
20:24:35,987 INFO  [org.jboss.as.webservices] (MSC service thread 1-3) JBAS015539: Starting service jboss.ws.port-component-link
20:24:36,003 INFO  [org.jboss.as.webservices] (MSC service thread 1-7) JBAS015539: Starting service jboss.ws.endpoint."WS4PDF_JBOSSEAR.ear"."WS4PDF_JBOSS.war"."com.motosoft.ws4pdf.web.service.ExportPdfForm"
20:24:36,003 INFO  [org.jboss.ws.common.management.DefaultEndpointRegistry] (MSC service thread 1-7) register: jboss.ws:context=WS4PDF_JBOSS,endpoint=com.motosoft.ws4pdf.web.service.ExportPdfForm
20:24:36,268 INFO  [org.jboss.web] (MSC service thread 1-7) JBAS018210: Registering web context: /WS4PDF_JBOSS
20:24:36,268 INFO  [org.jboss.as] (MSC service thread 1-5) JBAS015951: Admin console listening on http://127.0.0.1:9990
20:24:36,268 INFO  [org.jboss.as] (MSC service thread 1-5) JBAS015874: JBoss AS 7.1.1.Final "Brontes" started in 3388ms - Started 193 of 272 services (78 services are passive or on-demand)
20:24:36,519 INFO  [org.jboss.as.server] (DeploymentScanner-threads - 2) JBAS018559: Deployed "WS4PDF_JBOSSEAR.ear"
20:24:41,339 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=CLIENT_SEX, value=女
20:24:41,339 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=CLIENT_BIRTHDAY, value=1992/11/22
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=DOCTOR_AUTH_DATE, value=2012-05-10
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=PAYMENT_ORDER, value=1
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=CARTE_NO, value=CT10842780
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=CLIENT_NAME, value=指原莉乃
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=DOCTOR_NAME, value=秋元康
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=DIVISION_NAME, value=1
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=EXAMINATION_DAY_OF_WEEK, value=3
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=EXAMINATION_ZONE, value=1
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=RESERVATION_ZONE, value=1
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=EXAMINATION_HOUR, value=10
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=RESERVATION_HOUR, value=9
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=RESERVATION_MINUTES, value=0
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=EXAMINATION_MONTH, value=5
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=EXAMINATION_DAY, value=23
20:24:41,355 INFO  [stdout] (http-localhost-127.0.0.1-8080-1) Key=EXAMINATION_MINUTES, value=0

次回は、また、Acrobat X Proだけを用いて、オールマイティーな裏技で、PDFフォームに初期データを埋め込んでブラウザへ表示する方法を書く予定です。
[シリーズブログ]
ひみつのPDFフォーム
[1] [2] [3] [4] [5] [6] [7]

タイトルとURLをコピーしました