Java 如何使用SAP jco登录多个SAP系统
我是SAP JCo的新手,我需要使用SAP JCo调用多个SAP系统。但我无法同时连接多个sap系统 以下是代码:Java 如何使用SAP jco登录多个SAP系统,java,jco,sapjco3,sap-r3,sap-crm,Java,Jco,Sapjco3,Sap R3,Sap Crm,我是SAP JCo的新手,我需要使用SAP JCo调用多个SAP系统。但我无法同时连接多个sap系统 以下是代码: package com.sap.test; import java.util.Properties; import com.sap.conn.jco.JCoDestination; import com.sap.conn.jco.JCoDestinationManager; import com.sap.conn.jco.JCoException; import com.sa
package com.sap.test;
import java.util.Properties;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.JCoRepository;
import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.Environment;
import com.sap.utils.MyDestinationDataProvider;
import com.sap.utils.SapSystem;
public class TestMultipleSAPConnection {
public static Properties properties;
public static JCoDestination dest = null;
public static JCoRepository repos = null;
public static SapSystem system = null;
String SAP_SERVER = "SAP_SERVER";
MyDestinationDataProvider myProvider = null;
public static void main(String[] args) throws JCoException {
getConnection_CRM();
getConnection_R3();
}
public static JCoDestination getConnection_R3() {
boolean connR3_flag = true;
JCoDestination dest = null;
JCoRepository repos = null;
String SAP_SERVER = "SAP_SERVER";
Properties properties = new Properties();
SapSystem system = new SapSystem();
system.setClient("100");
system.setHost("r3devsvr.myweb.com");
system.setLanguage("en");
system.setSystemNumber("00");
system.setUser("SAP-R3-USER");
system.setPassword("init1234");
properties.setProperty("jco.client.ashost", system.getHost());
properties.setProperty("jco.client.sysnr", system.getSystemNumber());
properties.setProperty("jco.client.client", system.getClient());
properties.setProperty("jco.client.user", system.getUser());
properties.setProperty("jco.client.passwd", system.getPassword());
properties.setProperty("jco.client.lang", system.getLanguage());
System.out.println("******* Connection Parameter Set *******");
MyDestinationDataProvider myProvider = new MyDestinationDataProvider();
System.out.println("******* Destination Provider Set *******");
myProvider.changePropertiesForABAP_AS(properties);
if (!Environment.isDestinationDataProviderRegistered()) {
System.out.println("Registering Destination Provider R3");
Environment.registerDestinationDataProvider((DestinationDataProvider) myProvider);
}else{
System.out.println("Destination Provider already set..R3");
connR3_flag = false;
}
try {
dest = JCoDestinationManager.getDestination((String) SAP_SERVER);
repos = dest.getRepository();
if (repos == null) {
System.out.println("Repos is null.....");
} else {
System.out.println("Repos is not null.....");
}
System.out.println("After getting repos...");
if(connR3_flag){
System.out.println("R3 Connection Successfull...");
}
} catch (Exception ex) {
System.out.println(ex);
}
return dest;
}
public static JCoDestination getConnection_CRM() {
boolean connCRM_flag = true;
JCoDestination dest = null;
JCoRepository repos = null;
String SAP_SERVER = "SAP_SERVER";
Properties properties = new Properties();
SapSystem system = new SapSystem();
system.setClient("200");
system.setHost("crmdevsvr.myweb.com");
system.setLanguage("en");
system.setSystemNumber("00");
system.setUser("SAP-CRM-USER");
system.setPassword("init1234");
properties.setProperty("jco.client.ashost", system.getHost());
properties.setProperty("jco.client.sysnr", system.getSystemNumber());
properties.setProperty("jco.client.client", system.getClient());
properties.setProperty("jco.client.user", system.getUser());
properties.setProperty("jco.client.passwd", system.getPassword());
properties.setProperty("jco.client.lang", system.getLanguage());
System.out.println("******* Connection Parameter Set *******");
MyDestinationDataProvider myProvider = new MyDestinationDataProvider();
System.out.println("******* Destination Provider Set *******");
myProvider.changePropertiesForABAP_AS(properties);
if (!Environment.isDestinationDataProviderRegistered()) {
System.out.println("Registering Destination Provider CRM");
Environment.registerDestinationDataProvider((DestinationDataProvider) myProvider);
}else{
System.out.println("Destination Provider already set..CRM");
connCRM_flag = false;
}
try {
dest = JCoDestinationManager.getDestination((String) SAP_SERVER);
repos = dest.getRepository();
if (repos == null) {
System.out.println("Repos is null.....");
} else {
System.out.println("Repos is not null.....");
}
System.out.println("After getting repos...");
if(connCRM_flag){
System.out.println("CRM Connection Successfull...");
}
} catch (Exception ex) {
System.out.println(ex);
}
return dest;
}
}
JCo JavaDoc文档说明: 只能注册DestinationDataProvider的一个实现。 要注册另一个实现,基础结构必须首先 注销当前已注册的实现。事实并非如此 建议永久交换目标数据提供程序 注册。一个已注册实例应全局管理所有 整个基础架构环境的目标配置 因此,您必须注册一个
DestinationDataProvider
实例,这是类MyDestinationDataProvider
的实例。
此实施需要管理和存储所有SAP系统的所有不同登录配置,可通过不同的目标名称字符串访问。一个简单的HashMap
就足够了。将两个具有不同目标名称字符串的属性
实例添加到HashMap
中,并从方法MyDestinationDataProvider.getDestinationProperties(String destinationName)
返回与传递的destinationName关联的属性
实例。
因此,您可以通过特定的目标名称访问针对任何SAP系统的所需JCoDestination
实例。在您的示例中,两种目标配置都使用了“SAP_服务器”,但这两种配置都不起作用。例如,使用SAP系统ID(SID)作为目标名称(键)
如果使用示例中的名称,则
JCoDestinationManager.getDestination(“CRM”)
将返回系统“CRM”的JCoDestination
实例和系统“R3”的JCoDestination.getDestination(“R3”)
实例。而且两者都可以独立和同时使用。就是这样。JCo JavaDoc文档说明:
只能注册DestinationDataProvider的一个实现。
要注册另一个实现,基础结构必须首先
注销当前已注册的实现。事实并非如此
建议永久交换目标数据提供程序
注册。一个已注册实例应全局管理所有
整个基础架构环境的目标配置
因此,您必须注册一个DestinationDataProvider
实例,这是类MyDestinationDataProvider
的实例。
此实施需要管理和存储所有SAP系统的所有不同登录配置,可通过不同的目标名称字符串访问。一个简单的HashMap
就足够了。将两个具有不同目标名称字符串的属性
实例添加到HashMap
中,并从方法MyDestinationDataProvider.getDestinationProperties(String destinationName)
返回与传递的destinationName关联的属性
实例。
因此,您可以通过特定的目标名称访问针对任何SAP系统的所需JCoDestination
实例。在您的示例中,两种目标配置都使用了“SAP_服务器”,但这两种配置都不起作用。例如,使用SAP系统ID(SID)作为目标名称(键)
如果使用示例中的名称,则
JCoDestinationManager.getDestination(“CRM”)
将返回系统“CRM”的JCoDestination
实例和系统“R3”的JCoDestination.getDestination(“R3”)
实例。而且两者都可以独立和同时使用。就是这样。与您分享我最近针对这个问题提出的解决方案。我发现了两种不同的方法来实现CustomDestinationDataProvider,这样我就可以使用多个目的地
我在两种不同的解决方案中所做的一件事是改变CustomDestinationDataProvider中实例化MyDestinationDataProvider内部类的方法,以便它不返回ArrayList,而是返回JCoDestination。我将此方法的名称从ExecuteSAppCall更改为getDestination
我发现允许我使用多个目的地并成功更改目的地的第一种方法是为MyDestinationDataProvider引入一个类变量,这样我就可以保留实例化的版本。请注意,对于这个解决方案,CustomDestinationDataProvider类仍然嵌入在我的java应用程序代码中
我发现这个解决方案只适用于一个应用程序。我无法在同一个tomcat服务器上的多个应用程序中使用此机制,但至少我最终能够成功地切换目的地。以下是第一个解决方案的CustomDestinationDataProvider.java代码:
public class CustomDestinationDataProvider {
private MyDestinationDataProvider gProvider; // class version of MyDestinationDataProvider
public class MyDestinationDataProvider implements DestinationDataProvider {
private DestinationDataEventListener eL;
private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
public Properties getDestinationProperties(String destinationName) {
try {
Properties p = secureDBStorage.get(destinationName);
if(p!=null) {
if(p.isEmpty())
throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);
return p;
}
return null;
} catch(RuntimeException re) {
System.out.println("getDestinationProperties: Exception detected!!! message = " + re.getMessage());
throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);
}
}
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eL = eventListener;
}
public boolean supportsEvents() {
return true;
}
public void changeProperties(String destName, Properties properties) {
synchronized(secureDBStorage) {
if(properties==null) {
if(secureDBStorage.remove(destName)!=null) {
eL.deleted(destName);
}
} else {
secureDBStorage.put(destName, properties);
eL.updated(destName); // create or updated
}
}
}
}
public JCoDestination getDestination(String destName, Properties connectProperties) {
MyDestinationDataProvider myProvider = new MyDestinationDataProvider();
boolean destinationDataProviderRegistered = com.sap.conn.jco.ext.Environment.isDestinationDataProviderRegistered();
if (!destinationDataProviderRegistered) {
try {
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
gProvider = myProvider; // save our destination data provider in the class var
} catch(IllegalStateException providerAlreadyRegisteredException) {
throw new Error(providerAlreadyRegisteredException);
}
} else {
myProvider = gProvider; // get the destination data provider from the class var.
}
myProvider.changeProperties(destName, connectProperties);
JCoDestination dest = null;
try {
dest = JCoDestinationManager.getDestination(destName);
} catch(JCoException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
}
return dest;
同样,此解决方案仅在一个应用程序中有效。如果将此代码直接实现到多个应用程序中,则调用此代码的第一个应用程序将获得资源,而另一个应用程序将出错
我提出的第二个解决方案允许多个java应用程序同时使用CustomDestinationDataProvider类。我将CustomDestinationDataProvider类从应用程序代码中分离出来,并为其创建了一个单独的JavaSpring应用程序(不是web应用程序),目的是创建一个jar。然后,我将MyDestinationDataProvider内部类转换为单例。以下是CustomDestinationDataProvider的单例版本的代码:
public class CustomDestinationDataProvider {
public static class MyDestinationDataProvider implements DestinationDataProvider {
////////////////////////////////////////////////////////////////////
// The following lines convert MyDestinationDataProvider into a singleton. Notice
// that the MyDestinationDataProvider class has now been declared as static.
private static MyDestinationDataProvider myDestinationDataProvider = null;
private MyDestinationDataProvider() {
}
public static MyDestinationDataProvider getInstance() {
if (myDestinationDataProvider == null) {
myDestinationDataProvider = new MyDestinationDataProvider();
}
return myDestinationDataProvider;
}
////////////////////////////////////////////////////////////////////
private DestinationDataEventListener eL;
private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
public Properties getDestinationProperties(String destinationName) {
try {
Properties p = secureDBStorage.get(destinationName);
if(p!=null) {
if(p.isEmpty())
throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);
return p;
}
return null;
} catch(RuntimeException re) {
throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);
}
}
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eL = eventListener;
}
public boolean supportsEvents() {
return true;
}
public void changeProperties(String destName, Properties properties) {
synchronized(secureDBStorage) {
if(properties==null) {
if(secureDBStorage.remove(destName)!=null) {
eL.deleted(destName);
}
} else {
secureDBStorage.put(destName, properties);
eL.updated(destName); // create or updated
}
}
}
}
public JCoDestination getDestination(String destName, Properties connectProperties) throws Exception {
MyDestinationDataProvider myProvider = MyDestinationDataProvider.getInstance();
boolean destinationDataProviderRegistered = com.sap.conn.jco.ext.Environment.isDestinationDataProviderRegistered();
if (!destinationDataProviderRegistered) {
try {
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
} catch(IllegalStateException providerAlreadyRegisteredException) {
throw new Error(providerAlreadyRegisteredException);
}
}
myProvider.changeProperties(destName, connectProperties);
JCoDestination dest = null;
try {
dest = JCoDestinationManager.getDestination(destName);
} catch(JCoException ex) {
ex.printStackTrace();
throw ex;
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
return dest;
}
}
我还将这个jar文件的副本放在工作站上的“C:\Users\userid\Documents\jars”文件夹中,以便测试应用程序代码可以看到jar中的代码并进行编译。然后我引用了这个公司
public class CustomDestinationDataProvider {
public static class MyDestinationDataProvider implements DestinationDataProvider {
////////////////////////////////////////////////////////////////////
// The following lines convert MyDestinationDataProvider into a singleton. Notice
// that the MyDestinationDataProvider class has now been declared as static.
private static MyDestinationDataProvider myDestinationDataProvider = null;
private MyDestinationDataProvider() {
}
public static MyDestinationDataProvider getInstance() {
if (myDestinationDataProvider == null) {
myDestinationDataProvider = new MyDestinationDataProvider();
}
return myDestinationDataProvider;
}
////////////////////////////////////////////////////////////////////
private DestinationDataEventListener eL;
private HashMap<String, Properties> secureDBStorage = new HashMap<String, Properties>();
public Properties getDestinationProperties(String destinationName) {
try {
Properties p = secureDBStorage.get(destinationName);
if(p!=null) {
if(p.isEmpty())
throw new DataProviderException(DataProviderException.Reason.INVALID_CONFIGURATION, "destination configuration is incorrect", null);
return p;
}
return null;
} catch(RuntimeException re) {
throw new DataProviderException(DataProviderException.Reason.INTERNAL_ERROR, re);
}
}
public void setDestinationDataEventListener(DestinationDataEventListener eventListener) {
this.eL = eventListener;
}
public boolean supportsEvents() {
return true;
}
public void changeProperties(String destName, Properties properties) {
synchronized(secureDBStorage) {
if(properties==null) {
if(secureDBStorage.remove(destName)!=null) {
eL.deleted(destName);
}
} else {
secureDBStorage.put(destName, properties);
eL.updated(destName); // create or updated
}
}
}
}
public JCoDestination getDestination(String destName, Properties connectProperties) throws Exception {
MyDestinationDataProvider myProvider = MyDestinationDataProvider.getInstance();
boolean destinationDataProviderRegistered = com.sap.conn.jco.ext.Environment.isDestinationDataProviderRegistered();
if (!destinationDataProviderRegistered) {
try {
com.sap.conn.jco.ext.Environment.registerDestinationDataProvider(myProvider);
} catch(IllegalStateException providerAlreadyRegisteredException) {
throw new Error(providerAlreadyRegisteredException);
}
}
myProvider.changeProperties(destName, connectProperties);
JCoDestination dest = null;
try {
dest = JCoDestinationManager.getDestination(destName);
} catch(JCoException ex) {
ex.printStackTrace();
throw ex;
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
return dest;
}
}
shared.loader=\
${catalina.home}/shared/lib\*.jar,${catalina.home}/shared/lib
<dependency>
<groupId>com.mycompany</groupId>
<artifactId>jcoconnector</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>C:\Users\userid\Documents\jars\JCOConnector.jar</systemPath>
</dependency>
CustomDestinationDataProvider cddp = new CustomDestinationDataProvider();
JCoDestination dest = null;
SAPDAO sapDAO = new SAPDAO();
Properties p1 = getProperties("SAPSystem01");
try {
dest = cddp.getDestination("SAP_R3_USERID_01", p1);
sapDAO.searchEmployees(dest);
} catch (Exception ex) {
ex.printStackTrace();
}
CustomDestinationDataProvider cddp = new CustomDestinationDataProvider();
JCoDestination dest = null;
SAPDAO sapDAO = new SAPDAO();
Properties p2 = getProperties("SAPSystem02");
try {
dest = cddp.getDestination("SAP_R3_USERID_02", p2);
sapDAO.searchAvailability(dest);
} catch (Exception ex) {
ex.printStackTrace();
}