基于JAVA中Jersey处理Http协议中的Multipart的详解
那么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--