Отправка iDOC из Java в SAP

У нас есть файлы iDOC, созданные нашей системой. Теперь мы пытаемся отправить их в SAP через соединение RFC. Я уже установил соединение RFC КАК КЛИЕНТ, но не могу отправить iDOC!

Я попытался создать образец iDOC, чтобы протестировать его, но он не работает!

Exception in thread "main" java.lang.NoSuchMethodError: com.sap.conn.idoc.jco.SAPRepository$ConnectionProvider.execute(Lcom/sap/conn/jco/JCoFunction;Lcom/sap/conn/jco/rt/AbapRepository;)V
    at com.sap.conn.idoc.jco.SAPRepository.queryRootSegmentMetaData40(SAPRepository.java:1204)
    at com.sap.conn.idoc.jco.SAPRepository.queryRootSegmentMetaData(SAPRepository.java:1110)
    at com.sap.conn.idoc.jco.SAPRepository.getRootSegmentMetaData(SAPRepository.java:909)
    at com.sap.conn.idoc.rt.DefaultIDocDocument.<init>(DefaultIDocDocument.java:124)
    at com.sap.conn.idoc.rt.DefaultIDocDocument.<init>(DefaultIDocDocument.java:61)
    at com.sap.conn.idoc.jco.JCoIDocDocument.<init>(JCoIDocDocument.java:51)
    at com.sap.conn.idoc.jco.JCoIDocRuntime.createIDocDocument(JCoIDocRuntime.java:133)
    at com.sap.conn.idoc.jco.JCoIDocRuntime.createIDocDocument(JCoIDocRuntime.java:35)
    at com.sap.conn.idoc.rt.DefaultIDocRuntime.createIDocDocument(DefaultIDocRuntime.java:175)
    at com.sap.conn.idoc.rt.DefaultIDocRuntime.createIDocDocument(DefaultIDocRuntime.java:18)
    at com.idoc.sender.IDocClientExample.main(IDocClientExample.java:49)

Я даже пытался отправить образец XML iDOC, но также столкнулся с другой ошибкой, много раз пытался изменить XML, но снова и снова сталкивался с одной и той же проблемой!

com.sap.conn.idoc.IDocParseException: (7) IDOC_ERROR_PARSE_FAILURE: Invalid character encountered in XML input data source:
state=READING_XMLDECLARATION, charPosition=14, lineNumber=1, columnNumber=15, invalidChar=U+003D,
sourceSnippet=...@<?xml version="1.0" encoding="UTF-8"?><DEBMAS06><IDOC><EDI_DC40><DOCNUM>20120114120000</DOCNUM><IDO...
                               ^
    at com.sap.conn.idoc.rt.xml.DefaultIDocXMLParser.throwIDocParseException(DefaultIDocXMLParser.java:2223)
    at com.sap.conn.idoc.rt.xml.DefaultIDocXMLParser.parseProlog(DefaultIDocXMLParser.java:1635)
    at com.sap.conn.idoc.rt.xml.DefaultIDocXMLParser.parse(DefaultIDocXMLParser.java:320)
    at com.sap.conn.idoc.rt.xml.DefaultIDocXMLProcessor.parse(DefaultIDocXMLProcessor.java:112)
    at com.sap.conn.idoc.rt.xml.DefaultIDocXMLProcessor.parse(DefaultIDocXMLProcessor.java:54)
    at com.sap.conn.idoc.rt.xml.DefaultIDocXMLProcessor.parse(DefaultIDocXMLProcessor.java:31)
    at com.idoc.sender.IDocClientExample.main(IDocClientExample.java:57)

Это код, который я использую для создания iDOC и отправки XML-файла iDOC:

package com.idoc.sender;


import com.sap.conn.idoc.*;
import com.sap.conn.idoc.jco.JCoIDoc;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;

import java.io.BufferedReader;
import java.io.FileReader;


public class IDocClientExample {

 public static void main(String[] args) {

  try {

   String iDocXML = null;
   FileReader fileReader;

   try {
    fileReader = new FileReader("TestSalesOrder.xml");
    BufferedReader br = new BufferedReader(fileReader);
    StringBuffer sb = new StringBuffer();
    String line;
    while ((line = br.readLine()) != null) {
     sb.append(line);
    }

    iDocXML = sb.toString();

    br.close();
    fileReader.close();
   } catch (Exception ex) {
    ex.printStackTrace();
   }

   // see provided configuration file xxxx.jcoDestination
   JCoDestination destination = JCoDestinationManager.getDestination("xxxx");
   IDocRepository iDocRepository = JCoIDoc.getIDocRepository(destination);
   String tid = destination.createTID();
   IDocFactory iDocFactory = JCoIDoc.getIDocFactory();

   System.out.println(destination.getAttributes());


   // a) create sample new idoc
   IDocDocument doc = iDocFactory.createIDocDocument(iDocRepository, "SYSTAT01");
   IDocSegment segment = doc.getRootSegment();
   segment.addChild("E1MARAM");
   JCoIDoc.send(doc, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);


   // b) use existent xml file
   IDocXMLProcessor processor = iDocFactory.getIDocXMLProcessor();
   IDocDocumentList iDocList = processor.parse(iDocRepository, iDocXML);
   JCoIDoc.send(iDocList, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);
   destination.confirmTID(tid);

  } catch (Exception e) {
   e.printStackTrace();
  }
  System.out.print("program end");
 }
}
// a) create sample new idoc
IDocDocument doc = iDocFactory.createIDocDocument(iDocRepository, "SYSTAT01");
IDocSegment segment = doc.getRootSegment();
segment.addChild("E1MARAM");
JCoIDoc.send(doc, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);


