基于PI的Webservice发布实例

最近的项目中,接口较多,而Webservice技术是主要实现方式之一。下面以项目中的一个具体实例来体验一下基于PI的Webservice发布。


业务场景

SAP系统实时接收一个外围接口系统(基于Web的电子商务平台)回传的数据。


技术分析

由于同步要求较高,数据量偏小,采用Webservice实现较为合理。


实例演示

创建好自建表,用于接收回传的数据:


 

TC: SPROXY根据集成组在PI配置的服务名创建Service Interface


 

在实现类中,根据传入的XML字符串,解析后更新到自建表:

  data: ls_field_data like zmmjyh_cdif,

        lt_field_data like table of ls_field_data,

        ls_zmmjyh_ht_0007 like zmmjyh_ht_0007,

        lt_zmmjyh_ht_0007 like table of ls_zmmjyh_ht_0007,

        l_retcode type i,

        l_fieldname type string,

        l_float type f.

 

  field-symbols: <fs_fieldname> type any,

                 <fs_fieldvalue> type any.

 

  "解析XML数据到通用内表

  type-pools: ixml.

  types: begin of t_xml_line ,

  data(256) type x,

  end of t_xml_line.

 

  data: l_ixml            type ref to if_ixml,

        l_streamfactory   type ref to if_ixml_stream_factory,

        l_parser          type ref to if_ixml_parser,

        l_istream         type ref to if_ixml_istream,

        l_document        type ref to if_ixml_document,

        l_node            type ref to if_ixml_node,

        l_xmldata         type string.

 

  data: l_elem            type ref to if_ixml_element,

        l_root_node       type ref to if_ixml_node,

        l_next_node       type ref to if_ixml_node,

        l_name            type string,

        l_iterator        type ref to if_ixml_node_iterator.

 

  data: l_xml_table       type table of t_xml_line,

        l_xml_line        type t_xml_line,

        l_xml_table_size  type i.

 

* Creating the main iXML factory

  l_ixml = cl_ixml=>create( ).

 

* Creating a stream factorya

  l_streamfactory = l_ixml->create_stream_factory( ).

 

  l_istream = l_streamfactory->create_istream_string( string = input ).

 

* Creating a document

 

  l_document = l_ixml->create_document( ).

 

* Create a Parser

 

  l_parser = l_ixml->create_parser( stream_factory = l_streamfactory

                                    istream        = l_istream

                                    document       = l_document ).

 

* Parse the stream

  if l_parser->parse( ) ne 0.

    l_retcode = 0.

    return .

  endif.

 

* Process the document

  if l_parser->is_dom_generating( ) eq 'X'.

    perform process_dom tables lt_field_data using l_document .

  endif.

 

*&--------------------------------------------------------------------*

*& Form process_dom

*&--------------------------------------------------------------------*

form process_dom tables p_i_zxml structure zmmjyh_cdif

using document type ref to if_ixml_document .

 

  data: node      type ref to if_ixml_node,

        iterator  type ref to if_ixml_node_iterator,

        nodemap     type ref to if_ixml_named_node_map,

        node_parent type ref to if_ixml_node,

        attr      type ref to if_ixml_node,

        name      type string,

        name1     type string,

        prefix    type string,

        value     type string,

        indent    type i,

        count     type i,

        index     type i.

 

  node ?= document.

 

  check not node is initial.

 

  if node is initial.

    exit.

  endif.

 

* create a node iterator

  iterator  = node->create_iterator( ).

 

* get current node

  node = iterator->get_next( ).

 

* loop over all nodes

 

  while not node is initial.

    indent = node->get_height( ) * 2.

    indent = indent + 20.

 

    case node->get_type( ).

      when if_ixml_node=>co_node_element.

 

* element node

 

        name    = node->get_name( ).

        nodemap = node->get_attributes( ).

        if not nodemap is initial.

 

* attributes

 

          count = nodemap->get_length( ).

          do count times.

            index  = sy-index - 1.

            attr   = nodemap->get_item( index ).

            name   = attr->get_name( ).

            prefix = attr->get_namespace_prefix( ).

            value  = attr->get_value( ).

            "记录字段名、字段值

            p_i_zxml-fieldname  = name .

            p_i_zxml-fieldvalue = value .

            append p_i_zxml .

 

          enddo.

        endif.

      when if_ixml_node=>co_node_text or

        if_ixml_node=>co_node_cdata_section.

 

