基于JAVA中Jersey处理Http协议中的Multipart的详解

Java教程 2025-08-15

那么Http协议中的Multipart是个什么东东?下面是摘抄http协议1.1的一段话:

在multipart entity(多部分实体)的例子中,一个或多个不同的数据集合并在一个单一的body(体)中,一个"multipart"(多部分)类型 field的(域)必须出现在实体的header(头域)。body(体)必须包括一个或多个body part(体部分),每一个位于boundary(边界)定界符线之前,最后一个则跟着一个结束边界定界符线。在它的边界定界符线后,每一个体部分由头域、空行、体组成。

上面的描述写的有点拗口,简单的理解可以为:一个post的请求,可以根据一定规范去定义多个部分;

下面用移动网状网协议(其实就是一个请求中包括2个独立的xml内容,一个head的xml,一个body的xml)去举例说明如何利用Jersey处理Multipart,主要代码如下(开始的时候server端接收的代码死活不知道如何写也没查到别人怎么写的,后来一生气,反编译jersey-multipart-1.0.3.1.jar包的代码看了下,才明白):

复制代码代码如下:

private static WebResource webResource = client.resource("http://xxx.xx.xx:xxx");

public static final String HeadFieldName = "xmlhead";

public static final String BodyFieldName = "xmlbody";

// Client发送代码

public static String post(String head, String body) throws BusinessException {

FormDataMultiPart multiPart = new FormDataMultiPart();

multiPart.field(RequestField.HeadFieldName, head, MediaType.MULTIPART_FORM_DATA_TYPE);

multiPart.field(RequestField.BodyFieldName, body, MediaType.MULTIPART_FORM_DATA_TYPE);

return webResource.type("multipart/form-data").post(String.class, multiPart);

}

// Server端接收代码

@POST

@Produces({MediaType.APPLICATION_XML, MediaType.MULTIPART_FORM_DATA})

@Consumes({MediaType.APPLICATION_XML, MediaType.MULTIPART_FORM_DATA})

public String service(FormDataMultiPart multiPart) throws Exception{

if(multiPart == null){

if(_logger.isErrorEnabled()){

_logger.error("the request FormDataMultiPart is null");

}

throw new Exception("the request FormDataMultiPart is null");

}

List< RequestField > requestFields = new ArrayList< RequestField >();

for(BodyPart bodyPart : multiPart.getBodyParts()){

String fieldName = ((FormDataBodyPart)bodyPart).getName().trim();

if(fieldName.equalsIgnoreCase(RequestField.HeadFieldName)){

requestFields.add(new RequestField(fieldName, bodyPart.getEntityAs(String.class)));

}

else if(fieldName.equalsIgnoreCase(RequestField.BodyFieldName)){

requestFields.add(new RequestField(fieldName, bodyPart.getEntityAs(String.class)));

}

else{

if(_logger.isWarnEnabled()){

_logger.warn("invalid fieldName:" + fieldName + ",originXml:" + bodyPart.getEntityAs(String.class));

}

}

}

.....

}

用工具抓包的实际post报文:

复制代码代码如下:

POST /ba/resources/bossServer HTTP/1.1

Content-Type: multipart/form-data;boundary=Boundary_1_30911772_1367997277472

MIME-Version: 1.0

User-Agent: Java/1.6.0_10-rc2

Host: 192.168.245.18:8082

Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2

Connection: keep-alive

Content-Length: 1600

--Boundary_1_30911772_1367997277472

Content-Disposition: form-data;name="xmlhead"

Content-Type: multipart/form-data

< ?xml version="1.0" encoding="UTF-8"? >

< InterBOSS >

< Version >0100< /Version >

< TestFlag >0< /TestFlag >

< BIPType >

< BIPCode >BIP2B543< /BIPCode >

< ActivityCode >T2001543< /ActivityCode >

< ActionCode >0< /ActionCode >

< /BIPType >

< RoutingInfo >

< OrigDomain >IMPS< /OrigDomain >

< RouteType >01< /RouteType >

< Routing >

< HomeDomain >BOSS< /HomeDomain >

< RouteValue >13810494631< /RouteValue >

< /Routing >

< /RoutingInfo >

< TransInfo >

< SessionID >2013050815143783928824< /SessionID >

< TransIDO >2013050815143783928824< /TransIDO >

< TransIDOTime >20130508151437< /TransIDOTime >

< /TransInfo >

< /InterBOSS >

--Boundary_1_30911772_1367997277472

Content-Disposition: form-data;name="xmlbody"

Content-Type: multipart/form-data

< ?xml version="1.0" encoding="UTF-8"? >

< InterBOSS >

< SvcCont >< ![CDATA[< subscribeServiceReq >

< msgTransactionID >210001BIP2B543130508151437477294< /msgTransactionID >

< subscribeServInfo >

< oprTime >20130508151436< /oprTime >

< actionID >06< /actionID >

< effTime >20130508151437< /effTime >

< expireTime >30000101000000< /expireTime >

< feeUser_ID >13810494631< /feeUser_ID >

< destUser_ID >13810494631< /destUser_ID >

< actionReasonID >1< /actionReasonID >

< servType >210001< /servType >

< subServType >FXCJHY< /subServType >

< SPID >901508< /SPID >

< SPServID >FXCJHY< /SPServID >

< accessMode >01< /accessMode >

< feeType >2< /feeType >

< /subscribeServInfo >

< /subscribeServiceReq >]] >< /SvcCont >

< /InterBOSS >

--Boundary_1_30911772_1367997277472--