CIB documentServer technischer Leitfaden (DE)

Schneller Einstieg

Aufruf CIB documentServer

Im Folgenden finden Sie Beschreibungen, wie Sie aus dem Client-Paket den CIB documentServer komfortabel in JAVA einbinden können. Außerdem enthält dieser Abschnitt Anleitungen, wie Sie den CIB documentServer webservice in Visual basic .net, C# .net und mit dem JAX-WS Framework aufrufen können.

CIB documentServer Framework/Java
CIB documentServer Framework/.net
Aufruf CIB documentServer webservice
Aufruf CIB documentServer asynchron


CIB documentServer Framework/Java

Das CIB documentServer Framework ermöglicht für Java eine komfortable Einbindung des CIB documentServers. Aufgrund der Ähnlichkeit der Konzepte der beiden Plattformen sowie von Java und C# wird bleibt der entsprechende Abschnitt kurz.

Mit dem CIB documentServer Framework können Java Anwendungsentwickler die Auftragsdateien erzeugen, die Auftragsergebnisdateien analysieren, sowie die Ergebnisdokumente herausholen.

Die Auftragsverarbeitung wird entsprechend dem Schichtenmodell in mehreren Ebenen durch das Framework abgebildet.

Serverschicht

Auf dieser – innerhalb Java untersten – Ebene findet die Kommunikation zu den nativen Komponenten statt und sind Prozessmonitoring, Locking, interne Lastverteilung und Warteschlange implementiert.

Auftragsdateien und Auftragsergebnisdateien werden als byte[] bzw. byte[][] betrachtet und verarbeitet.

Sie können diese Klassen nutzen, um eine enge Zusammenarbeit mit dem CIB documentServer zu erreichen, wenn Sie die Serverschicht erweitern möchten, oder eine eigene Serverschicht entwickeln.

Integrationsschicht

Hier sind vorgefertigte Klassen zur Integration in die verschiedenen Nutzungsvarianten vorhanden, etwa das Servlet für die http-Schnittstelle zum CIB documentServer. Diese Schicht wird noch erweitert um Klassen zur Integration in EJB, JNI und MQSeries.

Sie werden diese Klassen direkt einsetzen, oder ganz durch eigene Klassen ersetzen. Sprechen Sie mit uns über die Bereitstellung von Sourcecode.

Anwendungsschicht

Sowohl in der Anwendungsschicht als auch in der Bereitstellung von Klassen für die Integrationsschicht werden Klassen zum komfortablen Erstellen und Ausführen von Auftragsdateien angeboten.

Auf dieser Ebene ist ein Auftrag ein Objekt vom Typ de.cib.docserv.job.Request und die Auftragsergebnisdatei vom Typ de.cib.docserv.job.Response. Die Ergebnisdokumente werden als Streams zur Verfügung gestellt.

Ein Auftrag wird an eine Klasse übergeben, die das Interface de.cib.docserv.DocumentServer implementiert, wie zum Beispiel die de.cib.docserv.UrlDocumentServerImpl, die die Kommunikation mit einem CIB documentServer über die Nutzungsvariante http vollständig kapselt.

