biz-Streamマニュアル Webサービスサーバ ガイド 第11章 サンプルプログラム(Java) 11.10 PDFを生成しバッチ印刷するサンプル(JAX-WS)

11.10 PDFを生成しバッチ印刷するサンプル(JAX-WS)

概要

バッチ印刷モジュールを利用するサンプルプログラムです。

このサンプルでは、印刷指示を行った後、「ジョブID」「印刷状態」を取得します。その結果「バッチ印刷エラーコード」を検知した場合は印刷の再実行を行います。 異常終了や例外を検知した場合はそこでプログラムを終了します。


環境準備

事前に『2.7 クライアントアプリケーションの環境構築』を確認してください。


サンプル構成

項目 ファイルパス
ページレイアウトサンプル <bswss-client_home>/sample/xml/Sample1.xml サンプル1
ソースサンプル <bswss-client_home>/sample/java/jax-ws/WSS_JAXWS_Sample10.java サンプル1

ソースサンプル

import java.math.BigInteger;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URL;
import java.util.List;
import java.util.Map;

import org.apache.ws.axis2.Bizstream;
import org.apache.ws.axis2.BizstreamPortType;

import com.brainsellers.schemas.webservices.bizstream._2006_10.BatchPrint;
import com.brainsellers.schemas.webservices.bizstream._2006_10.DoPrint;
import com.brainsellers.schemas.webservices.bizstream._2006_10.Error;
import com.brainsellers.schemas.webservices.bizstream._2006_10.GenerateOutputDataRequest;
import com.brainsellers.schemas.webservices.bizstream._2006_10.GenerateOutputDataResponse;
import com.brainsellers.schemas.webservices.bizstream._2006_10.LayoutData;
import com.brainsellers.schemas.webservices.bizstream._2006_10.LayoutDefinition;
import com.brainsellers.schemas.webservices.bizstream._2006_10.Output;
import com.brainsellers.schemas.webservices.bizstream._2006_10.PrintResult;
import com.brainsellers.schemas.webservices.bizstream._2006_10.PrintStatus;
import com.brainsellers.schemas.webservices.bizstream._2006_10.PrintStatuses;
import com.brainsellers.schemas.webservices.bizstream._2006_10.Printer;
import com.brainsellers.schemas.webservices.bizstream._2006_10.Query;
import com.brainsellers.schemas.webservices.bizstream._2006_10.QueryResult;
import com.brainsellers.schemas.webservices.bizstream._2006_10.Status;

import jakarta.xml.ws.BindingProvider;
import jakarta.xml.ws.WebServiceFeature;
import jakarta.xml.ws.soap.MTOMFeature;



public class WSS_JAXWS_Sample10 {

	// Webサービスサーバのホスト名
	private static final String WSS_HOST_NAME = "wsssrv";

	// バッチ印刷サーバのホスト名
	private static final String PRINT_HOST_NAME = "prntsrv";

	// バッチ印刷サーバのポート番号
	private static final String PORT_NO = "3000";

	// プリンタ名
	private static final String PRINTER_NAME = "Bullzip PDF Printer";

	// 印刷状態の取得間隔 (単位:ミリ秒)
	// 【注意】1000ミリ秒未満はバッチ印刷サーバに負荷が掛かるため短くしすぎないこと
	private static final int INTERVAL = 1 * 1000;

	// Webサービスサーバ上のサンプルディレクトリの場所
	private static final String WSS_BIZSTREAM_SAMPLE_DIR = "/bs/sample";

	// Webサービスのエンドポイントプリフィックス
	private static final String WSS_SERVICE_LOCATION = "http://" + WSS_HOST_NAME + ":8080/axis2/services";

	// BASIC認証のユーザ名
	private static final String USER_NAME = "bizuser1";

	// BASIC認証のパスワード
	private static final String PASSWORD = "bizuser1";

	// 監査ロギング用のユーザ定義
	private static final String USER_DEF = "AAA";

	// Webサービスサーバ上の入力レイアウト定義ファイルパス
	private static final String LAYOUT_FILE = WSS_BIZSTREAM_SAMPLE_DIR + "/xml/Sample1.xml";

