R/3 to Java Sending IDOCs Using SapIdoc Jar

Following are the configurations to be done on the SAP R/3 system to send/Receive IDoc

1)      Create One TCP/IP Destination

Use the transaction SM59

            Provide a name for the RFC Destination, in our case IDOCTEST

            Select connection type as T (TCP/IP connection)

            Give a program ID (This is important), here it’s IDOCTEST

            Add a description

Now your screen should look as follows

2) Creating port and assigning logical Name

            Use the transaction WE21

            Right click on Transactional RFC and select New

            Give a port name

            Select RFC Destination created in step 1

            Your screen should look as follows

3) Creating logical system for the IDOC

            Use the transaction BD54

            Click on new entries

            Provide a Name for the logical system

            Screen shot should look as follows

4) Creating Partner Agreement

            Use the transaction WE20

            Select the partner Number

            Select partner type as LS

            Create outbound partner profile for the ORDERS

Creating inbound parameter for MATMAS as follows

Finally your screen should look as follows

You might be thinking I could not find even a single java code so far, here goes the java part

 

1)      Create a Java project using NWDS

2)      Create a folder lib and add the following libraries (sapidoc.jar, sapidocjco.jar, sapjco.jar) all of this are downloadable from http://service.sap.com/connectors

3)      Add this jar to the build path

 

//Code provided along with the IDOC Sample

package com.bcone.test;

import com.sap.mw.idoc.*;
import com.sap.mw.idoc.jco.*;
import com.sap.mw.jco.*;

import java.io.*;

/**
 * This sample program demonstrates how to receive IDocs from an SAP system.
 * Furthermore it gives a little insight on how to navigate on IDoc segment
 * trees demonstrating a sample processing of an ORDERS message.
 *
 */