…
Response t_Response = new UrlDocumentServerImpl(t_Hostname, 
t_Port).execute(t_Request);
if 
(!t_Response.hasErrors())
{
        JobResult t_JobResult = t_Response.getJobResult();
        StepResult t_StepResult = t_JobResult.getStepResult();
        String t_ContentType = t_StepResult.getMimeType();
        InputStream t_Document  = t_StepResult.getStepData();

Packages

Im Folgenden sind die wichtigsten Packages aufgelistet.

de.cib.docserv

Dieses Package enthält zusammen mit den Unterpackages die Klassen, die für die Nutzungsvarianten Java, JEE Servlet Container und JEE EJB Container benötigt werden.

Speziell die für Sie wichtigen Schnittstellenklassen, die das Interface de.cib.docserv.DocumentServer implementieren finden Sie hier. Außerdem die Basisimplementierung des CIB documentServer in Form von de.cib.docserv.ServerManager, de.cib.docserv.ServerQueue, sowie die Exception- und Error-Klassen.

de.cib.docserv.job

Dieses Package enthält unter anderem die für Sie wichtigen Hilfsklassen de.cib.docserv.job.Request und de.cib.docserv.job.Response, mit denen Aufträge erzeugt und analysiert werden können. Benutzen Sie zusätzlich die Klasse de.cib.xml.dom.Dom, um Ihr XML mit den Nutzdaten dem Auftrag hinzuzufügen.

de.cib.xml.dom

Hervorgehoben sei die Klasse de.cib.xml.dom.Dom, mit der andere Klassen des Frameworks XML-Daten entgegennehmen. Verpacken Sie also Ihr XML mit den Nutzdaten in einen de.cib.xml.dom.Dom.

Beispiel-Aufruf aus JAVA

Das CIB documentServer Framework ermöglicht eine Einbindung des CIB documentServers. Im ersten Schritt wird die Auftragsdatei eingelesen und daraus der Request für den CIB documentServer erstellt. Im nächsten Schritt wird der CIB documentServer erzeugt und konfiguriert, der den Request bearbeitet. Als Ergebnis liefert der CIB documentServer eine Response, die im letzten Schritt verarbeitet wird. Das folgende Code-Snippet zeigt die Einbindung eines CIB documentServers in ein Java Programm.

//create request for the CIB documentServer
Request request = new RequestXmlParser().parseRequest(new File("Job.xml"));
//create documentServer with following parameters: hostname: remote computer, where 
the CIB documentServer servlet is configured; port: port number of servlet.
DocumentServer documentServer = new UrlDocumentServerImpl(“localhost“, 8080);
//get the response from the CIB documentserver
Response response = null;
if (request != null) {
	response = documentServer.execute(request);
	//check if all jobs were successful
	if (response.hasErrors() || response == null {
		System.err.println("Response: "+response);
		System.out.println("Bytes written: "+0);
		response.throwException(); // optional
	} else {
		//Save the JobResult in a client file
		InputStream input = null;
		OutputStream output = null;
		int bytesWritten = 0;
		Set enumStepResults = response.getJobResult().getStepNames();
		if (enumStepResults != null) {
			Iterator iterator = enumStepResults.iterator();
			while (iterator.hasNext()) {
				String name = (String) iterator.next();
				try {
					input = response.getJobResult().
						getStepResult(name).getStepData();
					if (input.available() <= 0)
						continue;
					// only one result is available and the 
					// mimetype is application/pdf
					output = new FileOutputStream(new File(request
						.getJob().getName() + "-" + name +
						".pdf"));
					byte[] buffer = new byte[0xffff];
					int bytesRead = 0;
					while ((bytesRead = input.read(buffer)) >= 0) {
						output.write(buffer, 0, bytesRead);
						bytesWritten += bytesRead;
					}
					if (bytesWritten <= 0) {
						byte[] text = "Empty Result".getBytes();
						output.write(text, 0, text.length);
						bytesWritten += text.length;
					}
					input.close();
					output.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		System.out.println("Bytes written: " + bytesWritten);
	}
} 

Weitere Beispiele finden Sie im Client-Paket unter example/de/cib/docserv/samples.

Aufbau eines Auftrags aus JAVA

Es ist auch möglich einen XML-Auftrag erst durch das CIB documentServer Framework aufzubauen.

//build new Request
Request request = new Request();
Job job = new Job("testJob");
job.setProperty("OutputMode", "XML");
Step pdfJoinStep = new Step((new CommandFactory()).createCommand(CommandFactory.COMMAND_PDFJOIN), "PdfJoinStep");
//Set the propertys for the request
pdfJoinStep.setProperty("OutputFilename", "ZUGFeRD-invoice.xml");
pdfJoinStep.setProperty("ZUGFeRDDoCheck", "1");
pdfJoinStep.setProperty("OutputFormat", "FormatInfo");
pdfJoinStep.setProperty("FilterInfo", "EmbeddedFilesInfo");
pdfJoinStep.setProperty("EmbeddedFilesInfoFilter", "EmbeddedFiles");
//Set a property with setPropertyMode and “out” value in order to obtain its value in the //response
pdfJoinStep.setPropertyMode("EmbeddedFilesInfo", "out");
pdfJoinStep.setPropertyMode("ModuleName", "out");
//Use setPropertyMode with value “inout”in order to hint, that the value of an input //property will also be obtained in the response. 
pdfJoinStep.setProperty("InputFilename", “Test.pdf”);
pdfJoinStep.setPropertyMode("InputFilename", "inout");
job.addStep(pdfJoinStep);
request.addJob(job);
 

In diesem Beispiel wird ein Auftrag mit einem “PdfJoin” Step aufgebaut. Eine Reihe von Properties wird für den entsprechenden Auftrag programmatisch deklariert.

Es ist auch möglich den Wert von gewünschten Properties im Ergebnis-Response abzuholen durch die Verwendung der Methode “setPropertyMode” beim Request-Aufbau (ab Version 1.10.6).

Die Propertywerte können wie folgt abgeholt werden:

JobResult t_JobResult = response.getJobResult();
StepResult t_StepResult = t_JobResult.getStepResult("PdfJoinStep ");
String ModuleName = t_StepResult.getProperty("ModuleName");
String embeddedFilesInfo = t_StepResult.getProperty("EmbeddedFilesInfo");
String inputFilename = t_StepResult.getProperty("InputFilename"); 

CIB documentServer Framework/.net

Analog zum Framework/Java erlaubt das Framework/.net eine Einbindung der Auftrags-Funktionalität in kundeneigene .net-Anwendungen.


Aufruf CIB documentServer webservice

In diesem Abschnitt finden Sie Beschreibungen, wie Sie in unterschiedlichen Umgebungen den CIB document webservice aufrufen können. Dabei wird auf VB.net, C#.net und das JAX-WS Client Framework eingegangen.

VB.net

Entwerfen Sie eine Methode, die den CIB documentServer webservice aufruft.

Hinzufügen des Webservice

Registrieren Sie den Webservice, indem Sie Ihrem Projekt eine Webressource hinzufügen. Ergänzen Sie die URL am Ende mit ?wsdl. Der Webservice “CibDocumentServer” sollte mit einer Methode “generate” angezeigt werden. Geben Sie den Paketnamen aus de.cib.docserv.web als „Web reference name“ an.

Generieren Sie Klassen, indem Sie „Update“ auswählen. Um diesen Schritt erfolgreich auszuführen, benötigen Sie Internetzugriff auf www.cib.de.

Aufruf des Webservice

Entwerfen Sie jetzt Instanzen der Service und Request Klassen z. B. folgendermaßen:

Dim service As New de.cib.docserv.web.CibDocumentServer
Dim request As New de.cib.docserv.web.Request

Fügen Sie dem Request die benötigten Steps hinzu. (siehe auch Codebeispiel im Anhang)

Dim mergeStep As New de.cib.docserv.web.StepType
Dim mergeProps(4) As de.cib.docserv.web.PropertyType
mergeStep.name = "step1"
mergeStep.command = "merge"

mergeStep.properties = New de.cib.docserv.web.PropertiesType()
mergeStep.properties.property = mergeProps
mergeStep.properties.property(0) = New de.cib.docserv.web.PropertyType()
mergeStep.properties.property(0).name = "-i"
mergeStep.properties.property(0).Value = "Test.rtf"

Fügen Sie dem Request Ihre Nutzdaten hinzu. Der Aufbau ist beliebig, muss aber zum Eingabe-Template (-i) des merge-Steps passen und zur Option -d.

Dim XmlString As String = "Otto..."
Dim xmldata As New System.Xml.XmlDocument
xmldata.LoadXml(XmlString)

request.Data = xmldata.DocumentElement

Rufen Sie jetzt den Webservice auf und bereiten ihn auf den Empfang des Ergebnisses vor:

Dim response As de.cib.docserv.web.Response
response = service.generate(request)

Verarbeiten von Ergebnissen

Treten Server-Fehler auf, wird durch obigen Aufruf eine Exception geworfen.

Im Falle von Fehlern, die bei der Dokumentgenerierung auftreten, werden keine Exceptions geworfen. Sie erhalten stattdessen ein Response-Objekt. Sie sollten den Fehlercode vom Jobresult abholen, um zu entscheiden, ob ein Ausführungsfehler aufgetreten ist. Ein Beispiel für eine Fehlermeldung lautet: „CIB merge error 10: Unbekannte Variable im Template“.

Dim jobResults As de.cib.docserv.web.JobResultsType
jobResults = CType(response.Comod.Items(0), de.cib.docserv.web.JobResultsType)
If (jobResults.jobresult(0).jobresultcode = 0) Then
	' Success
	Dim stepData As de.cib.docserv.web.StepDataType
	stepData = jobResults.jobresult(0).stepresults(1).stepdata
	...	
Else
	' A step failed
	Debug.Print("Error " & jobResults.jobresult(0).jobresultcode & ": " _
		& jobResults.jobresult(0).jobresulttext)
	Debug.Print("Failed step(s): " _
		& jobResults.jobresult(0).failed.name)
	...
End If

Im Erfolgsfall müssen Sie die erzeugten Dokumente aus dem Response herausholen. Das Ergebnis ist base64-kodiert. Dieses müssen Sie entsprechend dekodieren.

' Extract base64 encoded pdf from stepdata
saveDocument(stepData.Value)

Den kompletten VB.net Sourcecode finden Sie im Anhang dieses Dokuments.

Die entsprechenden Beispiele für SOAP Requests und Responses finden Sie ebenfalls im Anhang.

C# .net

Soll der CIB documentServer aus C#.net als Webservice aufgerufen werden, ist genauso vorzugehen wie unter VB.net. Die Aufrufe unterscheiden sich lediglich in ihrer Syntax. Einen Beispielcode finden Sie im Anhang.

Bei dem Aufruf aus C#.net mittels einer HTTP-Verbindung kann es Kommunikationsprobleme im Zusammenhang mit einem Applikationsserver geben. In diesem Fall kann es möglicherweise helfen, die „Expect100Continue“-Eigenschaft der Client-Server Verbindung zu deaktivieren (der Standardwert ist true). Beispiel:

webRequest.ServicePoint.Expect100Continue = false;

CIB documentServer Framework/JAX-WS

Der JAX-WS (Java API for XML-Web Services) Client stellt eine einfache Möglichkeit dar, den CIB documentServer webservice aufzurufen. Die Funktionalität ist im CibDocumentServer.jar integriert. Um JAX-WS zu benutzen ist mindestens ein JRE 5.0 notwendig.

Lokaler Aufruf von CIB job (Offline)

Dieser Abschnitt muss noch überarbeitet werden bzgl. JobDocumentServerImpl.

Der modulare Aufbau des CIB documentServer erlaubt dessen Installation auf dem Client auch ohne lokale Serverumgebung wie JEE Servlet Container, MTS oder .net.

Die Anwendung übergibt einen Auftrag (XML) an die vorhandenen Komponenten des CIB documentServer, der ein entsprechendes Dokument erzeugt.

Die Übergabe erfolgt dabei über Aufrufschnittstellen aus Javacode oder aus native Code (Schnittstellen Java Call, Native Call). Hierfür ist kein JEE Application-Server erforderlich.

Wenn mehrere Threads Aufträge an einen Servermanager senden, jedoch kein Webcontext vorliegt, stehen geeignete Klassen bereit, um die Verwaltung des Servermanagers zu übernehmen (de.cib.docserv.LocalDocumentServerImpl).

In normalen Java-Anwendungen, die statt JNI ebenfalls das CIB documentServer Framework einsetzen möchten, ist es nicht erforderlich, mehrere Socketserver parallel zu starten.

Stattdessen reicht ein einzelner externer Prozess aus, der vom Framework automatisch gestartet wird. Auch für diese Situation stehen neben den Auftragsklassen (de.cib.job.Request, de.cib.job.Response) geeignete Verwaltungsklassen bereit (de.cib.docserv.SingleDocumentServerImpl).


Aufruf CIB documentServer asynchron

Um Aufträge asynchron mit dem CIB documentServer auszuführen, verwenden Sie bitte die Methode asyncExecute des CIB documentServer Frameworks.

Bei Verwendung anderer Ansteuerungen des CIB documentServers aus anderen Sprachen, setzen Sie bitte zusätzlich zu allen üblichen http header fields noch das Headerfield async-action:

Asynchronen Aufruf starten:

async-action: new

Ergebnis des asynchronen Aufrufs mit der ID 12345 abholen:

async-action: 12345

Die bei asynchronen Aufrufen ausgetauschten XML-Inhalte entnehmen Sie bitte dem technischen Leitfaden für CIB job aus den Abschnitten Zusatzeinstellungen für asynchron ausgeführte Aufträge und Inhalt eines Auftragsergebnisses zu einem asynchron ausgeführten Auftrag.