您的位置:首页 > 其它

通过esb报文调用接口,返回报文数据

2014-01-23 01:56 405 查看
最近公司为了规范代码,要求之前的所有http请求的接口,全部通过esb调用。 何为ESB,ESB全称为Enterprise Service Bus,即企业服务总线。它是传统中间件技术与XML、Web服务等技术结合的产物。ESB提供了网络中最基本的连接中枢

 ESB提供比传统中间件产品更为廉价的解决方案,同时它还可以消除不同应用之间的技术差异,让不同的应用服务器协调运作,实现了不同服务之间的通信与整合。从功能上看,ESB提供了事件驱动和文档导向的处理模式,以及分布式的运行管理机制,它支持基于内容的路由和过滤,具备了复杂数据的传输能力,并可以提供一系列的标准接口,但是ESB并没有http请求效率高。

    废话就不多说了,先看看怎么实现的吧。

    首先确定请求报文的格式,以我在项目中的报文为例:

<MbfService xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<input1>

<MbfHeader>

<ServiceCode>CMercPerformanceMgmt</ServiceCode>

<Operation>queryStoreScores</Operation>

<AppCode>SFS</AppCode>

<UId>5136fa413f96493391d6075f654d4d83bcfbbc57bd8e47e5</UId>

</MbfHeader>

<MbfBody>

<cmfUserId>0224136722</cmfUserId>

<currentPage>1</currentPage>

<pageSize>5</pageSize>

<supportCStore>0</supportCStore>

</MbfBody>

</input1></MbfService>

这就是一个接口的请求报文,一般报文格式是固定的,需要改动的只是报文的节点,被调用方接口也是根据节点筛选出所需要的请求参数,另外,报文是用POST方式提交,参数是封装在body中的。

    下面是被请求接口:为了各位看的明白些,我狠添注释,这样代码和注释一起看比较方便

//RequestMapping,这个是spring中截获请求的url作用

@RequestMapping("/my_product_review")

    public String getPendingOrderItems(HttpServletRequest request, HttpServletResponse response)

            throws IOException {

        //这里是从request中取到报文,getMbfRequestInput方法会在下面贴出代码

        MbfRequestInput mbfRequestInput = getMbfRequestInput(request);

        //根据报文中参数创建请求对象,这里只要PendingOrderItemDTO 中的属性跟请求报文的节点一致即可(也就是报文中      <MbfBody>中的节点名称)

        PendingOrderItemDTO requestDTO = (PendingOrderItemDTO) mbfRequestInput

                .getMbfBody(PendingOrderItemDTO.class);

        //封装返回对像的报文

        MbfResponseWrapper mbfResponseWrapper = new MbfResponseWrapper(

                mbfRequestInput.getMbfHeader());

        // 处理请求参数,orderVo为最终返回报文的类

        MobilePhonePendingOrderVO orderVO = null;

       try {

       //这句代码可以忽略,就是根据请求参数做处理,封装类,作为返回报文数据

            orderVO = mobilePhoneService.getPendingOrderItems(requestDTO.getCmfUserId(),

                    requestDTO.getCurrentPage(), requestDTO.getPageSize(),

                    requestDTO.getSupportCStore());

            //将返回类按报文格式处理,就是跟请求报文一样,比如orderVo有一个属性name,返回报文<MbfBody>中就会有<name>XXX</name>

            mbfResponseWrapper.setMbfBody(orderVO);

            //返回此次请求成功标识

            mbfResponseWrapper.setStatus(Constants.COMPLETE);

        } catch (Exception e) {

            mbfResponseWrapper.setMbfBody(new DummyResponseDTO());

            //返回此次请求失败标识

            mbfResponseWrapper.setStatus(Constants.FAIL);

            mbfResponseWrapper.setCode("");

            mbfResponseWrapper.setDesc(e.getMessage());

            //下面是异常处理

            EventMessage eventMessage = new EventMessage();

            eventMessage.setFunctionName(ExceptionUtil.getCurrentMethodName());

            logger.logException(eventMessage, e);

        }

        //按报文格式返回数据

        return ajaxXmlCache(response, mbfResponseWrapper.getMbfResponse().toString(),

                ReviewProperties.getMaxAge());

    }

上面这些代码对使用esb处理请求,返回报文等就够了,因为解析报文是有专门的封装类的,只需要引入,就可以使用里面的方法。为了各位方便学习,我多写点吧

/**

     * 从HttpServletRequest中获取ESB请求报文

     */

    public MbfRequestInput getMbfRequestInput(HttpServletRequest request) throws IOException {

        InputStream inputStream = request.getInputStream();

        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));

        StringBuffer buffer = new StringBuffer();

        String line = "";

        while ((line = in.readLine()) != null) {

            buffer.append(line);

        }

        return MbfRequest.getMbfRequest(buffer.toString()).getInput();

    }

