お知らせ 当ブログは、ブログに割当てられたディスク容量が満杯になったため、2017年1月8日に、続ブログへ移転しました。 【移転先】 続・Emi Clockは、どうなったの? https://yuna-k.blog.ss-blog.jp/ RSSフィード https://yuna-k.blog.ss-blog.jp/index.xml ※ 60秒後に自動的に続ブログへ移動します。 |
ひみつのPDFフォーム(その7) [アーキテクトぽい]
![[exclamation]](https://blog.ss-blog.jp/_images_e/158.gif)
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 += "&"; } 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 Runtime」ウィンドウで、適当なRuntimeの名前を付けて、ホームディレクトリーには、JBoss AS 7.1.1.Final "Brontes"をインストールしたディレクトリ(例えば、"c:\jboss-as-7.1.1.Final")を入力します。
JREは、必ず、最新のJDKのJREを指定してください。(ここ、重要)

では、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』を指定し、他はデフォルトにします。

「Webサービス Java Beanの識別」ウィンドウで、"exportData"メソッドを選択し、「スタイルおよび使用」で『文書/リテラル』をチェックします。
「サーバーを始動」ボタンをクリックすると、ローカルホスト上でJBoss AS 7.1が起動し、Webサービスが使えるようになります。
忘れないうちに、『WS4PDF_JBOSS_EAR』プロジェクトを JBoss AS 7.1サーバに追加しておきます。

Webブラウザから、WebサービスのWSDLを取得するURL(http://localhost:8080/WS4PDF_JBOSS/services/ExportPdfForm?wsdl)を開き、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サービスと通信し、レスポンスを返します。

上記のように、、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]
Facebook コメント

This blog post, right has been protected by copyright law and international law. Without permission screen photo of, hard copy, that you use the other secondary copies without permission is a violation of the rights Please note.
- - - - -
All rights reserved. Copyright (C) Motosoft(Toshi At Kuroneko) 2007-2022.
コメント 0