// b) use existent xml file
IDocXMLProcessor processor = iDocFactory.getIDocXMLProcessor();
IDocDocumentList iDocList = processor.parse(iDocRepository, iDocXML);
JCoIDoc.send(iDocList, IDocFactory.IDOC_VERSION_DEFAULT, destination, tid);
destination.confirmTID(tid);

} catch (Exception e) {
 e.printStackTrace();
}
System.out.print("program end");
}
}

Это мой файл подключения:

jco.client.lang=EN
jco.client.client=100
jco.client.passwd=xxxx
jco.client.user=xxxx
jco.client.sysnr=01
jco.client.ashost=xxxx

Это мой xml-файл:

<?xml version="1.0" encoding="UTF-8"?>
<DEBMAS06>
<IDOC>
<EDI_DC40>
<DOCNUM>20120114120000</DOCNUM><IDOCTYP>DEBMAS06</IDOCTYP>
<MESTYP>DEBMAS</MESTYP>
<SNDPOR>HTTPDEMO</SNDPOR>
<SNDPRT>LS</SNDPRT>
<SNDPRN>HTTPDEMO</SNDPRN>
<RCVPOR>SAPxxx</RCVPOR>
<RCVPRT>LS</RCVPRT>
<RCVPRN>xxxCLNT100</RCVPRN>
</EDI_DC40>
<E1KNA1M segment="1">
<KUNNR>47</KUNNR>
<NAME1>Test Customer</NAME1>
<KTOKD>0004</KTOKD>
<SORTL>TEST</SORTL>
<ORT01>City</ORT01>
<LAND1>PL</LAND1>
<LZONE>A</LZONE>
<SPRAS>L</SPRAS>
<STRAS>Street</STRAS>
</E1KNA1M>
</IDOC>
</DEBMAS06>

Я использую sapjco3-x86-64bit-3.0.5 и sapidoc-3.0.1!

Тестирование создания iDOC и отправки XML IDOC проводится только для проверки, но в нашем случае iDOC уже готов!

Мой вопрос: как я могу отправить iDOC непосредственно с моего диска в SAP через RFC? Если я не могу этого сделать, как я могу исправить ошибку создания iDOC или отправки iDOC XML? Мой второй вопрос: как только я смогу отправить iDOC, нужно ли мне устанавливать новое RFC-соединение СЕРВЕРА, чтобы я мог получать iDOC из SAP?

** ИЗМЕНИТЬ **

Теперь я могу правильно отправлять и получать IDoc. Моя проблема заключается в том, как я могу получить IDoc как Плоский IDoc.

Я могу получить свой IDoc как XML IDoc с помощью этого кода:

package com.idoc.actif;

import com.sap.conn.idoc.IDocDocumentList;
import com.sap.conn.idoc.IDocXMLProcessor;
import com.sap.conn.idoc.jco.*;
import com.sap.conn.jco.server.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;


public class IDocServerExample
{
    public static void main(String[] a)
    {   
        try
        {
            // see provided examples of configuration files xxxx.jcoServer and  xxxx.jcoDestination
            JCoIDocServer server = JCoIDoc.getServer("xxxx");
            server.setIDocHandlerFactory(new MyIDocHandlerFactory());

            server.setTIDHandler(new MyTidHandler());

            MyThrowableListener listener = new MyThrowableListener();
            server.addServerErrorListener(listener);
            server.addServerExceptionListener(listener);
            //server.setConnectionCount(1);
            server.start();

        }
        catch (Exception e) 
        {
            e.printStackTrace();
        }
     }

