|
Invité de passage
 franck guindeuil Développeur informatique Inscription : novembre 2011 Messages : 2 Détails du profil  Informations personnelles : Nom :  franck guindeuil Localisation : France, Hauts de Seine (Île de France) Informations professionnelles :
Activité : Développeur informatique Secteur : Administration - Collectivité locale Informations forums :
Inscription : novembre 2011 Messages : 2 Points : 0 Points : 0
|
UTL_HTTP envoi de fichier via requete POST (HTTP500 - Stream ended unexpectedly)
J'obtiens l'erreur 500 Internal Server Error : Processing of multipart/form-data request failed. Stream ended unexpectedly quand j'envoie une requete POST sur un serveur apache tomcat 5.5 qui se trouve dans un autre service (je n'ai pas la main directement dessus)
L'objectif est d'envoyer un fichier KML (c'est un fichier XML)
J'aimerai savoir si mon code est bon et si ma requete http finale est bonne
et surtout pourquoi j'obtiens l'erreur (mon fichier fait un peu moins de 300Ko)
est ce que le problème peut venir du serveur sur lequel je n'ai pas la main? du genre maxPostSize? http://www.developpez.net/forums/d94...-unexpectedly/
voici ci dessous mon code
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
|
--
-- Envoi d'un KML dans l'extranet des consignations via POST
--
PROCEDURE Envoyer_KML
( pNomFic VARCHAR2
, pDirectoryId VARCHAR2
, pRecordId VARCHAR2
)
IS
vContenu VARCHAR2(4000); --contiendra le debut du contenu le content de la requete HTTP
vPostText CLOB;
vRequest UTL_HTTP.REQ;
vResponse UTL_HTTP.RESP;
vResponseText VARCHAR2(4000);
vErrorText VARCHAR2(2000);
vReponseWsOk VARCHAR2(7) :='{"Id":%';
vContentLenght integer:=0; --contiendra la taille de la requete HTTP
vLeBfile BFILE;
vLen NUMBER := dbms_lob.lobmaxsize;
vNum NUMBER ;
vSrc_off PLS_INTEGER := 1 ;
vDst_off PLS_INTEGER := 1 ;
vLangctx NUMBER := dbms_lob.default_lang_ctx ;
vWarn NUMBER;
nStart NUMBER := 1;
nEnd NUMBER := 32000;
nClobLength NUMBER;
vChunkData VARCHAR2(32000);
nLength NUMBER := 32000;
vFrontiere VARCHAR2(60) := 'FfGg0x75';
BEGIN
--*****************************************
--lecture du fichier dans un clob
--*****************************************
--creation du fichier temporaire
dbms_lob.createtemporary( vPostText, TRUE ) ;
--initialisation du clob au debut de la requete
vContenu := '--' || vFrontiere || CHR(13) || CHR(10) || 'content-disposition: form-data; name="directoryId"' || CHR(13) || CHR(10) || CHR(13) || CHR(10) || pDirectoryId || CHR(13) || CHR(10) ;
vContenu := vContenu || '--' || vFrontiere || CHR(13) || CHR(10) || 'content-disposition: form-data; name="recordId"' || CHR(13) || CHR(10) || CHR(13) || CHR(10) || pRecordId || CHR(13) || CHR(10) ;
vContenu := vContenu || '--' || vFrontiere || CHR(13) || CHR(10) || 'content-disposition: form-data; name="14"; filename="' || pNomFic || '"' || CHR(13) || CHR(10) ;
vContenu := vContenu || 'Content-Type: text/xml' || CHR(13) || CHR(10) ;
vContenu := vContenu || 'Content-Transfer-Encoding: UTF-8' || CHR(13) || CHR(10) || CHR(13) || CHR(10) ;
dbms_lob.WRITE(vPostText, LENGTH(vContenu), 1, vContenu);
--ouverture du fichier
vLeBfile := BFILENAME( 'KML_FILES', pNomFic );
dbms_lob.fileopen(vLeBfile, dbms_lob.file_readonly);
--reglage du debut de la destination à la fin du CLOB
vDst_off := LENGTH(vContenu)+1;
DBMS_LOB.LOADCLOBFROMFILE (
vPostText, -- CLOB de destination
vLeBfile, -- Pointeur fichier en entrée
vLen, -- Nombre d'octets à lire
vDst_off, -- Position destination de départ
vSrc_off, -- Position source de départ
dbms_lob.default_csid,-- CSID
vLangctx, -- Contexte langue
vWarn); -- Message d'avertissement
dbms_lob.fileclose(vLeBfile);
--écriture de la derniere frontiere (fin du fichier)
dbms_lob.writeappend(vPostText, length(vFrontiere)+4, '--' || vFrontiere || '--' );
--suppression des caractères accentués pour avoir une taille équivalente au nombre de caractères
--plus tard je compterai doubles ces caractères dans le content-lenght
vPostText := dfn_clobReplace(vPostText,'é','e');
vPostText := dfn_clobReplace(vPostText,'è','e');
vPostText := dfn_clobReplace(vPostText,'à','a');
vPostText := dfn_clobReplace(vPostText,'ô','o');
vPostText := dfn_clobReplace(vPostText,'ç','c');
vPostText := dfn_clobReplace(vPostText,'°','0');
DBMS_OUTPUT.PUT_LINE('Content lenght = ' || dbms_lob.getLength(vPostText));
--*****************************************
--envoi du fichier
--*****************************************
--réglage du proxy
utl_http.set_proxy(proxy=>ADRESSE_PROXY);
--création de l'objet requête
vRequest := UTL_HTTP.BEGIN_REQUEST
( url => ADRESSE_WS_KML
, METHOD => 'POST'
, http_version => 'HTTP/1.1'
);
--réglage de la requete au format UTF-8
UTL_HTTP.SET_BODY_CHARSET
(r => vRequest
,charset => CHARSET_EMISSION);
--le header Content-Type
UTL_HTTP.SET_HEADER
( r => vRequest
, NAME => 'Content-Type'
, VALUE => 'multipart/form-data, boundary=' || vFrontiere
);
--le header Content-Length
UTL_HTTP.SET_HEADER
( r => vRequest
, NAME => 'Content-Length'
, VALUE => (dbms_lob.getLength(vPostText)+1)
);
nClobLength := dbms_lob.getLength(vPostText);
--
--ecrire le corps de la requete en faisant une boucle
--
LOOP
IF nEnd > nClobLength then
nEnd := nClobLength;
nLength := nEnd - nStart+1;
end IF;
DBMS_OUTPUT.PUT_LINE ('nEnd:' || nEnd || ' nClobLength:' || nClobLength || ' nLength:' || nLength);
vChunkData := NULL;
vChunkData := DBMS_LOB.SUBSTR(vPostText, nLength, nStart);
UTL_HTTP.WRITE_TEXT ( vRequest, vChunkData );
DBMS_OUTPUT.PUT_LINE ( vChunkData );
IF nEnd = nClobLength then
exit;
end IF;
nStart := nEnd ;
nEnd := nStart + 32000;
END LOOP;
--envoi de la requete et récupération de la réponse
vResponse := UTL_HTTP.GET_RESPONSE(vRequest);
--*************************************************************
--analyse de la réponse
--*************************************************************
IF vResponse.status_code = STATUS_OK THEN
--reponse = OK
--la réponse est au format ISO-8859-1
UTL_HTTP.SET_BODY_CHARSET
(r => vResponse
,charset => CHARSET_RECEPTION);
--lire la réponse
UTL_HTTP.READ_TEXT(vResponse, vResponseText);
--si reponse NOK mettre son contenu dans la variable d'erreur
IF vResponseText NOT LIKE vReponseWsOk THEN
vErrorText := vResponseText;
DBMS_OUTPUT.PUT_LINE ('vResponseText NOT LIKE vReponseWsOk');
DBMS_OUTPUT.PUT_LINE (vResponseText || vResponse.status_code);
ELSE
DBMS_OUTPUT.PUT_LINE ('vResponseText LIKE vReponseWsOk');
END IF;
ELSE --reponse = NOK
--mettre le code et la raison dans la variable d'erreur
DBMS_OUTPUT.PUT_LINE ('status:'||vResponse.status_code||' reason:'||vResponse.reason_phrase);
vErrorText := 'status:'||vResponse.status_code||' reason:'||vResponse.reason_phrase;
END IF;
--fermer la réponse libérer les CLOB
UTL_HTTP.END_RESPONSE(vResponse);
dbms_lob.freetemporary(vPostText);
--si la variable d'erreur n'est pas vide : journaliser
IF vErrorText IS NOT NULL THEN
Pkg_Journal.INSERT_LOG_INTERNAL_ERROR (SQLCODE, 'création impossible de la consignation n°' || ' ErrorText=' || vErrorText, 'PKG_EXTRANET_DES_CONSIGNATIONS-Envoyer_KML');
END IF;
END Envoyer_KML; |
Voici ci dessous la reqete qui est vraiment envoyée : je l'ai récupérée de wireshark que j'ai installé sur le serveur de base de données
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
POST http://r55-signalement.rec.fin.URL/signalement/jsp/site/rest/directory/record/ HTTP/1.1
Host: r55-signalement.rec.fin.URL
Content-Type: multipart/form-DATA, boundary=FfGg0x75
Content-Length: 232040
Connection: close
--FfGg0x75
content-disposition: form-DATA; name="directoryId"
2
--FfGg0x75
content-disposition: form-DATA; name="recordId"
293
--FfGg0x75
content-disposition: form-DATA; name="14"; filename="consignations.kml"
Content-Type: text/xml
Content-Transfer-Encoding: UTF-8
<?xml version="1.0" encoding="utf-8" ?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document><Folder><name>consignation</name>
<Schema name="consignation" id="consignation">
<SimpleField name="Name" type="string"></SimpleField>
<SimpleField name="Description" type="string"></SimpleField>
<SimpleField name="NUM_CONSIGNATION" type="string"></SimpleField>
<SimpleField name="AFFICHAGE" type="string"></SimpleField>
</Schema>
<Placemark>
<name>Consignation n0 : 172434</name>
<description>Localisation : Intersection rue Rambuteau rue Mondetour<br />Date de debut : 2003/10/31 <br />Date de fin : 2010/01/01<br />Commentaire : </description>
<Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
<ExtendedData><SchemaData schemaUrl="#consignation">
<SimpleData name="NUM_CONSIGNATION">Consignation n0 : 172434</SimpleData>
<SimpleData name="AFFICHAGE">Localisation : Intersection rue Rambuteau rue Mondetour<br />Date de debut : 2003/10/31 <br />Date de fin : 2010/01/01<br />Commentaire : </SimpleData>
</SchemaData></ExtendedData>
<LineString><coordinates>2.348370159975013,48.862451839376206,43.198869185522199 2.348299417217526,48.862431612632072,43.19891501031816 2.348206598165612,48.862428483136988,43.198971983976662 2.347824984890921,48.862516288185496,43.199192680418491 2.347980158816752,48.862828231251981,43.199056162498891 2.348360837512066,48.862818023987202,43.198825596831739 2.348430759427624,48.862822162791609,43.198782439343631 2.348570473785997,48.862860188214363,43.198692202568054</coordinates></LineString>
</Placemark>
...150 placemarks entre les deux...
<Placemark>
<name>Consignation n0 : 410833</name>
<description>Localisation : test FG BR<br />Date de debut : 2011/10/28 <br />Date de fin : 2011/10/31<br />Commentaire : test FG BR</description>
<Style><LineStyle><color>ff0000ff</color></LineStyle><PolyStyle><fill>0</fill></PolyStyle></Style>
<ExtendedData><SchemaData schemaUrl="#consignation">
<SimpleData name="NUM_CONSIGNATION">Consignation n0 : 410833</SimpleData>
<SimpleData name="AFFICHAGE">Localisation : test FG BR<br />Date de debut : 2011/10/28 <br />Date de fin : 2011/10/31<br />Commentaire : test FG BR</SimpleData>
</SchemaData></ExtendedData>
<LineString><coordinates>2.329534197301053,48.827828272982103,43.215011136606336 2.330051766530076,48.827826148421778,43.214695536531508</coordinates></LineString>
</Placemark>
</Folder></Document></kml>
--FfGg0x75-- |
Voici ci dessous la réponse du serveur
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
HTTP/1.1 500 Internal Server Error
Via: 1.1 RES-DM-PXINT-S2
Connection: close
Proxy-Connection: close
Content-Length: 3021
Date: Tue, 22 Nov 2011 16:54:35 GMT
Content-Type: text/html;charset=utf-8
Server: Apache/2.0.52 (Red Hat)
<html><head><title>Apache Tomcat/5.5.23 - Error report</title><style><!--H1 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:22px;} H2 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:16px;} H3 {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;font-size:14px;} BODY {font-family:Tahoma,Arial,sans-serif;color:black;background-color:white;} B {font-family:Tahoma,Arial,sans-serif;color:white;background-color:#525D76;} P {font-family:Tahoma,Arial,sans-serif;background:white;color:black;font-size:12px;}A {color : black;}A.name {color : black;}HR {color : #525D76;}--></style> </head><body><h1>HTTP Status 500 - </h1><HR size="1" noshade="noshade"><p><b>type</b> Exception report</p><p><b>message</b> <u></u></p><p><b>description</b> <u>The server encountered an internal error () that prevented it from fulfilling this request.</u></p><p><b>exception</b> <pre>javax.servlet.ServletException: Unkown error occured during the upload
Debut.URL.portal.web.upload.UploadFilter.doFilter(UploadFilter.java:218)
Debut.URL.portal.web.upload.DosGuardFilter.doFilter(DosGuardFilter.java:126)
Debut.URL.portal.web.encoding.EncodingFilter.doFilter(EncodingFilter.java:86)
</pre></p><p><b>root cause</b> <pre>org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-DATA request failed. Stream ended unexpectedly
org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:371)
org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
Debut.URL.portal.web.upload.UploadFilter.doFilter(UploadFilter.java:157)
Debut.URL.portal.web.upload.DosGuardFilter.doFilter(DosGuardFilter.java:126)
Debut.URL.portal.web.encoding.EncodingFilter.doFilter(EncodingFilter.java:86)
</pre></p><p><b>root cause</b> <pre>org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:982)
org.apache.commons.fileupload.MultipartStream$ItemInputStream.READ(MultipartStream.java:886)
java.io.InputStream.READ(InputStream.java:89)
org.apache.commons.fileupload.util.Streams.copy(Streams.java:96)
org.apache.commons.fileupload.util.Streams.copy(Streams.java:66)
org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:366)
org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:126)
Debut.URL.portal.web.upload.UploadFilter.doFilter(UploadFilter.java:157)
Debut.URL.portal.web.upload.DosGuardFilter.doFilter(DosGuardFilter.java:126)
Debut.URL.portal.web.encoding.EncodingFilter.doFilter(EncodingFilter.java:86)
</pre></p><p><b>note</b> <u>The full stack trace of the root cause IS available IN the Apache Tomcat/5.5.23 logs.</u></p><HR size="1" noshade="noshade"><h3>Apache Tomcat/5.5.23</h3></body></html> |
Mais en fait je me pose une question qui est peut être plus importante :
Est ce une bonne architecture? sachant que la demande initiale indique que l'envoi du fichier doit se faire sur un clic de souris dans une application. Ce qui entrainerai que la procédure serait appelée sur un trigger (create, update ou delete).
Faire tout ceci via un trigger : cela me heurte un peu quelque part...
Peut être qu'une autre solution serait de
-1- mettre à jour une valeur dans la base à chaque create, update ou delete
-2- faire un job qui crée le fichier et l'envoie (le job tournerai tous les quarts d'heure)
D'avance merci pour l'aide que vous pourrez m'apporter.
|