En V6R1, et de manière intégrée au système d'exploitation, nous avons des mécanismes pour accéder à un service web depuis le langage RPG (entre autre).
on dit "consommer un service web"...
L'exemple (SOAP) fourni par IBM est basé sur le service ConvertTemp automatiquement créé lors de la création du serveur d'application
Allez sur la page
Si vous le testez, vous voyez (remarquez le paramètre param0, qui est une structure composée d'une seule zone _TEMPIN) :
ATTENTION,
sur les dernières versions du serveur de web services les noms des
variables ne sont plus précédés de "_", sauf à indiquer enabled ici : (en cas de doute, vérifiez le fichier .wsdl) |
Utilisation en PHP
Débug :
<?php $client = new SoapClient("http://AS400S:10030/web/services/ConvertTemp?wsdl"); |
Résultat :
>
Pour accéder à la valeur
<?php $client = new SoapClient("http://AS400S:10030/web/services/ConvertTemp?wsdl"); |
Si vous retournez un DS à occurrences -> DIM(xx) , tenez en compte dans votre code
Démo avec notre exemple retournant une DS INFOCENTRE à NBPROD occurrences
affiche
en .NET
Après avoir ajouté une référence web dont l'URL est "http://AS400:10030/web/services/ConvertTemp?wsdl"
Dim wsTemp As New AS400_Temperature.ConvertTemp |
Par exemple sur l'événement "click" d'un bouton cmdOK (ici libellé Go)
Protected Sub cmdOK_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim wsTemp As New AS400_Temperature.ConvertTemp
Dim input As New AS400_Temperature.CONVERTTEMPInput
If txtF.text <> "" Then
input._TEMPIN = txtF.text
lblC.Text = wsTemp.converttemp_XML(input)
End If
End Sub
Résultat
Enfin, en RPG :
1/ récupérez le fichier de définition (WSDL) en cliquant
sur View definition
(sinon, pour celui-ci uniquement , il est déja
présent dans /QIBM/ProdData/OS/WebServices/V1/client)
2 / il faut générer le "stub" soit le programme "proxy" faisant l'interface entre Axis et notre RPG.
pour cela nous utiliserons l'outil WSDL2WS.SH sous shell (STRQSH)
> /QIBM/ProdData/OS/WebServices/V1/Client/bin/wsdl2ws.sh |
Si vous passez la commande ls, vous devez voir :
$ |
L'utilisation de ces sources C en RPG était assez complexe.
En début 2011 les PTF suivantes SI42234 (V5R40) , SI42236 (V6R10) , SI42235 (v7) apportent un nouvel utilitaire wsdl2rpg
comme le précédent, il se trouve dans QIBM/ProdData/OS/WebServices/V1/Client/bin/
> /QIBM/ProdData/OS/WebServices/V1/Client/bin/wsdl2rpg.sh |
L'option -s demande la création d'un programme de service dans la bibliothèque MABIB.
Cette fois il génère aussi du RPG, soit 6 fichiers en plus, portant le nom du service (Avant ConvertTempPortType, maintenant ConvertTempServices)
ConvertTempServices.CL | le CL de création du *SRVPGM |
ConvertTempServices.rpgleinc | fichier à inclure (dans votre programme) |
ConvertTempServices.rpgle | le code d'invoquation du web service (*SRVPGM) |
ConvertTempServices_util.rpgleinc | fichier à inclure (dans le source suivant) |
ConvertTempServices_util.rpgle | divers utilitaires |
ConvertTempServices__xsdtypes.rpgleinc | différents types de données standards |
le fichier de référence est le xxxxxxxx.Services.rpgleinc (ConvertTempServices.rpgleinc)
où xxxxxxxx représentant le nom du service tel que défini dans "http://AS400S:10030/web/services/xxxxxxxx?wsdl"
qui contient les définitions dont vous avez besoin, et qu'il faut inclure dans votre code :
Pour faire en RPG l'équivalent du test suivant (sur ConvertTemp) :
Ecrivez
Remarquez dans la fenêtre structure, le prototype pour l'opération (suite au /copy)
les paramètres sont en fait des DS possédant deux sous-zones significatives
Dernier point, vous devez linker tout ce petit monde, par :
.Essayons le pgm :
Cette version de l'utilitaire, permet un code RPG relativement simple plus lisible que le source généré en C par wsdl2ws.
Par exemple celui-ci attend des paramètres plus simples (voyez le .wsdl)
ce qui génère (par wsdl2rpg)
le code suivant est cohérent (et fonctionne) :
Enfin, si vous devez travailler en HTTPS (avec un certificat)
/copy /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc |
Si vous recevez HTTPTransportException: HTTPS transport error.GSKit Error is 428 - No certificate is available for SSL processing.
ne mettez rien en 3eme paramètre (remplacez motdepasse par une chaine vide)
Si vous avez des temps de réponses particulièrement longs, utilisez axiscStubSetTransportConnectTimeout(handle, nb-de-secondes)
Si vous rencontrez des problèmes, lancez une trace par axiscAxisStartTrace(’/tmp/axis.log’:*NULL) en début de pgm.
( axiscAxisStopTrace permet d'arrêter la trace)
Pour vous sortir à l'aide d'un proxy
/copy /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc |
Pour un accès avec authentification
/copy /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc |
tous les détails sur ces API : http://www-03.ibm.com/systems/resources/systems_i_software_iws_pdf_WebServicesClient_new.pdf
Enfin, depuis SF99368 Level 52, SF99713 Level 26, SF99722 Level 13 (Décembre 2017), nos pouvons récupérer les erreurs SOAP générées par le serveur
Exemple
SoapFault = axiscStubGetSOAPFault(WsStub.handle) ; |
RPG toujours, pour les web services REST, IBM propose (Mai 2016) d'utiliser directement les API Axis (alternative aux fonctions httpgetblob/clob)
il vous faut :
7.3: SI60805, SI60808
7.2: SI60806, SI60809
7.1: SI60807, SI60810
Avec,
7.3 : SI63730,
SI63759
7.2 :
SI63729,
SI63760
7.1 : SI63727,
SI63761
Exemple général
**free /COPY /QIBM/ProdData/OS/WebServices/V1/client/include/Axis.rpgleinc DCL-S rc INT(10); DCL-S uri CHAR(200); // --------------------------------------------------------------------
// Déconnexion. *INLR=*ON; // code des procédures extrait de developerWorks dcl-pr printf extproc(*dclcase); dcl-c NEWLINE CONST(x'15'); printf(%TRIM(msg) + NEWLINE); // ========================================= DCL-S axisCode INT(10); axisCode = axiscTransportGetLastErrorCode(tHandle); if (axisCode = EXC_TRANSPORT_HTTP_EXCEPTION); // ========================================= DCL-S header POINTER; clear response; // Flush data so request is sent // Receive data and print out data and response to stdout if (rc = -1); if (rc > -1); END-PROC; |
Voyez nos différentes solutions pour lire du JSON : http://www.volubis.fr/freeware/READJSON.html
httpGetBlobhttpGetClobhttpPutBlobhttpPutClobhttpPostBlobhttpPostClobhttpDeleteBlobhttpDeleteClobhttpBlobhttpClobhttpHead- UrlEncode
UrlDecode
base64Encode
base64Decode
Le but de ces fonctions est de consommer des services web plutôt orientés REST, revenant aux fondamentaux du protocole HTTP
Regardons à travers des exemplesValues SYSTOOLS.HTTPGETCLOB('http://www.volubis.fr' ,'') ;
Récupère dans une variable le contenu de notre page d'accueil
![]()
Pour les fonctions HTTPPOSTBLOB|CLOB et HTTPPUTBLOB|CLOB, il y un troisième paramètre: les données à transmettre
(avec GET les paramètres sont dans l'URL)Pour une page web "classique" , par formulaire
->
Voyez cet extrait de code
(pensez simplement à indiquer le type de contenu formulaire : "x-www-form-urlencoded" pour simuler un formulaire)
-- Appel d'une page PHP (normalement un formulaire avec "prenom")
Values SYSTOOLS.HTTPPOSTCLOB('http://as400/php/exemples/tp/tp0.php' ,
CAST ('<httpHeader>
<header name="Content-Type" value="application/x-www-form-urlencoded"/>
</httpHeader>' AS CLOB(1K)),
CAST('prenom=christian' AS CLOB(10K)) )
Si le site retourne du XML, l'utilisation de la fonction XMLTABLE permettra de ne recevoir que les données utiles
Sur la base d'un web service ayant cette enveloppe SOAP
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soap="http://soapprd.wsbeans.iseries/">
<soapenv:Header/>
<soapenv:Body>
<soap:getprd>
<arg0>
<CODE>2</CODE>
</arg0>
</soap:getprd>
</soapenv:Body>
</soapenv:Envelope>ET retournant celle ci
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:getprdResponse xmlns:ns2="http://soapprd.wsbeans.iseries/">
<return>
<RETOUR>
<PR_CODE>2</PR_CODE>
<PR_NOM>Château Maucaillou</PR_NOM>
<PR_ADRESSE>Quartier de la Gare</PR_ADRESSE>
<PR_CDPST>33480</PR_CDPST>
<PR_COMMUNE>Moulis-en-Médoc</PR_COMMUNE>
<PR_TEL>05 56 58 01 23</PR_TEL>
<PR_FAX>05 56 58 00 88</PR_FAX>
<PR_VENTE>oui</PR_VENTE>
<PR_VISITE>oui</PR_VISITE>
<APPEL_CODE>182</APPEL_CODE>
</RETOUR>
</return>
</ns2:getprdResponse>
</soap:Body>
</soap:Envelope>![]()
SELECT*
FROM XMLTABLE('$result/*:Envelope/*:Body/*:getprdResponse/*:return'
PASSING XMLPARSE(
DOCUMENT
SYSTOOLS.HTTPPOSTCLOB('http://as400:10025/web/services/SOAPPRDService/SOAPPRD', NULL,
CAST('<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:soap="http://soapprd.wsbeans.iseries/">
<soapenv:Header/>
<soapenv:Body>
<soap:getprd>
<arg0>
<CODE>2</CODE>
</arg0>
</soap:getprd>
</soapenv:Body>
</soapenv:Envelope>' AS CLOB(10K)) )
) as "result"
COLUMNS
NOM CHAR(30) PATH '*:RETOUR/*:PR_NOM',
VILLE CHAR(50) PATH ' *:RETOUR/*:PR_COMMUNE',
TEL CHAR(20) PATH ' *:RETOUR/*:PR_TEL'
) AS TABLEXML;
Sur la base d'un service ( http://www.webservicex.net/stockquote.asmx?WSDL) plus complexe :
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://www.webserviceX.NET/">
<soapenv:Header/>
<soapenv:Body>
<web:GetQuote>
<web:symbol>IBM</web:symbol>
</web:GetQuote>
</soapenv:Body>
</soapenv:Envelope>
Appel d'un Web service, utilisation du deuxième paramètre permettant de fournir les entêtes http,
le troisième contenant la demande(body), soit l'enveloppe SOAP.
(ici, nous demandons la valeur de l'action IBM à aujourd'hui dans une enveloppe SOAP)
-- Appel d'un web service , récupération de l'enveloppe SOAP réponse dans une variable
VALUES SYSTOOLS.HTTPPOSTCLOB('http://www.webservicex.net//stockquote.asmx',
CAST ('<httpHeader>
<header name="Content-Type" value="text/xml;charset=utf-8"/>
<header name="SOAPAction" value=""http://www.webserviceX.NET/GetQuote""/>
</httpHeader>' AS CLOB(1K)),
CAST('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetQuote xmlns="http://www.webserviceX.NET/">
<symbol>IBM</symbol>
</GetQuote>
</soap:Body>
</soap:Envelope>' AS CLOB(10K)) ) ;![]()
SoapUI nous montre l'enveloppe Soap en sortie, comme ceci :
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetQuoteResponse xmlns="http://www.webserviceX.NET/">
<GetQuoteResult><![CDATA[
<StockQuotes><Stock> <Symbol>IBM</Symbol><Last>182.46</Last><Date>11/14/2013</Date>
<Time>12:08pm</Time><Change>-1.09</Change><Open>180.63</Open><High>182.90</High><Low>179.66</Low>
<Volume>3474990</Volume><MktCap>198.1B</MktCap><PreviousClose>183.55</PreviousClose>
<PercentageChange>-0.59%</PercentageChange><AnnRange>172.57 - 215.90</AnnRange><Earns>14.439</Earns>
<P-E>12.71</P-E><Name>International Bus</Name></Stock></StockQuotes>
]]>
</GetQuoteResult>
</GetQuoteResponse>
</soap:Body>
</soap:Envelope>-- Appel d'un web service , récupération de l'enveloppe SOAP, "parsée"
-- il y a des espaces de nommage (xmlns) SOAP et d'autres propres au web service, d'où -> *:
-- les données extraites sont elle-même au format XML (on voit que l'action est à 210 $ 55 )
SELECT*
FROM XMLTABLE('$result/*:Envelope/*:Body/*:GetQuoteResponse'
PASSING XMLPARSE(
DOCUMENT
SYSTOOLS.HTTPPOSTCLOB('http://www.webservicex.net//stockquote.asmx',
CAST ('<httpHeader>
<header name="Content-Type" value="text/xml;charset=utf-8"/>
<header name="SOAPAction" value=""http://www.webserviceX.NET/GetQuote""/>
</httpHeader>' AS CLOB(1K)),
CAST('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetQuote xmlns="http://www.webserviceX.NET/">
<symbol>IBM</symbol>
</GetQuote>
</soap:Body>
</soap:Envelope>' AS CLOB(10K)) )
) as "result"
COLUMNS
resultat VARCHAR(2000) PATH '*:GetQuoteResult'
) AS TABLEXML;
-- Appel d'un web service , récupération de l'enveloppe SOAP, "parsée" pour lire le montant de l'action
-- puis découpage du XML extrait (présent dans CDATA[ ] ) à nouveau par la fonction XMLTABLE
<![CDATA[ <StockQuotes> <Stock><Symbol>IBM</Symbol><Last>182.46</Last><Date>11/14/2013</Date>
<Time>12:08pm</Time><Change>-1.09</Change><Open>180.63</Open><High>182.90</High><Low>179.66</Low>
<Volume>3474990</Volume><MktCap>198.1B</MktCap><PreviousClose>183.55</PreviousClose>
<PercentageChange>-0.59%</PercentageChange><AnnRange>172.57 - 215.90</AnnRange><Earns>14.439</Earns>
<P-E>12.71</P-E><Name>International Bus</Name></Stock>
</StockQuotes>
]]>WITH temp as (SELECT resultat
FROM XMLTABLE('$result/*:Envelope/*:Body/*:GetQuoteResponse'
PASSING XMLPARSE(
DOCUMENT
SYSTOOLS.HTTPPOSTCLOB('http://www.webservicex.net//stockquote.asmx',
CAST ('<httpHeader>
<header name="Content-Type" value="text/xml;charset=utf-8"/>
<header name="SOAPAction" value=""http://www.webserviceX.NET/GetQuote""/>
</httpHeader>' AS CLOB(1K)),
CAST('<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetQuote xmlns="http://www.webserviceX.NET/">
<symbol>IBM</symbol>
</GetQuote>
</soap:Body>
</soap:Envelope>' AS CLOB(10K)) )
) as "result"
COLUMNS
resultat VARCHAR(2000) PATH '*:GetQuoteResult'
) AS TABLEXML
)select * from temp,
XMLTABLE ('$c/StockQuotes/Stock' passing XMLPARSE(DOCUMENT RESULTAT) as "c"
COLUMNS
symbol CHAR(30) PATH 'Symbol',
prix dec(11, 2 ) PATH 'Last'
) AS X ;![]()
Pour un service web REST retournant du XML, c'est plus simple
conjuguons à nouveau HTTPGETBLOB et XMLTABLE
SELECT*
FROM XMLTABLE('$result/lstprodResult/RETOUR'
PASSING XMLPARSE(
DOCUMENT
SYSTOOLS.HTTPGETBLOB('http://as400:10042/web/services/LSTPRODR/suivant/25', '')
) as "result"COLUMNS
nom VARCHAR(50) PATH 'PR_NOM' ,
tel varchar(20) PATH 'PR_TEL',
nbvins dec(3, 0) PATH'NBVIN',
cepage char(20) PATH 'CEPAGE'
) AS TABLEXML;Si le service retourne du JSON
EN PHP
![]()
Résultat
![]()
AVANT TR1(7.3)/TR5(7.2), voyez l'utilitaire XML2JSON / JSON2XML
(http://www.mcpressonline.com/programming/techtip-json-and-xml-conversion-in-db2-for-i.html)
![]()
Depuis TR1 (7.3) TR5(7.2) une fonction JSON_TABLE est intégrée à SQL
JSON_TABLE(
JSON_SOURCE
JSON_PATH
COLUMNS
nom type PATH 'json_path',
...
) as X
- JSON_SOURCE
Flux JSON, peut-être
- une variable
- une colonne base de données (JSON ou BSON)
- un flux (HTTPGETCLOB, par exemple)
- JSON_PATH
- $ : objet en cours
- . : élément dans l'objet en cours
- [ ] : élément dans un tableau
- un_nom : la valeur de l'élément
- COLUMNS
Comme avec XMLTABLE il s'agit de "fabriquer" des pseudo-colonnes base de données, indiquez :
- un nom de colonne
- un type : CHAR(x) , DEC(x , y), etc...
- PATH
- une règle d'utilisation
- lax, utilisation souple
- on peut faire référence un élément, même quand c'est un tableau, l'itération est alors automatique
- on peut faire référence à un tableau, même quand c'est un élément
- les cas impossible génèrent valeur nulle
- strict, utilisation stricte, les cas prédédents génèrent une erreur
- L'élément JSON dont il faut extraire la valeur
- (options)
- NULL ON EMPTY
retourne valeur nulle sur un élément manquant
- ERROR ON EMPTY
retourne une erreur sur un élément manquant
- DEFAULT <une-valeur> ON EMPTY
retourne une valeur par défaut sur un élément manquant
- ERROR ON ERROR
retourne une erreur en cas d'erreur (SQL16410)
- DEFAULT <une-valeur> ON ERROR
retourne une valeur par défaut suite à une erreur
Par exemple avec ce flux
{
"id" : 901,
"name" : { "first":"John", "last":"Doe" },
"phones" : [{"type":"home", "number":"555-3762"},
{"type":"work", "number":"555-7252"}]
}'
COLUMNS(
id VARCHAR(10) PATH 'lax $.id',
first VARCHAR(10) PATH 'lax $.name.first',
last VARCHAR(10) PATH 'lax $.name.last' )
Avec XMLTABLE, si nous avons plusieurs téléphones, vous pouvez->ne recevoir que la(les) première(s) valeur(s)
Ecrivez
SELECT X.nom ,x.rue, x.ville, x.TEL
FROM posample/Customer,
XMLTABLE (
XMLNAMESPACES(DEFAULT 'http://posample.org'),
'$c/customerinfo' passing INFO as "c"
COLUMNS
NOM CHAR(30) PATH 'name',
RUE VARCHAR(25) PATH 'addr/street',
VILLE VARCHAR(25) PATH 'addr/city',
TEL char(10) PATH 'phone[1]'
) AS X
JSON_TABLE, propose une syntaxe approchante :
- -> retourner chaque téléphone avec la syntaxe suivante
SELECT X.nom ,x.rue, x.ville, x.TELNESTED avec JSON_TABLE
FROM posample.Customer,
XMLTABLE (
XMLNAMESPACES(DEFAULT 'http://posample.org'),
'$c/customerinfo/phone' passing INFO as "c"
COLUMNS
NOM CHAR(30) PATH '../name',
RUE VARCHAR(25) PATH '../addr/street',
VILLE VARCHAR(25) PATH '../addr/city',
TEL char(20) PATH '.'
) AS X
- Enfin comme avec XMLTABLE, vous pouvez récupérer la totalité des téléphones, dans un flux
->retourner la totalité des téléphones sous forme XML
SELECT X.nom ,x.rue, x.ville, x.TEL
FROM posample/Customer,
XMLTABLE (
XMLNAMESPACES(DEFAULT 'http://posample.org'),
'$c/customerinfo' passing INFO as "c"
COLUMNS
NOM CHAR(30) PATH 'name',
RUE VARCHAR(25) PATH 'addr/street',
VILLE VARCHAR(25) PATH 'addr/city',
TEL XML PATH 'phone'
) AS X
Sur le résultat d'un Web service REST
Avec des données OpenData de la ville de Nantes (voir http://data.nantes.fr)
(le deuxième caractère, optionnel est un code page)
par ex , pour passer l'authentification à un serveur HTTP, dans les entêtes (second paramètre des fonctions HTPPxxxxxxx)
<header name="Authorization" value="Basic bmljazpwYXNzdzByZA=="/> par exemple '<header name="Authorization" value="Basic ' CONCAT |
httpGetBlobVerbosehttpGetClobVerbosehttpPutBlobVerbosehttpPutClobVerbosehttpPostBlobVerbosehttpPostClobVerbosehttpDeleteBlobVerbosehttpDeleteClobVerbosehttpBlobVerbosehttpClobVerbosehttpHeadVerbose
qui s'utilisent comme çawith temp as (
select responsemsg as msg , responsehttpheader as header
from table( systools.httpgetclobverbose('http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml' ,'')) as E)select code, monnaie, taux from temp CROSS JOIN
xmltable('$r/httpHeader' passing xmlparse(DOCUMENT header) as "r"
COLUMNS
code char(25) PATH '@responseCode',
message char(25) PATH 'responseMessage'
) as x
CROSS JOIN
xmltable('$m/*:Envelope/*:Cube/*:Cube/*:Cube' passing xmlparse(DOCUMENT msg) as "m"
COLUMNS
monnaie char(3) PATH '@currency',
taux dec(11, 7) PATH '@rate'
) as y
- Pour les fonctions tables (verbeuses)
- Si la réponse du serveur n'est pas success vous recevez SQLSTATE 01H52 (Warning)
- Si le serveur ne peut être contacté SQLSTATE 38000
avec ce code vous aurez les messages d'erreur dans RESPONSEMSG
select * from table(
systools.httpgetclobverbose('http://www.w3.org/notfound.html', '<httpHeader includeErrorMsg="true"/>'))- Pour les fonctions scalaires (non verbeuses, vous recevez simplement SQLSTATE 38000 en cas d'erreur
- Pour débugger, ajoutez un variable d'environnement
ADDENVVAR ENVVAR(QIBM_COMPONENT_TRACE_LEVEL)
VALUE('SQJAVA,VERBOSE')
- lancez la fonction de SYSTOOLS
- tapez DMPUSRTRC
certains site imposent une version de SSL (Erreur : Received fatal alert: handshake_failure)
Créez la fonction suivante :
CREATE FUNCTION SYSTOOLS.setProperty(PROPERTY VARCHAR(80), VALUE VARCHAR(80))
RETURNS VARCHAR(80)
LANGUAGE JAVA
PARAMETER STYLE JAVA
EXTERNAL NAME 'java.lang.System.setProperty'
saisissezVALUES SYSTOOLS.setproperty('com.ibm.jsse2.overrideDefaultProtocol','TLSv12')
Les certificats sont enregistrés dans un magasin de certificats (keystore)
le magasin pour java, par défaut, est lié à la JVM :
/QOpenSys/QIBM/ProdData/JavaVM/jdk70/32bit/jre/lib/security/cacerts par exemple
pour être certain, retrouver votre job par WRKJVMJOB (option 5)
puis 2. Display environment variables et cherchez JAVA_HOME
par exemple le site de la métropole de Nantes provoque SQL4302, certificat not trusted
![]()
regardons le détail pour ce certificat
affichez le certificat pour l'authorité de certification DST Root CA X3
![]()
Sauvegardez le au format DER, transferez le sur l'IBM i
![]()
il faut ensuite l'importer par keytool -import
![]()
saisissez le mot de passe du magasin (le mot de passe est normalement "changeit"), et acceptez par oui
ainsi que le certificat intermédiaire
![]()
Vérifions par keytool -list
![]()
![]()
pour ces dernières options, concernant l'accès HTTPS, voyez aussi notre cours SSLVous pouvez mettre des options à java, en créant un fichier d'options
-Xmx Mémoire pour java (par exemple -Xmx2g -> 2 Go) http.proxyHost Coordonnées du Proxy http.proxyPort port du proxy (80 par défaut) http.proxyUser Utilisateur pour proxy http.proxyPassword Mot de passe pour proxy http.nonProxyHosts Liste des serveurs pour lesquels ne pas utiliser le proxy javax.net.ssl.trustStore emplacement du fichier contenant la liste des certificats des sites de confiance javax.net.ssl.trustStorePassword mot de passe pour ouvrir le fichier trustStore javax.net.ssl.keyStore emplacement du fichier contenant la liste des certificats et des clés privées (keystore) javax.net.ssl.keyStorePassword mot de passe pour ouvrir le fichier keyStore
Le fichier de propriétés java peut être indiqué comme suit :
- en créant une variable d'environnement indiquant sa localisation
ADDENVVAR ENVVAR(QIBM_JAVA_PROPERTIES_FILE)
VALUE(/QIBM/userdata/java400/mySystem.properties)- en créant un fichier SystemDefault.properties dans la home directory de l'utilisateur
- en créant un fichier SystemDefault.properties dans /QIBM/userdata/java400/
Copyright © 2017 VOLUBIS