    static class MyIDocHandler implements JCoIDocHandler
    {
        public void handleRequest(JCoServerContext serverCtx, IDocDocumentList idocList)
        {

            FileOutputStream fos=null;
            OutputStreamWriter osw=null;
            try
            {
                //receiving XML IDoc, how to get the IDoc as a Flat IDoc (SAP is sending the IDoc as Flat)???
                IDocXMLProcessor xmlProcessor = JCoIDoc.getIDocFactory().getIDocXMLProcessor();
                fos=new FileOutputStream(serverCtx.getTID());
                osw=new OutputStreamWriter(fos, "UTF8");
                xmlProcessor.render(idocList, osw, IDocXMLProcessor.RENDER_WITH_TABS_AND_CRLF);
                osw.flush();
            }
            catch (Throwable thr)
            {
                thr.printStackTrace();
            }
            finally
            {
                try
                {
                    if (osw!=null)
                        osw.close();
                    if (fos!=null)
                        fos.close();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
            }
        }
    }

    static class MyIDocHandlerFactory implements JCoIDocHandlerFactory
    {
        private JCoIDocHandler handler = new MyIDocHandler();
        public JCoIDocHandler getIDocHandler(JCoIDocServerContext serverCtx)
        {
            return handler;
        }
    }

    static class MyThrowableListener implements JCoServerErrorListener, JCoServerExceptionListener
    {

        public void serverErrorOccurred(JCoServer server, String connectionId, JCoServerContextInfo ctx, Error error)
        {
            System.out.println(">>> Error occured on " + server.getProgramID() + " connection " + connectionId);
            error.printStackTrace();
        }
        public void serverExceptionOccurred(JCoServer server, String connectionId, JCoServerContextInfo ctx, Exception error)
        {
            System.out.println(">>> Error occured on " + server.getProgramID() + " connection " + connectionId);
            error.printStackTrace();
        }
    }

    static class MyTidHandler implements JCoServerTIDHandler
    {
        public boolean checkTID(JCoServerContext serverCtx, String tid)
        {
            System.out.println("checkTID called for TID="+tid);
            return true;
        }


        public void confirmTID(JCoServerContext serverCtx, String tid)
        {
            System.out.println("confirmTID called for TID="+tid);
        }


        public void commit(JCoServerContext serverCtx, String tid)
        {
            System.out.println("commit called for TID="+tid);
        }


        public void rollback(JCoServerContext serverCtx, String tid)
        {
            System.out.print("rollback called for TID="+tid);
        }
    }
}

person H.Rhaiem    schedule 14.11.2017    source источник
comment
у вас настроен входной порт на xxxCLNT100 для вашего /LS/HTTPDEMO? см. код транзакции WE20.   -  person Iliya Kuznetsov    schedule 15.11.2017
comment
Извините, но я не совсем понимаю, что вы имеете в виду! Я новичок в SAP! Как вы думаете, у меня проблема с iDOC API?   -  person H.Rhaiem    schedule 15.11.2017
comment
Да, ты прав. Мой вопрос был для того, чтобы убедиться, что система приемника настроена правильно.   -  person Iliya Kuznetsov    schedule 15.11.2017
comment
Проблема решена, спасибо, могу ли я отправить Flat IDoc напрямую в SAP без необходимости создавать их с помощью Java?   -  person H.Rhaiem    schedule 16.11.2017


Ответы (1)


Я предполагаю, что существует несовместимость между двумя используемыми вами библиотеками SAP. Я рекомендую сначала установить последние уровни исправлений. В настоящее время это JCo версии 3.0.17 и библиотека Java IDoc 3.0.12.

Я только не понимаю, что вы тут делаете со StringBuffer. Если вы хотите прочитать IDoc-XML из файла, то IDocXMLProcessor предлагает для этого соответствующие методы синтаксического анализа — лучше всего будет

IDocXMLProcessor.parse(IDocRepository repository, InputStream xmlStream)

так что он также может позаботиться о различных кодировках файлов, как указано в содержащемся атрибуте кодирования XML. Если вы выберете java.io.Reader или String, вам придется позаботиться об этом самостоятельно (чего вы не делаете в своем примере).

Но в принципе ваш код не кажется неправильным на первый взгляд. В отличие от самого IDoc-XML, в котором отсутствуют обязательные атрибуты BEGIN="1" и SEGMENT="1" для тегов ‹IDOC› и ‹EDI_DC40›.

person Trixx    schedule 15.11.2017
comment
Да, я решил это, получив новый API, не могли бы вы посмотреть на редактирование, пожалуйста? - person H.Rhaiem; 16.11.2017
comment
Если мой ответ решил вашу проблему, не могли бы вы отметить его как правильный ответ, пожалуйста? Спасибо. Кроме того, новые вопросы, которые не были заданы в исходном сообщении, а также не имеют прямого отношения к нему (что имеет место здесь), должны быть заданы в отдельном новом вопросе, а не добавлены впоследствии с правкой. - person Trixx; 17.11.2017
comment
Большое спасибо, что приняли мой ответ. Но я не нашел ваш новый вопрос о плоских файлах IDoc. Так что я думаю, что это больше не представляет для вас интереса. - person Trixx; 19.11.2017
comment
О нет, я публикую это сегодня! - person H.Rhaiem; 19.11.2017