* text node

        value  = node->get_value( ).

        node_parent = node->get_parent( ).

        name1 = node_parent->get_name( ).

        "记录字段名、字段值

        p_i_zxml-fieldname  = name1 .

        p_i_zxml-fieldvalue = value .

        append p_i_zxml .

 

    endcase.

 

    node = iterator->get_next( ).

  endwhile.

endform. "process_dom

 

  "准备数据到数据库更新内表

  loop at lt_field_data into ls_field_data.

    clear l_fieldname.

    assign ls_field_data-fieldvalue to <fs_fieldvalue>.

    concatenate 'LS_ZMMJYH_HT_0007-' ls_field_data-fieldname into l_fieldname.

    assign (l_fieldname) to <fs_fieldname>.

    if <fs_fieldname> is assigned.

      if ls_field_data-fieldname = 'CONTRAMOUNTNUM'

          or ls_field_data-fieldname = 'APPLYAMOUNT'.

        "金额字段中科学计数法的处理

        clear l_float.

        l_float = <fs_fieldvalue>.

        <fs_fieldname> = l_float.

      else.

 

        <fs_fieldname> = <fs_fieldvalue>.

      endif.

    else.

 

      it_return-zresult =  '0'.

      it_return-description = '程序异常,字段名不匹配!'.

      append it_return.

      return.

    endif.

 

    "到达一条数据末尾

    if ls_field_data-fieldname = 'PREPAYID'.

      append ls_zmmjyh_ht_0007 to lt_zmmjyh_ht_0007.

      clear ls_zmmjyh_ht_0007.

    endif.

  endloop.

 

  "更新到自建表

  if lines( lt_zmmjyh_ht_0007 ) > 0 .

    modify zmmjyh_ht_0007 from table lt_zmmjyh_ht_0007.

    if sy-subrc = 0.

      commit work and wait.

      it_return-zresult =  '1'.

      it_return-description = '回传成功!'.

      append it_return.

    else.

      rollback work.

      it_return-zresult =  '0'.

      it_return-description = '回传失败,数据库更新异常!'.

      append it_return.

    endif.

  else.

 

    it_return-zresult =  '0'.

    it_return-description = '无数据可传输!'.

    append it_return.

  endif.

 

把结果回传给外围系统,先创建好Transformation

基于PI的Webservice发布实例_第1张图片

 

然后把返回值封装成XML串:

data:l_xstr type xstring.

  call transformation zmmjyhmesgjdzsw

        source      root = it_return[]

*          RESULT XML output

        result xml l_xstr

        options xml_header = 'no' .

 

types: begin of ty_bin,

      bin_data(1024) type x,

    end of ty_bin.

  data:lt_bin type table of ty_bin."文件二进制内表

  data:l_len type i.

 

  check input is not initial.

 

  call function 'SCMS_XSTRING_TO_BINARY'

    exporting

      buffer                = l_xstr

*   APPEND_TO_TABLE       = ' '

 importing

   output_length         = l_len

    tables

      binary_tab            = lt_bin

            .

 

  call function 'SCMS_BINARY_TO_STRING'

    exporting

      input_length        = l_len

*   FIRST_LINE          = 0

*   LAST_LINE           = 0

*   MIMETYPE            = ' '

*   ENCODING            =

   importing

     text_buffer         = output-zmmjyht010response-output

*   OUTPUT_LENGTH       =

    tables

      binary_tab          = lt_bin

* EXCEPTIONS

*   FAILED              = 1

*   OTHERS              = 2

            .

  if sy-subrc <> 0.

* MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

*         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

  endif.

 

由于是基于PI创建的,此时的Webservice还没有注册,TC:SOAMANAGER


 

进入single serviceadministration,搜索刚才创建的webservice:Zmmjyht010,并apply selection


 

点选Configurations标签,创建服务:


 

记得勾选中    User ID/Password

点击 show wsdl options,并把 WSDL Format 设置为standard,然后点选Display selectedBinding's WSDL URL,

在右边会得到WSDL的URL

 

在SICF中,找到服务 Zmmjyht010,在登录数据里,把过程数据改为 “标准”,这是为了跳过WSDL的安全策略。

基于PI的Webservice发布实例_第2张图片

 

最后,然后把此WSDL的URL给到外围系统的开发人员就可以了。

你可能感兴趣的:(xml,webservice,Stream,iterator,transformation,attributes)