There will be times when a client is better served by providing a service with a JSON over HTTP interface, rather than the more common SOAP over HTTP. By re-using the Java code that we built in the Converting between XML and JSON recipe, we'll expose a JSON interface, while working with XML internally to take the best advantage of OSB's strengths.
We'll assume that you have an OSB configuration project in OEPE, and that you have the Jackson and XMLBeans JAR files referred to in the Converting between XML and JSON recipe, as well as the JAR files produced by that recipe.
Enter the name jars
for the folder in the New Folder dialog, and click on Finish.
jars
folder:dist/CreditCardServiceMessages_1.0.jar
dist/CreditCardServiceMessagesXmlBeans_1.0.jar
lib/jackson-core-asl-1.9.7.jar
lib/jackson-mapper-asl-1.9.7.jar
In the Modify Jar Dependencies dialog, select the jackson-core-asl-1.9.7.jar file from the Available jars pane on the left, and click on the Add > button to move it to the Jar references pane. Click on OK.
There will be warnings about classes from the org.joda.time
package not being available. This is an optional dependency in the Jackson Mapper, and will not be a problem.
JSONCreditCardService_1.0
for the proxy service and click on Finish.HTTPMethodBranch
). For this branch, we will select a path based on the incoming HTTP method – we'll only support POST
for this service.<XPath>
value to open the XPath Expression Editor. Expand the inbound variable in the Variable Structures tab, as shown in the following screenshot:./ctx:transport/ctx:request/http:http-method
inbound
in the In Variable text field. The conditional branch should be configured as follows:POST
in the Label field, and 'POST'
in the Value field.PostPipelinePair
.PostPipelinePair
, and assign it the name ProcessPutRequest
.ProcessPOSTRequest
stage. In the Properties pane, click on the Browse button to select the method to be invoked.This will open the Select an Archive Resource dialog box. Select the CreditCardServiceMessages_1.0.jar
file in the JSONCreditCardService
project and click on the OK button. In the Select a Java Method dialog box, select the method debitCreditCardJsonToXml(java.lang.String)
and click on OK.
<Expression>
value to specify the input parameter to the Java method. Specify the XPath expression as $body/text()
. The content of the body variable is the received JSON string.requestXml
; the return value of the Java method will be assigned to this variable.Click on the ProcessPutRequest stage in the Message Flow view, and select the Namespaces tab in the Properties pane. Add the three namespace mappings, as shown in the following table:
Prefix |
URI |
---|---|
|
|
|
|
|
|
The result will be as follows:
data($requestXml//cmn:cardNumber)
, and the Variable to creditCardNumber
.Insert a Stage named ProcessPostResponse into the Response Pipeline of the PostPipelinePair
, and add the same namespace definitions as we previously added to the ProcessPutRequest stage.
<ebm:debitCreditCardResponse xmlns:ebm="http://rubiconred.com/ckbk/ebm/CreditCard" xmlns:cmn="http://rubiconred.com/ckbk/xsd/common"> <cmn:cardNumber>{$creditCardNumber}</cmn:cardNumber> <cmn:cardAuthCode>0000</cmn:cardAuthCode> </ebm:debitCreditCardResponse>
Set the Variable to responseXml
.
debitCreditCardResponseXmlToJson(org.apache.xmlbeans.XmlObject)
.Set the Java Callout activity's input parameter Expression to $responseXml
, and the Result Value to responseJson
.
.
body
$responseJson
Select the Replace node contents option.
Inbound Response
. Click on the Add Header button to add a new header to the Inbound Response.Set the HTTP header Content-Type to have the value 'application/json'
; this is the standard MIME type for JSON data.
The completed Pipeline Pair looks like the following screenshot:
Since JSON is just structured text, we can configure an OSB proxy service to accept and respond with JSON by using the Text messaging type. We then use the Jackson and XMLBeans libraries to convert between JSON and XML as required.
The Transport Header activity is used to set the Content-Type header in the response to application/json
, in order to inform the client of the data format used for the response. It's good practice for non-SOAP HTTP interfaces to ensure that the HTTP method, status code, and headers are used correctly.
It's possible to build services with OSB that will accept input in multiple formats, by inspecting the received Content-Type header, which can be accessed at:
$inbound/ctx:transport/ctx:request/tp:headers/http:Content-Type/text()
The appropriate transformation of the request payload can then be applied into a common format. Similar techniques may be used to return the response in a format chosen by the caller. The caller could indicate its preferred response format by using the Accept header, or by using something like a suffix on the request URI, which is accessed at:
$inbound/ctx:transport/ctx:request/http:relative-URI/text()
When adding error handling to your JSON services, you will probably want to override the HTTP status code of your response, to best communicate the error back to the caller. This can be achieved using an Insert activity, configured as follows:
Parameter |
Value |
---|---|
Expression |
|
Location |
as last child of |
XPath |
|
In Variable |
|
Where 404
in the previous table is the HTTP status code that will be returned in the response.