	// バッチ印刷サービスのエンドポイントプリフィックス
	private static final String PRINT_SERVICE_LOCATION = "http://" + PRINT_HOST_NAME + ":" + PORT_NO + "/";


	// 連続印刷数
	private static final int LOOP = 1;


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new WSS_JAXWS_Sample10();
	}

	/**
	 * メイン
	 */
	public WSS_JAXWS_Sample10() {
		try {
			// 連続印刷をシミュレーションする
			for (int i = 0; i < LOOP; i++) {
				doPrintAndGetStatus();
			}

			System.exit(0);
		} catch (Exception ex) {
			ex.printStackTrace();

			System.exit(1);
		}
	}

	/**
	 * 印刷要求を1回送信し、印刷状態を監視する
	 *
	 * @throws Exception
	 */
	private void doPrintAndGetStatus() throws Exception {
		// 印刷のループ
		// 通常は1回で抜けるが、PDF生成からやり直した場合は複数回ループする
		PRINT_LOOP : while (true) {
			// 認証の設定
			setAuth();

			GenerateOutputDataResponse dataResponse = null;
			try {
				// PDF生成とバッチ印刷サーバへの送信を行う
				dataResponse = doPrint();
			} catch (Exception ex) {
				// 以下の場合に該当
				// ・PDF生成でエラーが発生した場合

				// エラー処理をして異常終了とする
				throw new Exception("【エラー1】PDF生成でエラーが発生しました。プログラムを終了します。", ex);
			}

			// 印刷状態取得のためJobIDを取得
			PrintResult printResult = dataResponse.getPrintResult();
			String jobId = printResult.getJobId();

			System.out.println("==============================");
			System.out.println("jobId=" + jobId);
			System.out.println("==============================");

			if (jobId == null || jobId.equals("")) {
				// 以下の場合に該当
				// ・バッチ印刷が起動していない場合
				// ・接続先が誤っている場合
				// ・バッチ印刷が印刷要求を受け付けられない場合
				System.err.println("【エラー2】バッチ印刷の印刷要求結果を取得できませんでした。再度PDF生成からやり直します。");

				// 待ち時間の後、再度印刷要求を行う
				sleep();
				continue PRINT_LOOP;
			}

			// 待ち時間の後、印刷状態取得を行う
			sleep();

			// 印刷状態取得ループ
			// ステータスコードが0006になるまでINTERVAL間隔で印刷状態取得を繰り返す
			STATUS_LOOP : while (true) {
				// 印刷状態を取得する
				PrintStatus printStatus = getBatchPrintStatus(jobId);

				if (printStatus == null) {
					// 以下の場合に該当
					// ・バッチ印刷が印刷状態要求を受け付けられなかった場合

					// 【注意】
					// このパターンは印刷状態取得に失敗するが、印刷成功・失敗は不定となる
					// PDF生成からやり直した場合、二重に印刷されてしまう可能性があるため注意
					// 厳密に印刷結果を管理するには異常終了としてプログラムを止めた後に出力結果を確認、未印刷分からやり直すこと

					// 二重に印刷される可能性を許容する場合はこちらのロジックを使用する
					System.err.println("【エラー3】バッチ印刷の印刷状態を取得できませんでした。再度PDF生成からやり直します。");
					// 待ち時間の後、再度印刷要求を行う
					sleep();
					continue PRINT_LOOP;

					// 厳密に出力を管理するにはこちらのロジックを使用する
					// エラー処理をして異常終了とする
					// throw new Exception("【エラー3】バッチ印刷の印刷状態を取得できませんでした。プログラムを終了します。");
				}

				// 情報取得日時
				String dateTime = printStatus.getDateTime();

				// エラー情報
				Error error = printStatus.getError();
				String errorCause = error.getCause();
				BigInteger errorCode = error.getCode();
				String errorDetails = error.getDetails();

				// ステータス
				Status stat = printStatus.getStatus();
				String status = stat.getValue();
				String statusCode = stat.getCode();

				// プリンタ情報
				Printer printer = printStatus.getPrinter();
				String printerName = printer.getName();
				String jobName = printer.getJobName();

				System.out.println("------------------------------");
				System.out.println("dateTime=" + dateTime);
				System.out.println("errorCause=" + errorCause);
				System.out.println("errorCode=" + errorCode);
				System.out.println("errorDetails=" + errorDetails);
				System.out.println("jobId=" + jobId);
				System.out.println("jobName=" + jobName);
				System.out.println("printerName=" + printerName);
				System.out.println("status=" + status);
				System.out.println("statusCode=" + statusCode);
				System.out.println("------------------------------");


				if (errorCode != null && (errorCode.equals(new BigInteger("114")) || errorCode.equals(new BigInteger("405")) || errorCode.equals(new BigInteger("506")))) {
					// 以下の場合に該当
					// 114=バッチ印刷のキュー上限に達した場合
					// 405=スプールタイムアウトが発生した場合
					// 506=指定したJobIDに対応する印刷状態が存在しない場合(バッチ印刷が再起動された場合など)
					System.err.println("【エラー4】バッチ印刷でエラーが発生しました。再度PDF生成からやり直します。エラーコード: " + errorCode + ", エラーメッセージ: " + errorDetails);

					// 待ち時間の後、再度印刷要求を行う
					sleep();
					continue PRINT_LOOP;
				}

				if (statusCode == null || statusCode.equals("")) {
					// 以下の場合に該当
					// ・バッチ印刷が印刷要求または印刷状態要求を受け付けられない場合
					// ・印刷状態最大保持数、印刷状態最大保持時間の値が小さく、印刷状態がクリアされてしまった場合

					// 【注意】
					// このパターンは印刷状態取得に失敗するが、印刷成功・失敗は不定となる
					// PDF生成からやり直した場合、二重に印刷されてしまう可能性があるため注意
					// 厳密に印刷結果を管理するには異常終了としてプログラムを止めた後に出力結果を確認、未印刷分からやり直すこと

					// 二重に印刷される可能性を許容する場合はこちらのロジックを使用する
					System.err.println("【エラー5】バッチ印刷の印刷状態を取得できませんでした。再度PDF生成からやり直します。");
					// 待ち時間の後、再度印刷要求を行う
					sleep();
					continue PRINT_LOOP;

					// 厳密に出力を管理するにはこちらのロジックを使用する
					// エラー処理をして異常終了とする
					// throw new Exception("【エラー5】バッチ印刷の印刷状態を取得できませんでした。プログラムを終了します。");
				} else if (statusCode.equals("0002") || statusCode.equals("0004")) {
					// 0002 (印刷指示受付)
					// 0004 (印刷中)

					// 以下の場合に該当
					// ・バッチ印刷のキューに存在するが、キュー取り出し待ち状態の場合
					// ・キューから取り出されてAdobeモジュールによるPDFロードが行われ、プリントスプーラへ入るまでの間の場合

					// 待ち時間の後、再度印刷状態取得を実施
					sleep();
					continue STATUS_LOOP;
				} else if (statusCode.equals("0006")) {
					// 0006 (印刷要求送信完了)

					// 以下の場合に該当
					// ・正常にプリントスプーラへ送信完了した場合
					System.out.println("【正常】プリントスプーラへの送信が完了しました。JobID: " + jobId);

					break PRINT_LOOP;
				} else if (statusCode.equals("0008")) {
					// 0008 (印刷異常終了)

					if (errorCode != null && errorCode.equals(new BigInteger("000"))) {
						// 以下の場合に該当
						// ・印刷状態は0008で確定しているがエラーコードが確定するまでの間に印刷状態取得が行われた場合

						// 待ち時間の後、再度印刷状態取得を行う
						sleep();
						continue STATUS_LOOP;
					} else if (errorCode != null && errorCode.equals(new BigInteger("405"))) {
						// 以下の場合に該当
						// 405=スプールタイムアウトが発生した場合
						System.err.println("【エラー6】バッチ印刷でエラーが発生しました。再度PDF生成からやり直します。エラーコード: " + errorCode + ", エラーメッセージ: " + errorDetails);

						// 待ち時間の後、再度印刷要求を行う
						sleep();
						continue PRINT_LOOP;
					} else {
						// 以下の場合に該当
						// ・AdobeモジュールによるPDFロード、またはプリントスプーラへの投入時にエラーが発生した場合

						// エラー処理をして異常終了とする
						throw new Exception("【エラー7】印刷異常終了となりました。プログラムを終了します。");
					}
				}
			}
		}
	}

	/**
	 * 認証の設定
	 */
	private void setAuth(){
		Authenticator.setDefault(new Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(USER_NAME, PASSWORD.toCharArray());
			}
		});
	}

	/**
	 * PDFを生成してバッチ印刷を実行する
	 *
	 * @return GenerateOutputDataResponse
	 */
	private GenerateOutputDataResponse doPrint() throws Exception {
		// クライアントを生成
		Bizstream service = new Bizstream(new URL(WSS_SERVICE_LOCATION + "/bizstream?wsdl"));

		// MTOMを有効化
		WebServiceFeature feature = new MTOMFeature(true);
		BizstreamPortType type = service.getBizstreamSOAP11Port(feature);
		BindingProvider bp = (BindingProvider) type;
		Map<String, Object> reqContext = bp.getRequestContext();
		reqContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
				WSS_SERVICE_LOCATION + "/bizstream?UserDef=" + USER_DEF);

		// リクエストメッセージの作成
		GenerateOutputDataRequest request = new GenerateOutputDataRequest();

		// バッチ印刷の出力を設定
		Output output = new Output();
		BatchPrint batchPrint = new BatchPrint();
		DoPrint doPrint = new DoPrint();
		Printer printer = new Printer();
		doPrint.setUrl(PRINT_SERVICE_LOCATION);
		batchPrint.setDoPrint(doPrint);
		// プリンタ名
		printer.setName(PRINTER_NAME);
		// 印刷部数
		printer.setNumberOfCopy("1");
		// 出力トレイ
		printer.setSelectedTray("AUTO");
		// 印刷識別子(2バイト文字を使用する場合はUTF-8)
		printer.setJobName("WSS_JAXWS_Sample10");
		// 開始ページ番号
		printer.setFromPage("1");
		// 終了ページ番号
		printer.setToPage("-1");
		// 用紙に合わせて印刷
		printer.setDoFit("true");
		// 暗号化パスワード(バッチ印刷インストーラで指定したもの)
