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.

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:

[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:
- 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.
- Translate Request: Receive the request from the client and map its data to the format expected by SAP.
- Call SAP: Use a library (like
JCoorSAPJCo) to connect to the SAP system and execute the desired function (e.g., a BAPI). - Translate Response: Receive the response from SAP, process it, and map it to the format expected by the client.
- 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.

Prerequisites
- SAP System: Access to an SAP system (e.g., S/4HANA, ECC) where you can test.
- SAP JCo Library: Download the appropriate
sapjco3.jarand the native library file (.dllfor Windows,.sofor Linux) from the SAP Software Download Center. You'll need an S-user account. - Java Development Kit (JDK): JDK 8 or later.
- 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
-
Create a new Maven project in your favorite IDE (Eclipse, IntelliJ, etc.).
-
Add the
sapjco3.jarto your project's classpath. In Maven, you can add it to yourpom.xmlby 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 