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 : Sélectionner tout - Visualiser dans une fenêtre à part
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 : Sélectionner tout - Visualiser dans une fenêtre à part
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&lt;br /&gt;Date de debut : 2003/10/31 &lt;br /&gt;Date de fin : 2010/01/01&lt;br /&gt;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&lt;br /&gt;Date de debut : 2003/10/31 &lt;br /&gt;Date de fin : 2010/01/01&lt;br /&gt;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&lt;br /&gt;Date de debut : 2011/10/28 &lt;br /&gt;Date de fin : 2011/10/31&lt;br /&gt;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&lt;br /&gt;Date de debut : 2011/10/28 &lt;br /&gt;Date de fin : 2011/10/31&lt;br /&gt;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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.