Midrange News for the IBM i Community


Posted by: TFisher
Web service on the iSeries
has no ratings.
Published: 06 Jun 2013
Revised: 11 Jun 2013 - 3965 days ago
Last viewed on: 19 Apr 2024 (6346 views) 

Using IBM i? Need to create Excel, CSV, HTML, JSON, PDF, SPOOL reports? Learn more about the fastest and least expensive tool for the job: SQL iQuery.

Web service on the iSeries Published by: TFisher on 06 Jun 2013 view comments(15)

I have a web service that I am working on that needs to accept arrays as input parameters.  The problem is that the XML is ugly.  Is there any way to allow a well-formed XML request to be made?

 

Right now the XML must look like this:

 

<Item>SKU1</Item>

<Item>SKU2</Item>

<Qty>1</Qty>

<Qty>2</Qty>

<Price>1.22</Price>

<Price>2.22</Price>

 

But I want it to look like this:

<OrderLine>

  <OrderLine>

   <Item>SKU1</Item>

   <Qty>1</Qty>

   <Price>1.22</Price>

  </Product>

  <Product>

    <Item>SKU2</Item>

    <Qty>2</Qty>

    <Price>2.22</Price>

  </OrderLine>

</OrderLines> 

 

Is there something in Webshere I can do to allow this format to be accepted?

Return to midrangenews.com home page.
Sort Ascend | Descend

COMMENTS

(Sign in to Post a Comment)
Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 4 hours 24 minutes ago

A second issue I have is the reponse includes all 999 elements of my arrays and not just the number of elements passed in.  

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 3 hours 34 minutes ago

Hi Fish, I don't know if you really mean WebSphere or if you mean RPG IV? To me, "WebSphere" was used as term like "Lotus" to identify a family of products but no specific product--while many assumed the product they were using was called "Lotus" or "WebSphere".

In RPG IV, you can control what gets extracted by using a POSIX-style path to the sub-elements of the XML.

/OrderLines/OrderLine/Qty

This would extract the Qty value only. To pull out all the entries from OrderLine, then you'd extract them into a data structure named OrderLine and specify:

/OrderLines/OrderLine

on the XML-INTO statement.

 

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 3 hours 24 minutes ago

I am using Soap/XML and letting Apache handle all the parsing.  I have created an application server to call my program and pass it the parameters.

 

The problem is that we want to have a 'List' in the XML request being sent by the consumer. 

Posted by: clbirk
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 2 hours 52 minutes ago

Then, why don't you just build it in code and pass out a single field that has the xml structure in it that you want?

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 1 hours 5 minutes ago

A list is processed as an array in RPG. THe XML parser will return the count for you. Then you typically create a "Handler" routine that is just a subprocedure with a pre-defined parameter list (the parms include the array of data and the count of elements).

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 51 minutes ago

That is what I was thinking...it would basically be an array in RPG.  But I don't get any of the parameters when we build the XML the way we want it.  It has to be in the first format I posted before the arrays will load up.

 

I don't know what you mean by a "handler" routine though.  Is this something IBM has documented?  I have not been able to find any good documentation on how to deploy web services that allow for more complex structured XML (like lists or root elements).

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Web service on the iSeries
Posted: 10 years 10 months 14 days 10 minutes ago

If you're parsing XML with RPG, then yes, the %HANDLER function identifies the subprocedure that is auto-called (aka "callback" function) that is run when the XML parses a set (aka, array) of "records". It's document here in the RPG Reporter and in the RPG manuals.

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 13 days 23 hours 53 minutes ago

No, I am not doing any XML parsing.  My app never sees XML.  Apache is handling all that and I just get parameters passed in.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Web service on the iSeries
Posted: 10 years 10 months 13 days 20 hours 33 minutes ago

Okay. Well, can't help you. When I get in a SOAP/XML request, I save it to the IFS and then parse it in RPG using XML-INTO.

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 13 days 19 hours 34 minutes ago

That is what I really wanted to do, but I couldn't figure out how to tell Apache to do that either.  Plus, everyone else on this project is tired of waiting on me to figure out how to make this work so we decided to do it this way...even though it seems to be very limited, or at least not very well documented.  

THANKS!

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 13 days 7 hours 48 minutes ago

Bob,

Can you point me to some documentation that explains how to deploy a web service so that the XML is placed into a unique file name on the IFS and then calls my RPG program?

 

This is actually what I was attempting to figure out a couple of weeks ago but was too dumb to figure it out with everyone here telling me to HURRY and figure it out.  I still want to learn how to do it "right", but for now I think I am stuck having Apache do the parsing and passing my program indicidual parameters.  I will continue to play around and look for documentation to figure out how to make XML Lists work with this approach.

 

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 10 days 21 hours 33 minutes ago
Edited: Sun, 09 Jun, 2013 at 16:45:36 (3967 days ago)

