Using a web service from Natural on mainframe

Hello, I am trying to use a web service (http://www.webservicex.net/globalweather.asmx as an example) from Natural on the mainframe. I am using the REQUEST DOCUMENT statement. I can connect ok and get a 200 http return code when I use this code:

REQUEST DOCUMENT FROM #FROM              
 * WITH                                   
 *   HEADER #OUT-HDR 'POST'               
 *   DATA #DOCUMENT 'POST'                
   RETURN                                 
    HEADER ALL             #HEADER        
    NAME 'Content-Type'    #DOC-CHARSET   
   PAGE #PAGE                             
 RESPONSE #RC                             
   GIVING #RTERR                          

I seem to be getting the html page back. What I want to do is send it a SOAP envelope with the request to get the weather for Tokyo, Japan. I did this successfully using the SoapUI tool, and I copied the SOAP request into my Natural code. So I uncommented the WITH, HEADER and DATA lines. BUt then, I get a 415 - HTTP/1.1 415 Unsupported Media Type error. Any clues? I am fairly new to web services and SOAP. Here is my SOAP request:

COMPRESS                                                     
'<soapenv:Envelope '                                         
'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"'  
'xmlns:web="http://www.webserviceX.NET">'                    
'   <soapenv:Header/>'                                       
'   <soapenv:Body>'                                          
'      <web:GetWeather>'                                     
'         <!--Optional:-->'                                  
'         <web:CityName>tokyo</web:CityName>'                
'         <!--Optional:-->'                                  
'         <web:CountryName>Japan</web:CountryName>'          
'      </web:GetWeather>'                                    
'   </soapenv:Body>'                                         
'</soapenv:Envelope>'                                        
INTO #DOCUMENT       

Try

define data local
1 #FROM     (A) DYNAMIC
1 #DOCUMENT (A) DYNAMIC
1 #HEADER   (A) DYNAMIC
1 #PAGE     (A) DYNAMIC
1 #DOC-CHARSET (A) DYNAMIC
1 #RETERR   (I4)
1 #RC       (I4)   
End-define        
*                       
#FROM := 'http://www.webservicex.net/globalweather.asmx'
*                      
COMPRESS
'<?xml version="1.0" encoding="utf-8"?>' 
'<soap:Envelope'                                       
'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'
'xmlns:xsd="http://www.w3.org/2001/XMLSchema"'             
'xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">'
'   <soap:Body>'                                                                       
'      <GetWeather xmlns="http://www.webserviceX.NET">'    
'         <CityName>tokyo</CityName>'                                     
'         <CountryName>Japan</CountryName>'                       
'      </GetWeather>'                                                               
'   </soap:Body>'                                                                    
'</soap:Envelope>'                                                                
INTO #DOCUMENT                                                                  
*                                                                                             
#RC := *LENGTH(#DOCUMENT)                                              
*                                                                                             
REQUEST DOCUMENT FROM #FROM                                        
  WITH                                                                                     
    HEADER 'Content-Type' 'text/xml;charset=UTF-8'               
           'Content-Length' #RC                                                  
           'SOAPAction' 'http://www.webserviceX.NET/GetWeather' 
           'Request-method' 'POST'
    DATA ALL    #DOCUMENT       
    RETURN                                 
       HEADER ALL  #HEADER 
       PAGE #PAGE                            
       RESPONSE #RC                       
       GIVING #RETERR
*
WRITE #RC #RETERR 
END

Thanks, Woflgang, I’ll try it later on today. It looks good, and I’ll post how it goes.

I get this output:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/st
 <META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>??
 HTTP Error 400. The request has an invalid header name.</p>??</BODY></HTML>??  
HTTP/1.1 400 Bad Request?Content-Type: text/html; charset=us-ascii?Server: Micr
GMT?Connection: close?Content-Length: 339??                                     

I think the 400 isn’t really accurate, as when I commented out the last two headers, I still got the 400 error. When I comment out 3 headers, I get a 405 because it is doing a PUT. So, I think we’re closer, but not quite there.

REQUEST DOCUMENT FROM #FROM                                          
  WITH                                                               
    HEADER 'Content-Type'  'text/xml;charset=utf-8'                  
*          'Content-Length' #L                                       
*          'SOAPAction'    'http://www.webserviceX.NET/GetWeather'   
*          'Request-method' 'POST'                                   

One note:

I tried this from an OpenSystems Natural (Linux in that case), and it works as
posted, so yes, it can’t be much, but I can’t try from a mainframe Natural at
the moment.

I assume it’s an encoding issue, what’s your CP parameter setting ?

WRITE ‘=’ *CODEPAGE gives me this:

CODEPAGE: IBM01140
If it works on Linux, I think you’re right about the encoding. I’ll try a few things this morning.

I’d try changing it to

DATA ALL #DOCUMENT ENCODED CODEPAGE ‘UTF-8’

I tried that and still seem to get the 400 return code. I’ll continue to experiment.

REQUEST DOCUMENT FROM #FROM                                         
  WITH                                                              
    HEADER 'Content-Type'  'text/xml;charset=utf-8'                 
           'Content-Length' #L                                      
           'SOAPAction'    'http://www.webserviceX.NET/GetWeather'  
           'Request-method' 'POST'                                  
    DATA ALL    #DOCUMENT                                           
      ENCODED CODEPAGE 'UTF-8'                                      
  RETURN                                                            
   HEADER ALL             #HEADER                                   
   NAME 'Content-Type'    #DOC-CHARSET                              
  PAGE #PAGE                                                        
RESPONSE #RC                                                        
  GIVING #RTERR                                            

MORE
HTTP/1.1 400 Bad Request?Content-Type: text/html; charset=us-ascii?Server: Micr
GMT?Connection: close?Content-Length: 339??


HELLO AGAIN
??à|äèß&á?çè(<?&íâ<ñä?????ï?ä??àèà?çè(<???????á+??ÇÈÈø???ÏÏÏ?Ï???ÊÅ?èê?ÇÈ_%??ËÈ ?(áè ?çèè&?áéíñî??ä?>ÈÁ>È?è`øÁ??ä?>ÈÁ>È??ÈÁÌÈ?ÇÈ_%??ÄÇ/ÊËÁÈ?ÍË?/ËÄÑÑ???çá à???
çèè&?áÊÊ?Ê???èÇÁ?ÊÁÉÍÁËÈ?Ç/Ë?/>?Ñ>Î/%ÑÀ?ÇÁ/ÀÁÊ?>/_Á???ø???â|àß???çè(<???



CODEPAGE: IBM01140
BEFORE PARSE

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/st ??

HTTP Error 400. The request has an invalid header name.

????


YAHOO! I got it to return the weather info! Here is some of the code and the unparsed output. Thanks for all your help!

REQUEST DOCUMENT FROM #FROM                                             
   WITH                                                                  
     HEADER 'Content-Type'  'text/xml;charset=utf-8'                     
 *          'Content-Length' #L                                          
 *          'SOAPAction'    'http://www.webserviceX.NET/GetWeather'      
            'Request-method' 'POST'                                      
     DATA ALL    #DOCUMENT                                               
       ENCODED CODEPAGE 'UTF-8'                                          
   RETURN                                                                
    HEADER ALL             #HEADER                                       
    NAME 'Content-Type'    #DOC-CHARSET                                  
   PAGE #PAGE                                                            
 RESPONSE #RC                 

HELLO
#L: 425 #RC: 200

CODEPAGE: IBM01140                                                             
  BEFORE PARSE                                                                  
 <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas
 w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><s
 webserviceX.NET"><GetWeatherResult><?xml version="1.0" encoding="utf-16"?&gt
 International Airport, Japan (RJTT) 35-33N 139-47E 8M</Location>??  <T
 UTC</Time>??  <Wind> from the SSE (150 degrees) at 7 MPH (6 KT):0&l
 mile(s):0</Visibility>??  <SkyConditions> mostly cloudy</SkyCond
 Temperature>??  <DewPoint> 62 F (17 C)</DewPoint>??  <Relativ
 Pressure> 29.74 in. Hg (1007 hPa)</Pressure>??  <Status>Success&
 GetWeatherResult></GetWeatherResponse></soap:Body></soap:Envelope>             

Small warning !
I thought this was a good example and continued with parsing (- which you are probably already at?)
And this is not a walk in the park, since there are actually TWO xml documents, a soap envelope in UTF-8 and the actual weather report in UTF-16.
The natural parse statement tries to sort out the encoding but you will get some strange errors :frowning:

“3415 conversion result is truncated”
probably because of the 2byte UTF-16.

Haven’t figured out yet how to handle this smoothly :frowning:

Perhaps Wolfgang has some ideas ?
Finn

Just to confirm, this works for me on Linux as well, when I played with it I jumped between
400 & 415 errors so I stopped with a combination that finally worked :wink:

Still strange it doesn’t work the way I originally posted it, so there are probably subtle
differences at some layer.

Glad to see it works for you, finally, though !

Hello Finn,
When I use this to parse it,

ASSIGN #CP = *CODEPAGE                                     
MOVE ENCODED #PAGE TO #PAGE CODEPAGE #CP                   
WRITE ' BEFORE PARSE'                                      
PRINT #DISPLAY-DOC                                         
  / '_'(79)                                                
EJECT                                                      
PARSE XML #PAGE INTO PATH #PATH NAME #NAME VALUE #VALUE    
  PRINT #PATH / 'NAME=' #NAME / 'VALUE=' #VALUE / '_'(79)  
END-PARSE                                                  

I get the following. it just leaves the weather report all in one big glob. No errors reported, though. I am running on the mainframe.

soap:Envelope/soap:Body/GetWeatherResponse/GetWeatherResult/$                  
 NAME=                                                                          
 VALUE= <?xml version="1.0" encoding="utf-16"?>?<CurrentWeather>?  <Location>Tok
 47E 8M</Location>?  <Time>Jun 22, 2012 - 10:00 AM EDT / 2012.06.22 1400 UTC</Ti
 KT):0</Wind>?  <Visibility> greater than 7 mile(s):0</Visibility>?  <SkyConditi
 68 F (20 C)</Temperature>?  <DewPoint> 62 F (17 C)</DewPoint>?  <RelativeHumidi
 (1007 hPa)</Pressure>?  <Status>Success</Status>?</CurrentWeather>             

What happens when you add an ENCODED to the RETURN PAGE ?

Found a work-around - or actually two !
The problem appears to be that the content of the “GetWeatherResult” tag says it is utf-16, but in fact is just utf-8 !

So when Natural tries to parse it (as it should) as utf-16 you run into problems :frowning:
What I ghave done is to have two parse statements:
One for getting the “body” and one for parsing it after converting it with one of the options below:

  • Option 1 - change XML encoding-info in ?xml tag
    EXAMINE #PAGE2 FOR ‘utf-16’ REPLACE WITH ‘utf-8’

  • Option 2 make the actual encoding match the ?xml encoding-info
    MOVE ENCODED #PAGE2 CODEPAGE ‘utf-8’ TO #PAGE2 CODEPAGE ‘utf-16’

See full working example (for windows!) in the attachment.

Finn
PS After strugling a with this I googled “GetWeatherResult utf-8 utf-16” and found that I was not the first :wink:
WEATHER.txt (2.91 KB)

Thanks, Finn,

I’ve just posted a code sample with a working (cross-platform) example,
provided by R&D, I’m just waiting for the sample to get cleared by the admins
before I can refer to it here.

Synopsis:

  • ENCODING required on the REQUEST
  • avoid playing with encodings on the response and let Natural do the job

The code sample is   here

Any problems with it - please let me know !


Hi,

I found this thread for exactly what I was looking for. I tried the code on mainframes however I am getting runtime error ‘NAT0954 Abnormal termination AEY9 during program execution.’

Please can you help me with this, how to get a successful run of this program?

Thanks