java - tutorial - No se puede enviar una solicitud multiparte/mixta al servicio REST de Spring basado en MVC
spring rest tutorial (3)
Tengo un servicio REST basado en Spring MVC y Resteasy que necesito probar enviando una solicitud multiparte / mixta.
El servicio está codificado de la siguiente manera:
@POST
@Path("/mixedMimeText")
@Consumes("multipart/mixed")
@ResponseStatus(HttpStatus.OK)
public String createMime(@Context ServletContext servletContext, MultipartInput input) throws Exception, IOException {
logger.info("Processing /mixedMimeText");
for(InputPart p : input.getParts()){
logger.info("Headers : " + p.getHeaders());
logger.info("MediaType : " + p.getMediaType());
logger.info("Body : " + p.getBodyAsString());
logger.info("--------------------------------------------------- ");
}
return "TEST";
}
Estoy usando el siguiente archivo para enviar como contenido mime multiparte
--ABC123Boundary
Content-Type: text/xml
<?xml version="1.0" ?>
<request>
<account-id>XXXX-XXXX-XXXX-XXXX</account-id>
<reference>12345</reference>
<app-name>XXXXXXXXX</app-name>
<information>
<calling-party>
<name>Joe Bloggs</name>
<identifier>441234567890</identifier>
</calling-party>
<called-party>
<name>John Smith</name>
<identifier>15551234567</identifier>
</called-party>
</information>
</request>
--ABC123Boundary
Content-Type: text/xml
UklGRkBAAABXQVZFZm10IBAAAAAHAAEAQB8AAEAfAAABAAgAZmFjdAQAAAAPQ
AAAZGF0YRBAAABn5///////////////5///Z+fn///n////////5////////2f//2f//+f//+f////n/
///////52f//////2f//////2f/////5////////+f/////Z+f///////////////9n//9nZ/9n////5+f///9
<snip>
//+f//////2f/////////5//n//////////9n
--ABC123Boundary--
Estoy enviando la solicitud usando el cliente curl con el siguiente comando:
curl -X POST http://localhost:8080/MyRestServices/restportal/services/mixedMimeText -i -H "Content-Type: multipart/mixed; boundary="--ABC123Boundary" -T myfile.txt
La solicitud llega al servicio, pero todo lo que veo en el terminal JBOSS es que produce el siguiente error, que en realidad no tiene sentido. No hay trazas de pila ni ningún otro error.
21:48:37,174 WARN [org.apache.james.mime4j.parser.MimeEntity] (http--127.0.0.1-8080-1) Unexpected end of headers detected. Higher level boundary detected or EOF reached.
21:48:37,175 WARN [org.apache.james.mime4j.parser.MimeEntity] (http--127.0.0.1-8080-1) Invalid header encountered
21:48:37,176 WARN [org.apache.james.mime4j.parser.MimeEntity] (http--127.0.0.1-8080-1) Body part ended prematurely. Boundary detected in header or EOF reached.
Parece que hay algo mal con el contenido, pero no estoy seguro.
Editar
@Perception - Cambié el comando de la siguiente manera pero sigue produciendo el mismo error
curl http://localhost:8080/MyRestServices/restportal/services/mixedMimeText --data-binary @myfile.txt -X POST -i -H "Content-Type: multipart/mixed; boundary=--ABC123Boundary"
Me pregunto si la estructura MultipartInput espera que el contenido tenga un formato diferente.
Editar
Parece que los datos que se envían son correctos. Aquí está la salida cuando ejecuto el comando usando la opción --trace
curl http://localhost:8080/MyRestServices/restportal/services/mixedMimeText --data-binary @myfile.txt -X POST -i -H "Content-Type: multipart/mixed; boundary=--ABC123Boundary" --trace trace.txt
Salida de traza
== Info: About to connect() to localhost port 8080 (#0)
== Info: Trying 127.0.0.1...
== Info: connected
== Info: Connected to localhost (127.0.0.1) port 8080 (#0)
=> Send header, 243 bytes (0xf3)
0000: 50 4f 53 54 20 2f 4d 73 6d 52 65 73 74 53 65 72 POST /MyRestSer
0010: 76 69 63 65 73 2f 72 65 73 74 2f 73 65 72 76 69 vices/rest/servi
0020: 63 65 73 2f 6d 69 78 65 64 4d 69 6d 65 54 65 78 ces/mixedMimeTex
0030: 74 20 48 54 54 50 2f 31 2e 31 0d 0a 55 73 65 72 t HTTP/1.1..User
0040: 2d 41 67 65 6e 74 3a 20 63 75 72 6c 2f 37 2e 32 -Agent: curl/7.2
0050: 34 2e 30 20 28 69 33 38 36 2d 70 63 2d 77 69 6e 4.0 (i386-pc-win
0060: 33 32 29 20 6c 69 62 63 75 72 6c 2f 37 2e 32 34 32) libcurl/7.24
0070: 2e 30 20 7a 6c 69 62 2f 31 2e 32 2e 35 0d 0a 48 .0 zlib/1.2.5..H
0080: 6f 73 74 3a 20 6c 6f 63 61 6c 68 6f 73 74 3a 38 ost: localhost:8
0090: 30 38 30 0d 0a 41 63 63 65 70 74 3a 20 2a 2f 2a 080..Accept: */*
00a0: 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 ..Content-Type:
00b0: 6d 75 6c 74 69 70 61 72 74 2f 6d 69 78 65 64 3b multipart/mixed;
00c0: 20 62 6f 75 6e 64 61 72 79 3d 2d 2d 41 42 43 31 boundary=--ABC1
00d0: 32 33 42 6f 75 6e 64 61 72 79 0d 0a 43 6f 6e 74 23Boundary..Cont
00e0: 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 37 37 31 0d ent-Length: 771.
00f0: 0a 0d 0a ...
=> Send data, 771 bytes (0x303)
0000: 2d 2d 41 42 43 31 32 33 42 6f 75 6e 64 61 72 79 --ABC123Boundary
0010: 0d 0a 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 ..Content-Type:
0020: 74 65 78 74 2f 78 6d 6c 0d 0a 0d 0a 3c 3f 78 6d text/xml....<?xm
0030: 6c 20 76 65 72 73 69 6f 6e 3d 22 31 2e 30 22 20 l version="1.0"
0040: 3f 3e 0d 0a 3c 72 65 71 75 65 73 74 3e 0d 0a 3c ?>..<request>..<
0050: 61 63 63 6f 75 6e 74 2d 69 64 3e 58 58 58 58 2d account-id>XXXX-
0060: 58 58 58 58 2d 58 58 58 58 2d 58 58 58 58 3c 2f XXXX-XXXX-XXXX</
0070: 61 63 63 6f 75 6e 74 2d 69 64 3e 0d 0a 3c 72 65 account-id>..<re
0080: 66 65 72 65 6e 63 65 3e 31 32 33 34 35 3c 2f 72 ference>12345</r
0090: 65 66 65 72 65 6e 63 65 3e 0d 0a 3c 61 70 70 2d eference>..<app-
00a0: 6e 61 6d 65 3e 58 58 58 58 58 58 58 58 58 3c 2f name>XXXXXXXXX</
00b0: 61 70 70 2d 6e 61 6d 65 3e 0d 0a 3c 69 6e 66 6f app-name>..<info
00c0: 72 6d 61 74 69 6f 6e 3e 0d 0a 3c 63 61 6c 6c 69 rmation>..<calli
00d0: 6e 67 2d 70 61 72 74 79 3e 0d 0a 3c 6e 61 6d 65 ng-party>..<name
00e0: 3e 4a 6f 65 20 42 6c 6f 67 67 73 3c 2f 6e 61 6d >Joe Bloggs</nam
00f0: 65 3e 0d 0a 3c 69 64 65 6e 74 69 66 69 65 72 3e e>..<identifier>
0100: 34 34 31 32 33 34 35 36 37 38 39 30 3c 2f 69 64 441234567890</id
0110: 65 6e 74 69 66 69 65 72 3e 0d 0a 3c 2f 63 61 6c entifier>..</cal
0120: 6c 69 6e 67 2d 70 61 72 74 79 3e 0d 0a 3c 63 61 ling-party>..<ca
0130: 6c 6c 65 64 2d 70 61 72 74 79 3e 0d 0a 3c 6e 61 lled-party>..<na
0140: 6d 65 3e 4a 6f 68 6e 20 53 6d 69 74 68 3c 2f 6e me>John Smith</n
0150: 61 6d 65 3e 0d 0a 3c 69 64 65 6e 74 69 66 69 65 ame>..<identifie
0160: 72 3e 31 35 35 35 31 32 33 34 35 36 37 3c 2f 69 r>15551234567</i
0170: 64 65 6e 74 69 66 69 65 72 3e 0d 0a 3c 2f 63 61 dentifier>..</ca
0180: 6c 6c 65 64 2d 70 61 72 74 79 3e 0d 0a 3c 2f 69 lled-party>..</i
0190: 6e 66 6f 72 6d 61 74 69 6f 6e 3e 0d 0a 3c 2f 72 nformation>..</r
01a0: 65 71 75 65 73 74 3e 0d 0a 0d 0a 2d 2d 41 42 43 equest>....--ABC
01b0: 31 32 33 42 6f 75 6e 64 61 72 79 0d 0a 43 6f 6e 123Boundary..Con
01c0: 74 65 6e 74 2d 54 79 70 65 3a 20 74 65 78 74 2f tent-Type: text/
01d0: 78 6d 6c 0d 0a 0d 0a 55 6b 6c 47 52 6b 42 41 41 xml....UklGRkBAA
01e0: 41 42 58 51 56 5a 46 5a 6d 31 30 49 42 41 41 41 ABXQVZFZm10IBAAA
01f0: 41 41 48 41 41 45 41 51 42 38 41 41 45 41 66 41 AAHAAEAQB8AAEAfA
0200: 41 41 42 41 41 67 41 5a 6d 46 6a 64 41 51 41 41 AABAAgAZmFjdAQAA
0210: 41 41 50 51 0d 0a 41 41 41 5a 47 46 30 59 52 42 AAPQ..AAAZGF0YRB
0220: 41 41 41 42 6e 35 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f AAABn5//////////
0230: 2f 2f 2f 2f 2f 35 2f 2f 2f 5a 2b 66 6e 2f 2f 2f /////5///Z+fn///
0240: 6e 2f 2f 2f 2f 2f 2f 2f 2f 35 2f 2f 2f 2f 2f 2f n////////5//////
0250: 2f 2f 32 66 2f 2f 32 66 2f 2f 2b 66 2f 2f 2b 66 //2f//2f//+f//+f
0260: 2f 2f 2f 2f 6e 2f 0d 0a 2f 2f 2f 2f 2f 2f 2f 35 ////n/..///////5
0270: 32 66 2f 2f 2f 2f 2f 2f 32 66 2f 2f 2f 2f 2f 2f 2f//////2f//////
0280: 32 66 2f 2f 2f 2f 2f 35 2f 2f 2f 2f 2f 2f 2f 2f 2f/////5////////
0290: 2b 66 2f 2f 2f 2f 2f 5a 2b 66 2f 2f 2f 2f 2f 2f +f/////Z+f//////
02a0: 2f 2f 2f 2f 2f 2f 2f 2f 2f 39 6e 2f 2f 39 6e 5a /////////9n//9nZ
02b0: 2f 39 6e 2f 2f 2f 2f 35 2b 66 2f 2f 2f 39 0d 0a /9n////5+f///9..
02c0: 3c 73 6e 69 70 3e 0d 0a 2f 2f 2b 66 2f 2f 2f 2f <snip>..//+f////
02d0: 2f 2f 32 66 2f 2f 2f 2f 2f 2f 2f 2f 2f 35 2f 2f //2f/////////5//
02e0: 6e 2f 2f 2f 2f 2f 2f 2f 2f 2f 2f 39 6e 0d 0a 0d n//////////9n...
02f0: 0a 2d 2d 41 42 43 31 32 33 42 6f 75 6e 64 61 72 .--ABC123Boundar
0300: 79 2d 2d y--
== Info: upload completely sent off: 771 out of 771 bytes
<= Recv header, 17 bytes (0x11)
0000: 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK.
0010: 0a .
<= Recv header, 27 bytes (0x1b)
0000: 53 65 72 76 65 72 3a 20 41 70 61 63 68 65 2d 43 Server: Apache-C
0010: 6f 79 6f 74 65 2f 31 2e 31 0d 0a oyote/1.1..
<= Recv header, 19 bytes (0x13)
0000: 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 2a 2f Content-Type: */
0010: 2a 0d 0a *..
<= Recv header, 19 bytes (0x13)
0000: 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 Content-Length:
0010: 34 0d 0a 4..
<= Recv header, 37 bytes (0x25)
0000: 44 61 74 65 3a 20 53 61 74 2c 20 31 38 20 46 65 Date: Sat, 18 Fe
0010: 62 20 32 30 31 32 20 32 32 3a 34 33 3a 35 33 20 b 2012 22:43:53
0020: 47 4d 54 0d 0a GMT..
<= Recv header, 2 bytes (0x2)
0000: 0d 0a ..
<= Recv data, 4 bytes (0x4)
0000: 54 45 53 54 TEST
== Info: Connection #0 to host localhost left intact
== Info: Closing connection #0
Consulte: http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html en 7.2.1 muestra ejemplos y explica cómo se debe especificar y usar el límite. Un ejemplo sumario:
1. Especifique en el encabezado:
Content-Type: multipart/mixed;boundary=gc0p4Jq0M2Yt08jU534c0p
2. Preceda cada parte con - y el límite:
--gc0p4Jq0M2Yt08jU534c0p
3. El último límite es - y el límite y -:
--gc0p4Jq0M2Yt08jU534c0p--
Espero que ayude. He tenido que lidiar con esto recientemente.
La opción -T
de curl es para publicar un archivo en un sitio. Hace que Curl establezca sus propios encabezados y transmita el archivo al servidor, lo que realmente no es lo que quiere en este caso. Pruebe esto en su lugar:
curl http://localhost:8080/MyRestServices/restportal/services/mixedMimeText --data-binary @myfile.txt -X POST -i -H "Content-Type: multipart/mixed; boundary="--ABC123Boundary"
puedes manejarlo como multipart / form-data
curl --insecure --request POST --header ''Content-Type: multipart/form-data'' --form ''[email protected]'' --form ''<parameter1>=<value>'' --form ''<parameter2>=<value>'' --form ''<parameter3>=<value>'' http://localhost:8080/MyRestServices/restportal/services/mixedMimeText
Si desea probarlo en un caso de prueba utilizando un simulacro, puede hacer lo siguiente:
MvcResult mvcResult = this.mockMvc.perform(fileUpload("/MyRestServices/restportal/services/mixedMimeText")
.file("file", IOUtils.toByteArray(getClass().getResourceAsStream(Filename))) // the test file is added as a resource to your project
.param("<parameter1>", "<value>")
.param("<parameter2>", "<value>")
.param("<parameter3>", "<value>")
).andExpect(status().isOk())
.andReturn();