//		printer.setPassword("password");
		// エンコード済み暗号化パスワード
//		printer.setPasswordWithEncoded("cGFzc3dvcmQ=");

		batchPrint.setPrinter(printer);
		output.setBatchPrint(batchPrint);
		request.setOutput(output);

		// レイアウト定義を設定
		LayoutData layoutData = new LayoutData();
		LayoutDefinition layout = new LayoutDefinition();
		layout.setUri(LAYOUT_FILE);
		layoutData.getLayoutDefinition().add(layout);
		request.setLayoutData(layoutData);

		// リクエストを送信
		return type.generateOutputData(request);
	}

	/**
	 * 指定したJobIDをキーとして印刷状態を取得する
	 *
	 * @param jobID JobID
	 * @return 印刷状態
	 */
	private PrintStatus getBatchPrintStatus(String jobID) throws Exception {
		// クライアントを生成
		Bizstream service = new Bizstream(new URL(WSS_SERVICE_LOCATION + "/bizstream?wsdl"));

		// MTOMを有効化
		WebServiceFeature feature = new MTOMFeature(true);
		BizstreamPortType type = service.getBizstreamSOAP11Port(feature);
		BindingProvider bp = (BindingProvider) type;
		Map<String, Object> reqContext = bp.getRequestContext();
		reqContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
				WSS_SERVICE_LOCATION + "/bizstream?UserDef=" + USER_DEF);

		// JobIDを設定
		Query query = new Query();
		query.setUrl( PRINT_SERVICE_LOCATION);
		query.getJobId().add(jobID);

		// リクエストを送信
		QueryResult queryResult = type.getBatchStatus(query);

		// 印刷状態を取得
		PrintStatuses printStatuses = queryResult.getPrintStatuses();
		List<PrintStatus> printStatusList = printStatuses.getPrintStatus();
		if (printStatusList.size() < 1) {
			return null;
		}
		PrintStatus printStatus = printStatusList.get(0);

		return printStatus;
	}

	/**
	 * 指定した時間待つ
	 */
	private void sleep() {
		try {
			Thread.sleep(INTERVAL);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}