public class IDocReceiver
       implements JCO.ServerExceptionListener
{
    /** Formatter for timestamp strings. */
    private static final java.text.SimpleDateFormat timestampFormat = new java.text.SimpleDateFormat("yyyyMMddHHmmss");

    /** Path to write the incoming data. */
    private static String incomingPath = "c://";

    /** Default constructor. */
    public IDocReceiver()
    {
    }

    /**
     * Class MyIDocServer is for receiving IDocs and function requests.
     * The reason for implementing the class as an inner class of the sample
     * program is only to keep all the sample source code within one file.
     */
    public static class MyIDocServer
                  extends JCoIDoc.Server
    {
        /**
         * Overridden constructor of JCoIDoc.Server.
         * Choose the constructors that one would like to make public.
         */
        public MyIDocServer(String gwhost, String gwserv, String progid,
                            IRepository jcoRepository, IDoc.Repository idocRepository)
        {
            super(gwhost, gwserv, progid, jcoRepository, idocRepository);
        }//constructor MyIDocServer

        /**
         * Overridden constructor of JCoIDoc.Server.
         * Choose the constructors that one would like to make public.
         */
        public MyIDocServer(java.util.Properties properties,
                            IRepository jcoRepository, IDoc.Repository idocRepository)
        {
            super(properties, jcoRepository, idocRepository);
        }//constructor MyIDocServer

        /**
         * Overridden method of JCoIDoc.Server.
         * Function requests that do not contain IDocs will be handled here.
         * These requests will be stored as XML file in the incoming path.
         * No other action will be done. The return values won't be filled and
         * no exception will be thrown to the caller.
         */
        protected void handleRequest(JCO.Function function)
        {
            System.out.println("Incoming function request '" + function.getName() + "'...");
            String filename = function.getName() + "_" +
                              timestampFormat.format(new java.util.Date()) + ".xml";
            System.out.println("Storing function request as XML file '" + filename + "'...");
            function.writeXML(incomingPath + filename);
        }//method handleRequest

        /**
         * Overridden method of JCoIDoc.Server.
         * Function requests that contain IDocs will be handled here.
         * All IDocs will be stored as XML files in the incoming path.
         * Additionally, IDocs that are part of an ORDERS message will be
         * processed specifically. Some relevant information is extracted from
         * these IDocs and will be stored in a text file in the incoming path.
         */
        protected void handleRequest(IDoc.DocumentList documentList)
        {
            System.out.println("Incoming IDoc list request containing " +
                               documentList.getNumDocuments() + " documents...");

            IDoc.DocumentIterator iterator = documentList.iterator();
            IDoc.Document doc = null;

            while (iterator.hasNext())
            {
                doc = iterator.nextDocument();
                System.out.println(doc.toXML());
               
                System.out.println("Processing document no. " + doc.getIDocNumber() + "...");

                String iDocType = doc.getIDocTypeExtension();
                if (iDocType.length() == 0) iDocType = doc.getIDocType();
                String filename = "IDOC_" + iDocType + "_" + doc.getIDocNumber() + "_" +
                                  timestampFormat.format(new java.util.Date()) + ".xml";
                System.out.print("Storing IDoc as XML file '" + incomingPath + filename + "'...");
                doc.writeXML(incomingPath + filename);
                System.out.println(" done.");

                if (doc.getMessageType().equals("ORDERS")) {
                    System.out.println("Processing message of type 'ORDERS'...");
                    processOrder(doc);
                } else {
                    System.out.println("Message of type '" + doc.getMessageType() +
                                       "' won't be processed.");
                }
            }
        }//method handleRequest

        /**
         * The following 4 methods for transaction management are not implemented
         * here in this sample program. For a description on how to implement
         * them in real production scenarios please see the JCo API specification
         * for the JCO.Server class.
         */
        protected boolean onCheckTID(String tid) {
            return true;
        }//method onCheckTID

        protected void onConfirmTID(String tid) {
        }//method onConfirmTID

        protected void onCommit(String tid) {
        }//method onCommit

        protected void onRollback(String tid) {
        }//method onRollback
    }//class MyIDocServer

   /**
    * Process an IDoc of type ORDERS##.
    * Please note that this is only a sample processing that does not reflect
    * all possible application data scenarios for ORDERS. There are different
    * segment navigation and iteration techniques used within this method.
    */
    public static void processOrder(IDoc.Document order)
    {
        try {
            String filename = "ORDER_" + order.getIDocNumber() + "_" +
                              timestampFormat.format(new java.util.Date()) + ".txt";
            System.out.print("Storing IDoc as text file '" + filename + "'...");
            PrintWriter out = new PrintWriter(new FileOutputStream(incomingPath + filename));

            out.println("General data:");
            out.println("-------------");
            out.println("IDoc number: " + order.getIDocNumber());
            out.println("Partner number: " + order.getSenderPartnerNumber());
            out.println("IDoc type: " + order.getIDocType());
            out.println("IDoc type extension: " + order.getIDocTypeExtension());

            //get the root segment from the document
            //The root segment does not contain any fields or data. It is only
            //used as the standard parent segment.
            IDoc.Segment root = order.getRootSegment();
            IDoc.Segment seg = null;

            //get the document header general data
            seg = root.getFirstChild("E1EDK01");
            String currency = seg.getString("CURCY");
            out.println("/nOrder number: " + seg.getString("BELNR"));

            //get the customer (sold-to party)
            seg = root.getFirstChild("E1EDKA1", "PARVW", "AG");
            if (seg!=null) {
                out.println("/nSold-to party:");
                out.println("--------------");
                writeAddress(out, seg);
            }

            //get the goods recipient (ship-to party)
            seg = root.getFirstChild("E1EDKA1", "PARVW", "WE");
            if (seg!=null) {
                out.println("/nShip-to party:");
                out.println("--------------");
                writeAddress(out, seg);
            }

            //process the order items
            IDoc.SegmentIterator orderItems = root.getChildrenIterator("E1EDP01");
            out.println("/nOrder items:");
            out.println("------------");

            IDoc.Segment segItemID = null;
            String materialID = null;
            String materialText = null;
            String priceUnit = null;

            while (orderItems.hasNext())
            {
                //get the next order item
                seg = orderItems.nextSegment();

                //first try to find segment specifying material number
                //used by vendor (first segment field QUALF=002)
                segItemID = seg.getFirstChild("E1EDP19", 0, "002");

                //if not found try to find segment specifying international
                //article number EAN (first segment field QUALF=003)
                if (segItemID==null) segItemID = seg.getFirstChild("E1EDP19", 0, "003");

                //if not found try to find segment specifying material number
                //used by customer (first segment field QUALF=001)
                if (segItemID==null) segItemID = seg.getFirstChild("E1EDP19", 0, "001");

                //get the material ID and short text
                if (segItemID!=null) {
                    materialID = segItemID.getString(1); //field IDTNR
                    materialText = segItemID.getString(2); //field KTEXT
                } else {
                    materialID = "unknown";
                    materialText = "product";
                }

                //get the ordered quantity and price data
                //and output the ordered item
                out.print(seg.getString("MENGE") + " "); //quantity
                out.print(seg.getString("MENEE") + " "); //unit of measure
                out.print(materialID + " " + materialText);
                out.print(" ; Price: ");
                out.print(seg.getString("VPREI") + " "); //price (net)
                out.print(currency + "/");
                priceUnit = seg.getString("PEINH"); //price unit
                if (!priceUnit.equals("1")) out.print(priceUnit + " ");
                out.print(seg.getString("PMENE")); //price unit of measure
                out.print(" ; Total Price: ");
                out.print(seg.getString("NETWR") + " "); //item value (net)
                out.println(currency);
            }

            //get some totals (if available)
            out.println("/nTotals:");
            out.println("-------");
            seg = root.getFirstChild("E1EDS01");
            while (seg!=null) {
                switch (seg.getShort("SUMID")) {
                    case 001: out.println("Number of items: " + seg.getString("SUMME") + " " + seg.getString("SUNIT"));
                    case 002: out.println("Net document value: " + seg.getString("SUMME") + " " + seg.getString("SUNIT"));
                }
                seg = seg.getNextSibling("E1EDS01");
            }

            out.close();
            System.out.println(" done.");
        }
        catch (java.lang.Exception ex) {
            System.out.println("Exception occurred: " + ex);
        }
    }//method processOrder

    /**
     * Standard method for writing address data extracted from an E1EDKA1 segment
     * to a PrintWriter output stream.
     */
    public static void writeAddress(PrintWriter out, IDoc.Segment e1edka1)
    {
        String value = null;

        value = e1edka1.getString("PARTN");
        if (value.length()>0) out.println("Partner number: " + value + "/n");
        value = e1edka1.getString("NAME1");
        if (value.length()>0) out.println("Name 1: " + value);
        value = e1edka1.getString("NAME2");
        if (value.length()>0) out.println("Name 2: " + value);
        value = e1edka1.getString("NAME3");
        if (value.length()>0) out.println("Name 3: " + value);
        value = e1edka1.getString("NAME4");
        if (value.length()>0) out.println("Name 4: " + value);
        value = e1edka1.getString("STRAS"); //
        if (value.length()>0) out.println("Street 1: " + value);
        value = e1edka1.getString("STRS2");
        if (value.length()>0) out.println("Street 2: " + value);
        value = e1edka1.getString("ORT01");
        if (value.length()>0) out.println("City: " + value);
        value = e1edka1.getString("COUNC");
        if (value.length()>0) out.println("County code: " + value);
        value = e1edka1.getString("PSTLZ");
        if (value.length()>0) out.println("Postal code: " + value);
        value = e1edka1.getString("LAND1");
        if (value.length()>0) out.println("Country key: " + value);
        value = e1edka1.getString("TELF1");
        if (value.length()>0) out.println("1st phone: " + value);
        value = e1edka1.getString("TELF2");
        if (value.length()>0) out.println("2nd phone: " + value);
        value = e1edka1.getString("TELFX");
        if (value.length()>0) out.println("Fax: " + value);
        value = e1edka1.getString("BNAME");

        out.println();
        if (value.length()>0) out.println("User: " + value);
        value = e1edka1.getString("PAORG");
        if (value.length()>0) out.println("Org. code: " + value);
        value = e1edka1.getString("ORGTX");
        if (value.length()>0) out.println("Org. text: " + value);
        value = e1edka1.getString("PAGRU");
        if (value.length()>0) out.println("Group code: " + value);
    }//method writeAddress

    /**
     * Interface method of JCO.ServerExceptionListener to be notified about
     * server exceptions.
     */
    public void serverExceptionOccurred(JCO.Server server, java.lang.Exception ex)
    {
        System.out.println("Server exception occurred: " + ex);
    }//method serverExceptionOccurred

    /**
     * Main method initializing and starting the JCoIDoc.Server.
     */
    public static void main(String[] args)
    {
        try {
            //instantiate main class
            IDocReceiver myApp = new IDocReceiver();

            //add server exception listener to be notified about server exceptions
            JCO.addServerExceptionListener(myApp);

            //server properties to log on at the gateway server
            java.util.Properties srvProps = new java.util.Properties();
            srvProps.put("jco.server.gwhost", "B03");
            srvProps.put("jco.server.gwserv", "sapgw00");
            srvProps.put("jco.server.progid", "IDOCTEST"); // This should match with the one created in Step1
            srvProps.put("jco.server.unicode", "0"); // enter "1" for unicode systems

            //client properties to log on for repository queries
            java.util.Properties clntProps = new java.util.Properties();
            clntProps.put("jco.client.client", "500");
            clntProps.put("jco.client.user", "UserID");
            clntProps.put("jco.client.passwd", "*****");
            clntProps.put("jco.client.lang", "EN");
            clntProps.put("jco.client.ashost", "B03");
            clntProps.put("jco.client.sysnr", "00");

            //create a JCo client pool
            JCO.addClientPool("MyPool", 5, clntProps);

            //create a JCo repository that will be used for querying
            //meta data for standard function requests
            IRepository jcoRepository = JCO.createRepository("MyJCoRepository", "MyPool");

            //create an IDoc repository that will be used for querying
            //IDoc meta data
            IDoc.Repository idocRepository = JCoIDoc.createRepository("MyIDocRepository", "MyPool");

            //create a JCoIDoc.Server instance
            MyIDocServer server = new MyIDocServer(srvProps, jcoRepository, idocRepository);

            //start the JCoIDoc.Server instance and listen for incoming
            //function requests and IDocs
            server.start();
            System.out.println("Started MyIDocServer.");
            System.out.println("MyIDocServer is listening now...");
        }
        catch ( java.lang.Exception ex ) {
            System.out.println("Application error: " + ex);
        }
    }
}

 