其中MbfRequest.getMbfRequest()方法

/**

     * 功能描述:resquestXml转换成MbfResquest对象

     */

    public static MbfRequest getMbfRequest(String xml){

        MbfRequest mbfRequest = (MbfRequest) XStreamUtil.xmlToObject(xml, MbfRequest.class);

        mbfRequest.getInput().setMbfBodyXml(getMbfBodyXml(xml));

        return mbfRequest;

    }

至于比如getInput()等方法就是自己封装的很基础的java类了,贴出来也无妨

/**

 * 

 * 功能描述: 企业内同一区域内系统交互请求报文对象

 * 请求报文格式:

 *  <MbfService xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

 *       <input1>

 *           <MbfHeader>

 *             <!--ServiceCode: 服务代码-->

 *               <ServiceCode>OrderManage</ServiceCode>

 *               <!--Operation: 操作编码-->

 *               <Operation>CreateOrder</Operation>

 *               <!--AppCode: 请求方系统代码-->

 *               <AppCode>b2c</AppCode>  

 *               <!--UId: 服务流水号-->       

 *               <UId>414d5120514d5f6c6f63616c202020203baa474c20012802</UId>

 *               <!--AuthId: 认证ID -->

 *               <AuthId/>

 *           </MbfHeader>

 *           <MbfBody>

 *               <!--请求服务系统BODY -->

 *           </MbfBody>

 *       </input1>

 *   </MbfService>

 */

@XStreamAlias("MbfService")

public class MbfRequest {

    private static final String rootStart = "<MbfService xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">";

    private static final String rootEnd   = "</MbfService>";

    

    private static final String bodyStart = "<MbfBody>";

    

    private static final String bodyEnd  = "</MbfBody>";

    @XStreamAlias("input1")

    private MbfRequestInput     input;

    public MbfRequestInput getInput() {

        return input;

    }

    public void setInput(MbfRequestInput input) {

        this.input = input;

    }

    

    /**

     * 功能描述:resquestXml转换成MbfResquest对象

     */

    public static MbfRequest getMbfRequest(String xml){

        MbfRequest mbfRequest = (MbfRequest) XStreamUtil.xmlToObject(xml, MbfRequest.class);

        mbfRequest.getInput().setMbfBodyXml(getMbfBodyXml(xml));

        return mbfRequest;

    }

    private static String getMbfBodyXml(String xml){

   

        int beginIndex = xml.indexOf(bodyStart);

        int endIndex = xml.indexOf(bodyEnd);

        String bodyXml = "";

        if(beginIndex != -1 && endIndex != -1){

        bodyXml = xml.substring(beginIndex + bodyStart.length(), endIndex);

        }

        return bodyXml;

    }

    

    @Override

    public String toString() {

        return toString(false);

    }

    

    public String toString(boolean replaceBlank) {

        String inputStr = null;

        if(replaceBlank){

            inputStr = input.toString(true);

        } else {

            inputStr = input.toString(false);

        }

        String result = rootStart + inputStr + rootEnd;

        return result;

    }

}

虽然上面主要贴了的是解析请求报文,但是相信大家看到这里也应该知道是怎么回事了,如果你用现有的解析报文的jar包,很方便用,但是如果你就想自己写jar包玩,根据上面的慢慢琢磨是可以的,但是还是有些底层jar需要引用,比如:com.thoughtworks.xstream.annotations.XStreamAlias,不过就是一层一层的解析xml文件,封装成请求对象,然后在把返回对象解析成xml文件发送给调用方罢了。

最后,我觉得有必要说下主方法中的return后面的内容:ajaxXmlCache(response, mbfResponseWrapper.getMbfResponse().toString(),

                ReviewProperties.getMaxAge());

这个地方是比较容易出现问题的,不多说 了,直接贴代码吧:

/**

     * 根据字符串输出xml,返回null

     * 

     * @param xml

     * @return

     */

    public String ajaxXmlCache(HttpServletResponse response, String xmlString, String cacheTime) {

        return ajaxCache(response, xmlString, "text/xml", cacheTime);

    }

//下面就是最原始的写内容了

/**

     * AJAX输出,返回null

     * 

     * @param content

     * @param type

     * @return

     */

    public String ajaxCache(HttpServletResponse response, String content, String type, String cacheTime) {

        try {

            response.setContentType(type + ";charset=UTF-8");

            setCache(response, cacheTime);

            response.getWriter().write(content);

            response.getWriter().flush();

        } catch (IOException e) {

            EventMessage eventMessage = new EventMessage();

            eventMessage.setFunctionName(ExceptionUtil.getCurrentMethodName());

            logger.logException(eventMessage, e);

        }

        return null;

    }

其中针对解析报文,封装报文,以及对内容的封装代码也是有很多的,觉得没有必要全部贴出来,就写这些吧,刚开始写博客,算作是记录一下自己的成长经历吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息