无法向基于Spring MVC的REST服务发送多部分/混合请求

我有一个基于Spring MVC和Resteasy的REST服务,我需要通过发送multipart / mixed请求进行测试。

该服务编码如下:

@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"; } 

我使用以下文件作为multipart mime内容发送

 --ABC123Boundary Content-Type: text/xml   XXXX-XXXX-XXXX-XXXX 12345 XXXXXXXXX   Joe Bloggs 441234567890   John Smith 15551234567    --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  //+f//////2f/////////5//n//////////9n --ABC123Boundary-- 

我使用curl客户端使用以下命令发送请求:

 curl -X POST http://localhost:8080/MyRestServices/restportal/services/mixedMimeText -i -H "Content-Type: multipart/mixed; boundary="--ABC123Boundary" -T myfile.txt 

请求确实到达了服务,但我在JBOSS终端上看到的是它产生了以下错误,这个错误并没有多大意义。 没有堆栈跟踪或任何其他错误。

 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. 

听起来内容有问题,但我不太确定。

编辑

@Perception – 我按如下方式更改了命令,但仍然会产生同样的错误

 curl http://localhost:8080/MyRestServices/restportal/services/mixedMimeText --data-binary @myfile.txt -X POST -i -H "Content-Type: multipart/mixed; boundary=--ABC123Boundary" 

我想知道MultipartInput结构是否期望内容采用不同的格式。

编辑

看起来发送的数据是正确的。 以下是使用–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 

跟踪输出

 == 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........XXXX- 0060: 58 58 58 58 2d 58 58 58 58 2d 58 58 58 58 3c 2f XXXX-XXXX-XXXX..12345..XXXXXXXXX......Joe Bloggs.. 0100: 34 34 31 32 33 34 35 36 37 38 39 30 3c 2f 69 64 441234567890......John Smith..15551234567..........--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 ..//+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 

请参阅7.2.1中的http://www.w3.org/Protocols/rfc1341/7_2_Multipart.html ,它显示了示例并讨论了如何指定和使用边界。 摘要示例:

1.在标题中指定:

 Content-Type: multipart/mixed;boundary=gc0p4Jq0M2Yt08jU534c0p 

2.在每个部分前面加上 – 和边界:

 --gc0p4Jq0M2Yt08jU534c0p 

3.最后的边界是 – 和边界和 – :

 --gc0p4Jq0M2Yt08jU534c0p-- 

希望有所帮助。 我最近自己不得不自己处理这件事。

curl的-T选项用于将文件发布到站点。 它会导致curl设置自己的标头并将文件流式传输到服务器,在这种情况下,这实际上不是你想要的。 试试这个:

 curl http:// localhost:8080 / MyRestServices / restportal / services / mixedMimeText
     --data-binary @ myfile.txt
     -X POST
     -i -H“Content-Type:multipart / mixed; boundary =” -  ABC123Boundary“

你可以把它作为multipart / form-data处理

 curl --insecure --request POST --header 'Content-Type: multipart/form-data' --form 'file=@myfile.txt' --form '=' --form '=' --form '=' http://localhost:8080/MyRestServices/restportal/services/mixedMimeText 

如果你想使用mock在测试用例中测试它,那么你可以执行以下操作:

 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("", "") .param("", "") .param("", "") ).andExpect(status().isOk()) .andReturn();