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<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 : 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.
Partager