杰瑞科技汇

Java如何调用SAP的WebService?

Of course! Creating a Java Web Service to interact with SAP is a very common and powerful integration pattern. It allows you to expose SAP business logic (like BAPIs, RFCs, or OData services) to any external system that can consume a standard web service.

Java如何调用SAP的WebService?-图1
(图片来源网络,侵删)

This guide will walk you through the entire process, from concepts to a practical example using the most popular and modern approach.


Core Concepts: Why and How?

Why use a Java Web Service for SAP Integration?

  • Decoupling: Your external application (e.g., a Java web app, a mobile app, a .NET service) doesn't need to know the specifics of SAP's communication protocols (like RFC or IDoc). It just calls a standard SOAP or REST web service.
  • Reusability: A single Java web service can be consumed by many different applications.
  • Security: You can leverage standard web service security (WS-Security, OAuth) and apply your own security layers in Java before even calling SAP.
  • Technology Agnostic: The consuming application can be built in any language (Java, Python, C#, etc.) as long as it can make HTTP/SOAP/REST calls.
  • Asynchronous Processing: You can design the web service to call SAP synchronously or asynchronously, improving the performance of your external system.

How does it work? The Architecture

The typical architecture looks like this:

Java如何调用SAP的WebService?-图2
(图片来源网络,侵删)
[External Client] --> [Java Web Service (Endpoint)] --> [SAP System]
        (SOAP/REST)          (Your Java Code)         (BAPI/RFC/OData)

The Java Web Service acts as a proxy or an adapter. Its main jobs are:

  1. Expose an Endpoint: Define a web service (e.g., a WSDL for SOAP or an OpenAPI spec for REST) that the external client can call.
  2. Translate Request: Receive the request from the client and map its data to the format expected by SAP.
  3. Call SAP: Use a library (like JCo or SAPJCo) to connect to the SAP system and execute the desired function (e.g., a BAPI).
  4. Translate Response: Receive the response from SAP, process it, and map it to the format expected by the client.
  5. Send Response: Return the response to the external client.

Key SAP Technologies You'll Use

To connect your Java code to SAP, you'll use one of the following libraries:

Technology Full Name Description Best For
SAP JCo SAP Java Connector The classic, robust library for calling SAP's Remote Function Call (RFC) modules. It's a mature, stable, and feature-rich library. Synchronous communication. Calling BAPIs and RFC-enabled function modules. This is the most common approach for custom logic.
SAP Cloud Connector - A secure gateway component that on-premise systems (like your Java application server) can use to connect to cloud-based SAP services (like SAP S/4HANA Cloud). Connecting on-premise Java apps to SAP Cloud Platform or SAP S/4HANA Cloud. It handles network connectivity and authentication securely.
SAP OData Open Data Protocol A standardized protocol for building and consuming RESTful APIs. SAP exposes many standard business objects (like Sales Orders, Materials) as OData services. Consuming standard data models from modern SAP systems (S/4HANA). It's REST-based and very easy to use with modern Java HTTP clients.

For this guide, we will focus on SAP JCo, as it's the most fundamental and widely used method for custom integrations.


Step-by-Step Guide: Creating a Java Web Service for a BAPI

Let's create a simple example where a Java Web Service exposes a BAPI to create a Sales Order in SAP.

Java如何调用SAP的WebService?-图3
(图片来源网络,侵删)

Prerequisites

  1. SAP System: Access to an SAP system (e.g., S/4HANA, ECC) where you can test.
  2. SAP JCo Library: Download the appropriate sapjco3.jar and the native library file (.dll for Windows, .so for Linux) from the SAP Software Download Center. You'll need an S-user account.
  3. Java Development Kit (JDK): JDK 8 or later.
  4. Web Service Framework: We'll use JAX-WS (Java API for XML Web Services), which is built into Java EE. For REST, you would use JAX-RS (like RESTEasy or Jersey).

Step 1: Create a Java Project and Add JCo Library

  1. Create a new Maven project in your favorite IDE (Eclipse, IntelliJ, etc.).

  2. Add the sapjco3.jar to your project's classpath. In Maven, you can add it to your pom.xml by installing it to your local Maven repository first:

    mvn install:install-file \
      -Dfile=path/to/sapjco3.jar \
      -DgroupId=com.sap.conn.jco \
      -DartifactId=sapjco \
      -Dversion=3.1.22 \
      -Dpackaging=jar

    Then, add it to your pom.xml:

    <dependency>
        <groupId>com.sap.conn.jco</groupId>
        <artifactId>sapjco</artifactId>
        <version>3.1.22</version> <!-- Use your version -->
    </dependency>

Step 2: Create the Data Transfer Objects (DTOs)

These simple Java classes will represent the data sent to and received from the web service.

SalesOrderRequest.java

// This class will be the input to our web service
public class SalesOrderRequest {
    private String customerNumber;
    private String materialNumber;
    private int quantity;
    // Getters and Setters
    public String getCustomerNumber() { return customerNumber; }
    public void setCustomerNumber(String customerNumber) { this.customerNumber = customerNumber; }
    public String getMaterialNumber() { return materialNumber; }
    public void setMaterialNumber(String materialNumber) { this.materialNumber = materialNumber; }
    public int getQuantity() { return quantity; }
    public void setQuantity(int quantity) { this.quantity = quantity; }
}

SalesOrderResponse.java

// This class will be the output from our web service
public class SalesOrderResponse {
    private boolean success;
    private String message;
    private String salesOrderNumber;
    // Getters and Setters
    public boolean isSuccess() { return success; }
    public void setSuccess(boolean success) { this.success = success; }
    public String getMessage() { return message; }
    public void setMessage(String message) { this.message = message; }
    public String getSalesOrderNumber() { return salesOrderNumber; }
    public void setSalesOrderNumber(String salesOrderNumber) { this.salesOrderNumber = salesOrderNumber; }
}

Step 3: Create the SAP Integration Logic (The "Core")

This class contains the actual logic to connect to SAP and call the BAPI. Never hardcode credentials! Use a configuration file.

SapOrderService.java

import com.sap.conn.jco.*;
import java.util.Properties;
public class SapOrderService {
    // Load JCo destination from a properties file
    private JCoDestination getDestination() {
        try {
            Properties props = new Properties();
            // Load from a file 'sapjco_dest.properties' on the classpath
            props.load(getClass().getClassLoader().getResourceAsStream("sapjco_dest.properties"));
            return JCoDestinationManager.getDestination(props);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get SAP destination", e);
        }
    }
    public SalesOrderResponse createSalesOrder(SalesOrderRequest request) {
        SalesOrderResponse response = new SalesOrderResponse();
        JCoDestination destination = null;
        JCoFunction function = null;
        try {
            // 1. Get destination and create a function call to the BAPI
            destination = getDestination();
            function = destination.getRepository().getFunction("BAPI_SALESORDER_CREATEFROMDAT2");
            if (function == null) {
                throw new RuntimeException("BAPI_SALESORDER_CREATEFROMDAT2 not found in SAP.");
            }
            // 2. Set import parameters
            function.getImportParameterList().setValue("ORDER_HEADER_IN", "0000001234"); // Example order type
            function.getImportParameterList().setValue("SALES_ORG", "1000");
            function.getImportParameterList().setValue("DISTR_CHAN", "10");
            function.getImportParameterList().setValue("DIVISION", "00");
            // 3. Set table parameters (for items)
            JCoTable orderItems = function.getTableParameterList().getTable("ORDER_ITEMS_IN");
            orderItems.appendRow();
            orderItems.setValue("MATERIAL", request.getMaterialNumber());
            orderItems.setValue("TARGET_QTY", request.getQuantity());
            JCoTable partner = function.getTableParameterList
分享:
扫描分享到社交APP
上一篇
下一篇