This sample shows how to use a Java program as an API provider and to pass the JSON request and response payloads directly to and from the Java program. Normally in z/OS Connect, when a COBOL or PL/I program is called as an API provider, a binary payload is passed to and from the COBOL or PL/I program which is converted from and to JSON. However, in this sample the JSON payload is passed directly to and from the Java program meaning no conversion is required.
This sample is coded for CICS TS, but the API mappings and concepts of the Java program are identical for IMS and z/OS Applications. With minor changes to the Java class it will work for IMS, please refer to the Java Application section for details. Any other changes are also noted below.
In this sample we will show how the Path, Query and Header parameters, are passed as binary values but the request and response bodies are preserved in JSON from and to the calling client. By allowing the passing of JSON directly, JSON centric APIs such as Jackson can be used to directly manipulate the JSON in a manner that is more natural in a Java program.
We will use a simple Bookstore management API to demonstrate this usage.
Bookstore API (V1.0.0) has a single path, /bookstore/{title}, and a single method, PUT. The request has 3 parameters, a path title, a query store, and a header publisher, all strings, with a request body of title (string), suggestedPrice (number), and description (string). The 200 response has a returned Header parameter called section (string) and a response body consisting of object properties title (string), store (string), and description (string). See JSONPassthroughAPI/start/src/main/api/openapi.yaml for the full OpenAPI document.
Using the z/OS Connect Designer we will create an API to interface from the client to a Java program running under CICS TS which will act as the API provider. As part of this API construction, we will use JSONata expression functions to process the request and response bodies as JSON strings rather than separate Object properties that would normally be transformed to binary.
For details and options of starting z/OS Connect Designer see the z/OS Connect product documentation.
Let's walk through creating the Bookstore API using z/OS Connect Designer: in the JSONPassthroughAPI/start directory you will find the basic layout of an API project. Use this project as the start point for your Designer session, or alternatly start with an empty project and import the the OpenAPI document.
Note that the finish directory contains the completed API project for your reference.
We need to complete the single path along with the z/OS Asset to create the API. We will use a Meet in the Middle approach to do this using the OpenAPI document and a pre-defined COBOL copybook. Although we have a Java provider program, this Java program will be passed a binary COMMAREA that is used for communication of the API request and response. We use a COBOL copy book to describe the COMMAREA formats.
For the request we have three string parameters and then, rather than a breakdown of the JSON Object request, we want a string to represent the actual JSON payload (and similarly for the response).
Here is an example:
*
* Simple Book Management API(PUT)
*
01 UPDATE-BOOK-REQ.
03 XTITLE PIC X(32).
03 STORE PIC X(32).
03 PUBLISHER PIC X(32).
03 JSON-REQ PIC X(3200).
01 UPDATE-BOOK-RESP.
03 XSECTION PIC X(32) VALUE SPACES.
03 JSON-RESP PIC X(3200) VALUE SPACES.
Using the above Copybook we can create the API as shown below:
- Select the Paths navigation item which then shows the single Path and Method.
- Click on PUT to complete the path.
This shows the missing z/OS Asset and the incomplete Responses section.
- Click on the + symbol to create the z/OS Asset. Ensure Add new z/OS Asset is selected and select Next.
-
Select CICS COMMAREA program from the Asset type dropdown, then complete the following fields. For CICS program name enter BAQBSUP (BookStoreUpdate), for the Program language select COBOL. For the codepage CCSID enter 1047 and finally select a pre-existing CICS connection that has been defined in your Designer setup. Here I am using cicsJava. Then click Next.
Note: If you wish to run this API under IMS Select IMS transaction from the Asset type and enter the IMS Transaction Code and Program language, along with an IMS connection.
- Next import the COBOL data structure copybook to define the API mappings. Click Import data structure and either drop the PassthroughCopybook.cpy file (located in the JSONPassthroughAPI project) into the dialog or use the file selector dialog.
- Once imported select the UPDATE-BOOK-REQ structure and click Add. This will display the Request COMMAREA structure. Click Next.
- Repeat for the Response COMMAREA. Once that is done the z/OS Asset is ready to add. Enter and optional description and click Add z/OS Asset.
- We now need to define the mappings between JSON and the COBOL COMMAREA elements for request and response. Click Request in the BAQBSUP z/OS Asset. This shows the available binary fields that we need to map to the OpenAPI parameters and request body.
- Click the XTITLE field and select the fields menu icon. This will show the following available mappings. For XTITLE select Object/title from the pathParameters section. Repeat for STORE and PUBLISHER using the Query parameter and the Header parameter respectively.
- For JSON-REQ we want to use a JSONata function that will take the complete JSON request body and create a string representing the JSON in the Body. Click the JSON-REQ field and enter {{$string($body)}}. The JSONata string function casts the request body to a string and more details can be found at https://docs.jsonata.org/string-functions. This completes setting up the request structure for the z/OS Asset.
- Now to complete the Responses. There is only one defined response 200 so this is the default response. Click the 200 response to complete. This shows the mapping view.
- For the section header select the field and click the menu icon. In the dropdown under zosAssetResponse select Object/commarea/UPDATE-BOOK-RESP/XSECTION.
- For the 3 remaining response Object properties we need to construct these from the return string that contains the JSON response. This is done using the $eval JSONata function. $eval will take a string containing valid JSON and create a JSON object, from this JSON Object we can select the property we require for the API. Select the title field in the Body and click the Fx icon. Under String functions select $eval(). Then place your cursor within the $eval parentheses and click the menu icon. This shows the available mappings dialog. Select Object/commarea/UPDATE-BOOK-RESP/JSON-RESP. Now we have selected the JSON response string which will be converted to a JSON Object. From this Object we need to select the title property. After the $eval close parenthesis type .title. Repeat for store and description fields using the appropriate property names.
The API is now complete, and in the project's build folder under libs there should be a file called api.war which can be deployed to a z/OS Connect server.
For this provider API, the Java program will extract the passed parameters and JSON body string and create a simple response body and header. When handling the JSON data the Jackson mappers will be used and this program will demonstrate using both the binary and JSON data passed in the COMMAREA. Although this is a CICS TS program, the concepts are exactly the same for IMS or z/OS Applications. With a few minor tweaks this Java program can be used in those systems. See below for some details on the changes required for IMS.
In the JSONPassthroughJava Gradle project the Java program, called BookstoreUpdateProgram, is implemented as a JCICS Java program that will be deployed to a JVM Server within CICS TS as an OSGi Bundle. See below for details on how the Bundle is created and deployed. This Java program was coded against Java 11 SDK.
The main static method is called passing a com.ibm.cics.server.CommAreaHolder instance which contains the data. The getValue() method can then be called to retrun a byte array containing the binary data that matches the UPDATE-BOOK-REQ language structure. i.e.
01 UPDATE-BOOK-REQ.
03 XTITLE PIC X(32).
03 STORE PIC X(32).
03 PUBLISHER PIC X(32).
03 JSON-REQ PIC X(3200).
The COMMAREA binary data is converted to a List of Strings using the method decodeCommarea. This method takes the binary array and the JVMs natural codepage as inputs. decodeCommarea for each field creates a sub array of bytes using the field size and byte offsets, a new Java String is then constructed from the sub byte array and CCSID value and placed in an ArrayList. We now have a List of strings containing Title, Store, Publisher, and the request JSON body.
Using the Jackson ObjectMapper, the raw JSON characters representing a JSON Object with properties are converted to a Map of Key/Value pairs for each property.
Using an embedded static class called Request, a Request object is created from the Map of properties and getter properties used to get each individual field.
Using the suggestedPrice and publisher properties, a book section response parameter is determined as Bargain, New Releases, or General.
We now need to build up the response COMMAREA bytes that match the following COBOL copybook. With the JSON response body string being serialised as a JSON object.
01 UPDATE-BOOK-RESP.
03 XSECTION PIC X(32) VALUE SPACES.
03 JSON-RESP PIC X(3200) VALUE SPACES.
For the XSECTION field, we get the bytes from the section String using the CCSID. The returned byte array is then copied to the COMMAREA byte array and padded with spaces.
To create the response JSON string a Map is created using the strings that represent the response Object properties. The Jackson ObjectMapper is then used to serialise the Map to a JSON string. From this String we get its byte array which is padded with spaces. The byte array is then copied to the COMMAREA byte array after the XSECTION field.
The Java program then exits and CICS TS will pass the COMMAREA back to the caller z/OS Connect, which will process the response as per the defined API and JSONata mappings. This involves creating a section HTTP HEADER and creating a response body with the JSON Object built from the Java returned JSON string.
If an IMS equivalent is required the Java program then the main method is changed to a standard Java main method. The program class will use IMS com.ibm.ims.dli.tm.Application, MessageQueue, and Transaction classes to fetch the passed bytes for a transaction request, this occurs within a while() loop as the Java program is executed for the life of the JMP. Using the com.ibm.ims.application.IMSFieldMessage object which contains the passed field bytes as per the COBOL copybook the bytes for each field can be extracted using the Cp1047 code page and a Java String contructed.
Similarly when constructing the output bytes an IMSFieldMessage object can be used to marshal the bytes ready for output from the Java Strings. The IMSFieldMessage is inserted into the output MessageQueue and the transaction committed using Transaction objects commit() method.
The project JSONPassthroughJava is a Gradle project that uses the com.ibm.cics.bundle plugin along with biz.aQute.bnd.builder plugin to build an OSGi bundle containing the Java class that is suitable to deploy to a CICS TS JVM Server using the DFHOSGI profile.
If an IMS execution is required please refer to the IMS documentation for full details of IMS JMP setup.
The bundle includes the Jackson JSON libraries used to process the JSON in the Java class
The build.gradle file defines the required dependencies and captures the dependent libs after building the Java class. The cicsBundle task is then used to augment the OSGi bundle built by the bnd plugin using the bnd.bnd file. The cicsBundle task references CSD defined elements for the region where the bundle will be deployed. Refer to the latest CICS TS documentation for full details.
cicsBundle {
build {
defaultJVMServer = 'PTJVMSVR'
}
deploy {
bunddef = 'BAQBUNDL'
csdgroup = 'BAQJ'
url = 'http://test.ibm.com:22502'
}
}
From the project directory use gradle clean buildCICSBundle ---info to build the OSGi bundle. Under the build directory a bundle directory called JSONPassthroughJava-1.0.0 is created. See below for how this is deployed to a CICS TS region.
NOTE: Task cicsBundle requires to use Gradle version 8.10. Please ensure you have this version installed or use Gradle Wrapper to invoke this version.
The file csd.jcl defines the CSD definitions required to execute the Java program. The definitions consist of a JVMSERVER, BUNDLE, and PROGRAM.
DEFINE JVMSERVER(PTJVMSVR) GROUP(BAQJ)
JVMPROFILE(DFHOSGI)
DEFINE BUNDLE(BAQBUNDL) GROUP(BAQJ)
BUNDLEDIR(/u/user/bundles/JSONPassthroughJava-1.0.0)
DEFINE PROGRAM(BAQBSUP) GROUP(BAQJ)
JVMSERVER(PTJVMSVR) JVM(YES)
JVMCLASS(com.ibm.zosconnect.cics.BookstoreUpdateProgram)
The BUNDLE definition references the directory that contains the bundle directory created by the Gradle build. The complete JSONPassthroughJava-1.0.0 build directory is copied to this location.
Once the CSD has been defined and the group installed review the regions logs and JVM servers logs to ensure the bundle is active.
To configure a z/OS Connect server, copy the api.war file from the build/libs directory of the Designer project to the server's apps directory.
The server's server.xml config should be similar to this.
<?xml version="1.0" encoding="UTF-8"?>
<server description="sample-java-api">
<!-- Enable features -->
<featureManager>
<feature>zosconnect:cics-1.0</feature>
</featureManager>
<!-- To access this server from a remote client -->
<httpEndpoint id="defaultHttpEndpoint" host="*"
httpPort="${HTTP_PORT}"
httpsPort="${HTTPS_PORT}" />
<!-- config requires updateTrigger="mbean" for REFRESH command support -->
<config updateTrigger="mbean"/>
<!-- applicationMonitor requires updateTrigger="mbean" for REFRESH command support -->
<applicationMonitor updateTrigger="mbean" dropinsEnabled="false"/>
<!-- Automatic expansion of WAR files is required for z/OS Connect native servers -->
<applicationManager autoExpand="true" />
<!-- APIs are deployed as WAR files and a webApplication element must be used to specify
the location of the API WAR and optionally the name of the API -->
<webApplication id="JSON PT Java"location="${server.config.dir}/apps/api.war" name="JsonPTApi"/>
<zosconnect_cicsIpicConnection id="cicsJava" host="test.ibm.com"port="22502"/>
</server>
To test the API, ensure both the CICS TS region hosting the OSGi bundle in its JVM server and the z/OS Connect server with the API installed are both running. Enter the following curl command which supplies the API parameters and the request body as per the OpenAPI description for the API. Note that the response contains the section HTTP header and the response body built by the API mapping from the response JSON string.
curl -X 'PUT' \
'http://test.ibm.com:22501/bookstore/redbook?store=ibm' \
-H 'accept: application/json' \
-H 'publisher: IBM' \
-H 'Content-Type: application/json' -D - \
-d '{
"title": "redbook",
"suggestedPrice": 0.00,
"description": "A sample Redbook"
}'
CICS TS JVM Server STDOUT
Inbound Title: redbook
Inbound Store: ibm
Inbound Publisher: IBM
Inbound JSON: {"title":"redbook","suggestedPrice":0,"description":"A sample Redbook"}
Outbound Section: Bargain
Outbound JSON: {"description":"A sample Redbook","title":"redbook","store":"ibm"}
Curl Response
HTTP/1.1 200 OK
X-Powered-By: Servlet/4.0
section: "Bargain"
Content-Type: application/json
Date: Thu, 18 Dec 2025 15:11:30 GMT
Content-Language: en-US
Content-Length: 58
{"title":"Redbook","store":"ibm","description":"A sample Redbook"}















