基于JAVA中Jersey处理Http协议中的Multipart的详解
发布时间:2021-06-15 13:43:57
那么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--


猜你喜欢
- RocketMQ修改生产者消费者日志保存路径rocket默认是将所有日志文件保存到user.home的对于win系统就是C盘了。1.修改Ro
- 第一步:添加新项目第二步:添加新的页签,注意,此页签是显示到Outlook主界面的第三步:添加自己想要的文本框以及按钮第四步:如果你想将此界
- C#控制台程序使用Log4net日志组件,供大家参考,具体内容如下1、Log4net一般都不陌生,但是在配置上不同类型的项目又不相同的地方比
- 我们先来看看公众号发放现金红包的效果:需要调用商户平台的接口,接口发放规则如下:1.发送频率限制——默认1800/min 2.发送个数上限—
- 原理比较简单,引入System.Reflection命名空间,利用反射查看某种Type下的方法,属性,字段和支持的接口等。using Sys
- 目录目标为什么操作步骤工程截图运行效果完整源代码目标在SpringBoot中集成内存数据库H2.为什么像H2、hsqldb、derby、sq
- 本文实例讲解了Android中的自定义属性,具体内容如下1、引言对于自定义属性,大家肯定都不陌生,遵循以下几步,就可以实现:自定义一个Cus
- 伤害数字显示HUD游戏中收到伤害掉血,会有飘动的伤害数值;可以使用OnGUI中GUI.Label来实现;可自定义字体,颜色,大小等;如果需要
- 使用datatables自带后台查询 前台代码:<!DOCTYPE html><html><head>&
- 在Android中要让一个程序的界面始终保持一个方向,不随手机方向转动而变化的办法: 只要在AndroidManifest.xml里面配置一
- 废话不多说,直接上代码package com.ietree.basicskill.socket.basic.nio;import java.
- 本文实例讲述了Java正则验证正整数的方法。分享给大家供大家参考,具体如下:package des;import java.util.reg
- 一、问题最近在做代码重构,代码工程采用了Controller/Service/Dao分层架构,Dao层使用了Mybatis-Plus框架。在
- 方法一class Program { [STAThread] static
- 本文实例讲述了使用SAX来解析XML。通常来说在Android里面可以使用SAX和DOM,DOM需要把整个XML文件读入内存再解析,比较消耗
- List映射表List列表是一个java集合存储在序列中的元素,并允许重复的元素。此接口的用户可以精确地控制,其中列表中的每个元素插入。用户
- 效果展示在实际项目当中我们经常看到如下各种剪裁形状的效果,Flutter 为我们提供了非常方便的 Widget 很轻松就可以实现,下面我们来
- 一问道StringBuffer与StringBuilder的区别,张口就来StringBuffer是线程安全的,因为它相关方法都加了sync
- Java泛型映射不同的值类型详解前言:一般来说,开发人员偶尔会遇到这样的情形: 在一个特定容器中映射任意类型的值。然而Java 集合API只
- Spring AOP proxyTargetClass的行为要点列表形式proxyTargetClasstrue目标对象实现了接口 – 使用