I have played around with this a bit more this weekend and I have it a little closer to what I am needing.  Making the array parameter a data structure effected the PCML which allowed the parameter to be identified as 'struct' instead of a character string.  

 D GetProducts     Pr                  ExtPgm('WSTEST')     
 d   CountRet                    10i 0                       
 d   Products                          Likeds(Product) Dim(20)
 d                                     Options(*Varsize)     

 

Now I have a test that is generates XML that looks like this:

 

<GETPRODUCTS>

 <COUNTRET>2</COUNTRET>

 <PRODUCTS>

    <STYLE>A</STYLE>

    <COLOR>CLR1</COLOR>

    <SIZE>SIZE1</SIZE>

    <BACKING>01</BACKING>

    <WHSE>MID</WHSE>

    <PRICE>1.11</PRICE>

    <WEIGHT>101.10</WEIGHT>

 </PRODUCTS>

 <PRODUCTS>

    <STYLE>B</STYLE>

    <COLOR>CLR2</COLOR>

    <SIZE>SIZE2</SIZE>

    <BACKING>02</BACKING>

    <WHSE>MID</WHSE>

    <PRICE>2.22</PRICE>

    <WEIGHT>202.20</WEIGHT>

 </PRODUCTS>

</GETPRODUCTS> 

 

But I am needing it to look like this with a repeating once for each array element within the :

<GETPRODUCTS>

 <COUNTRET>2</COUNTRET>

 <PRODUCTS>

    <PRODUCT>

        <STYLE>A</STYLE>

        <COLOR>CLR1</COLOR>

        <SIZE>SIZE1</SIZE>

        <BACKING>01</BACKING>

        <WHSE>MID</WHSE>

        <PRICE>1.11</PRICE>

        <WEIGHT>101.10</WEIGHT>

    </PRODUCT>

    <PRODUCT>

       <STYLE>B</STYLE>

       <COLOR>CLR2</COLOR>

       <SIZE>SIZE2</SIZE>

       <BACKING>02</BACKING>

       <WHSE>MID</WHSE>

       <PRICE>2.22</PRICE>

       <WEIGHT>202.20</WEIGHT>

    </PRODUCT>

 </PRODUCTS>

</GETPRODUCTS>

Posted by: TFisher
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 10 days 5 hours 43 minutes ago

I think I have this figured out.  THANKS!

 

I would still like to know how to have the XML request placed on the IFS and have WebSphere call my program to process the XML as opposed to having WebSphere parse the XML request and pass all the parameters into my program.

Posted by: bobcozzi
Site Admin ****
Chicagoland
Comment on: Web service on the iSeries
Posted: 10 years 10 months 9 days 2 hours 59 minutes ago

Fish, if you were using COZCGILIB (COZTOOLS CGI library) I would say, start the program (specify it as the URL for the remote to transfer the XML/SOAP package to) then just do a cgiSaveFileToIFS. There is also a "save raw CGI buffer" if you want to also save the SOAP wrapper. But I'm suspecting you're doing most of the roll-your-own stuff, so that's not going to help much.

Posted by: Ringer
Premium member *
Comment on: Web service on the iSeries
Posted: 10 years 10 months 9 days 1 hours 24 minutes ago

I can show you how in php if interested. This is not SOAP (but a PHP class can be a SOAP server with a WSDL - created via Zend Studio).

 

Put a php !--script-- in /www/zendsvr/htdocs/test.php and

point URL to http://my400:10088/test.php?Num=1&Name=Bob

 

 

<?php   
// Save GET to POST data to IFS
define('BR','<br />') ;                                                 
$fileName = '/tmp/FilePutContents_' .
            time() . '_' . strtr(uniqid('',true),'.','_') . '.txt';

echo 'File Name: ', $fileName, BR;       

$method = $_SERVER['REQUEST_METHOD'] ;           
echo 'REQUEST_METHOD: ', $method, BR;            
if ( $method == 'POST' ) {                       
   $rawData = file_get_contents('php://input');  
else {                                        
   $rawData = $_SERVER['QUERY_STRING'] ;      
}                                             

file_put_contents($fileName, $rawData);       
echo htmlentities($rawData, ENT_QUOTES), BR ;

// File Name: /tmp/FilePutContents_1370972810_51b7628a5d1f50_24466868.txt
// REQUEST_METHOD: GET
// Num=1&Name=Bob

Chris Ringer