To Test this you need to login to the R/3 system
Use the Transaction WE19
Select Basic Type and Enter ORDERS05
Click on Execute 
Double Click on EDIDC
Fill in the details as follows

 

lick on Continue.
Click on Standard Outbound Processing

Output expected at the java end

MyIDocServer is listening now...

Incoming IDoc list request containing 1 documents...

Processing document no. 0000000000208036...

Storing IDoc as XML file 'c:/IDOC_ORDERS05_0000000000208036_20081120203757.xml'... done.

Open the file to see the contents received from R/3.

 

Following is the code needed to send the IDoc from Java to R/3

//Code available with IDoc Samples
package com.bcone.test;

import com.sap.mw.idoc.IDoc;
import com.sap.mw.idoc.jco.JCoIDoc;
import com.sap.mw.jco.JCO;

public class JCoIDocSender
{
    public static void main(String[] args)
    {
        try {
            //create a JCo client pool
            JCO.addClientPool( "MyPool",    //pool name
                               3,           //maximum pool connections
                               "500",       //SAP client
                               "UserID",    //RFC Permission needed for user ID
                               "*****",  //password
                               "EN",        //language
                               "B03", //app server host name
                               "00" );   //system number

            //create an IDoc repository
            IDoc.Repository idocRep = JCoIDoc.createRepository("MyIDocRepository", "MyPool");

            //create a new and empty MATMAS02 document
            System.out.print("Creating IDoc...");
            IDoc.Document doc = JCoIDoc.createDocument(idocRep, "MATMAS02");

            //get the root segment from the document
            //The root segment does not contain any fields or data. It is only
            //used as the standard parent segment and won't be transmitted when
            //the document is sent to an SAP system.
            IDoc.Segment segment = doc.getRootSegment();

            //create and add a new and empty child segment of type E1MARAM
            //and fill the segment data
            segment = segment.addChild("E1MARAM");
            segment.setField("MSGFN", "005");
            segment.setField("MATNR", "BOXCOOKIES");
            segment.setField("ERSDA", "20081101");
            segment.setField("ERNAM", "UserID");
            segment.setField("PSTAT", "K");
            segment.setField("MTART", "FERT");
            segment.setField("MBRSH", "M");
            //segment.setField("MATKL", "G1113");
            segment.setField("MEINS", "PCE");
            segment.setField("BLANZ", "000");
            segment.setField("BRGEW", "0.550");
            segment.setField("NTGEW", "0.000");
            segment.setField("GEWEI", "KGM");
            segment.setField("VPSTA", "KBG");
 
            //create and add a new and empty child segment of type E1MAKTM
            //and fill the segment data
            segment = segment.addChild("E1MAKTM");
            segment.setField("MSGFN", "005");
            segment.setField("SPRAS", "D");
            segment.setField("MAKTX", "Box of cookies[DE]");
            segment.setField("SPRAS_ISO", "DE");
           
            //create and add a new and empty sibling segment of type E1MAKTM (same type)
            //and fill the segment data
            segment = segment.addSibling();
            segment.setField("MSGFN", "005");
            segment.setField("SPRAS", "E");
            segment.setField("MAKTX", "Box of cookies");
            segment.setField("SPRAS_ISO", "EN");
 
            //prepare document for sending and set the appropriate control data
            doc.setMessageType("MATMAS");
            doc.setRecipientPartnerType("LS");
            doc.setRecipientPartnerNumber("LSB03");
           
            doc.setSenderPort("JAVIDOC");
            doc.setSenderPartnerType("LS");
            doc.setSenderPartnerNumber("JAVSYS");

            System.out.println(" done.");

            //check the whole document's syntax
            try {
                System.out.print("Checking IDoc syntax...");
                doc.checkSyntax();
                System.out.println(" done.");
            }
            catch ( IDoc.Exception ex ) {
                System.out.println(" Syntax error: " + ex);
                ex.printStackTrace();
                System.exit(0);
            }

            //get a JCo client from previously created client pool
            JCO.Client client = JCO.getClient("MyPool");

            //create a new transaction ID
            String tid = client.createTID();

            //send the document to the SAP system asynchronously
            System.out.print("Sending IDoc...");
            System.out.println(doc.toXML());
            client.send(doc, tid);

            //confirm the transaction ID
            client.confirmTID(tid);
            System.out.println(" done.");

            //release the JCo client and return it back to the pool
            JCO.releaseClient(client);
        }
        catch ( java.lang.Exception ex ) {
            System.out.println("Application error: " + ex);
            ex.printStackTrace();
        }
    }//method main
}

Once this code is executed You will see the following statements in the console.
Creating IDoc... done.

Checking IDoc syntax... done.

done.

Now you can login to the R/3 system and check whether the Material Master is created or not.

Incase if the material is not created use the transaction WE02.

Following should be the status if its successfully posted.

If the status is red, double click on the status record number for the error reason and details.

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值