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

 更新时间:2013年05月08日 19:01:41   作者:  
之前在基于C#开发彩信用最原始的StringBuilder拼接字符串方式处理过Multipart。现在在做一个项目的时候,由于之前的技术路线都是使用Jersey处理Http这块,为了保持技术路线一致,研究了一下如何使用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--

相关文章

  • 详解Spring中使用@within与@target的区别

    详解Spring中使用@within与@target的区别

    这篇文章主要介绍了Spring中使用@within与@target的一些区别,本文通过项目案例给大家详细分析,给大家介绍的非常详细,代码简单易懂,需要的朋友可以参考下
    2021-09-09
  • 解决mybatis-plus新增数据自增ID变无序问题

    解决mybatis-plus新增数据自增ID变无序问题

    这篇文章主要介绍了解决mybatis-plus新增数据自增ID变无序问题,具有很好的参考价值,希望对大家有所帮助。
    2023-07-07
  • Java中Controller、Service、Dao/Mapper层的区别与用法

    Java中Controller、Service、Dao/Mapper层的区别与用法

    在Java开发中,通常会采用三层架构(或称MVC架构)来划分程序的职责和功能,分别是Controller层、Service层、Dao/Mapper层,本文将详细给大家介绍了三层的区别和用法,需要的朋友可以参考下
    2023-05-05
  • Spring事务不生效的8种原因小结

    Spring事务不生效的8种原因小结

    Spring事务会在几种特定的场景下失效,本文主要介绍了Spring事务不生效的8种原因小结,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • SpringCloud+RocketMQ实现分布式事务的实践

    SpringCloud+RocketMQ实现分布式事务的实践

    分布式事务已经成为了我们的经常使用的。所以我们来一步一步的实现基于RocketMQ的分布式事务。感兴趣的可以了解一下
    2021-10-10
  • 动态代理模拟实现aop的示例

    动态代理模拟实现aop的示例

    下面小编就为大家带来一篇动态代理模拟实现aop的示例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望对大家有所帮助
    2017-11-11
  • 详解springboot+aop+Lua分布式限流的最佳实践

    详解springboot+aop+Lua分布式限流的最佳实践

    这篇文章主要介绍了详解springboot+aop+Lua分布式限流的最佳实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectOne的使用

    MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectO

    本文主要介绍了MyBatis-Plus 之selectMaps、selectObjs、selectCount、selectOne的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • Spring详细讲解@Autowired注解

    Spring详细讲解@Autowired注解

    @Autowired注解可以用在类属性,构造函数,setter方法和函数参数上,该注解可以准确地控制bean在何处如何自动装配的过程。在默认情况下,该注解是类型驱动的注入
    2022-06-06
  • java获取服务器基本信息的方法

    java获取服务器基本信息的方法

    这篇文章主要介绍了java获取服务器基本信息的方法,涉及java获取系统CPU、内存及操作系统等相关信息的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07

最新评论