建议您将随连接器一起交付的 BAPI 业务对象处理程序用作模板(有关详细信息,请参阅业务对象处理),而不用编写您自己的业务对象处理程序。使用定制业务对象处理程序的原因如下:
如果您决定创建定制业务对象处理程序,请将以下示例作为如何编写定制业务对象处理程序的指南。注意,SAPODA 不会为您生成代码。
package bapi.client ;
import AppSide_Connector.JavaConnectorUtil;
import CxCommon.BusinessObjectInterface;
import CxCommon.CxMsgFormat;
import CxCommon.CxStatusConstants;
import CxCommon.ReturnStatusDescriptor;
import com.crossworlds.connectors.sap.codegen.BapiBOHandlerBase;
import com.crossworlds.connectors.sap.codegen.exception.CwBoHandlerAppResponseTimeout;
import com.crossworlds.connectors.sap.codegen.exception.CwBoHandlerProcessingFailed;
import com.crossworlds.connectors.sap.visionframework.VisionBOHandlerInterface;
import com.crossworlds.connectors.sap.visionframework.VisionConnectorAgent;
import com.sap.mw.jco.IRepository;
import com.sap.mw.jco.JCO;
public class Bapi_customer_getlist extends BapiBOHandlerBase implements VisionBOHandlerInterface {
private static VisionConnectorAgent vca = VisionConnectorAgent.getCWSapConnManager();
private IRepository repository = getRepository();
private JCO.Function bapicommit = new JCO.Function(repository.
getFunctionTemplate("BAPI_TRANSACTION_COMMIT"));
private int checkBapiReturn = CxStatusConstants.SUCCEED;
public Bapi_customer_getlist()
{
}
public int doVerbForVision(BusinessObjectInterface theObj, ReturnStatusDescriptor rtn)
{
JCO.Function function = new JCO.Function(repository.getFunctionTemplate("BAPI_CUSTOMER_GETLIST"));
//Default processing to failure
int mReturnCode = CxStatusConstants.FAIL;
JCO.Client theClient = null;
try
{
traceMessage(JavaConnectorUtil.LEVEL1, 27025, CxMsgFormat.XRD_INFO, theObj.getName(), theObj.getVerb(),
null, null);
// get defaults and check for required fields for Create and Update only
if ((theObj.getVerb().equalsIgnoreCase("Create")) || (theObj.getVerb().equalsIgnoreCase("Update")))
{
traceMessage(JavaConnectorUtil.LEVEL4, 27021, CxMsgFormat.XRD_INFO, theObj.getName(),
null, null, null);
JavaConnectorUtil.initAndValidateAttributes(theObj);
}
// get a new connection to Sap
theClient = this.getClient();
// populate Rfc interface parameters
mReturnCode = doBusObjtoRfcData(theObj, function, function.getImportParameterList(),"I",false);
if (mReturnCode != CxStatusConstants.SUCCEED)
{
if (theClient != null) vca.releaseClient(theClient);
return CxStatusConstants.FAIL;
}
// Execute Rfc Call
this.callBapi(theClient,function);
try {
// After successful RfcCall: check Structure/Table RETURN for Bapi Return Codes E or A that
// indicate failure
this.checkBapiRc(function);
// After successful Bapi Call: call BAPI_TRANSACTIOM_COMMIT
this.callBapiCommit(theClient);
} catch (CwBoHandlerProcessingFailed cwpf) {
rtn.setErrorString(cwpf.getMessage());
rtn.setStatus(CxStatusConstants.FAIL);
checkBapiReturn = CxStatusConstants.FAIL;
}
// Now create CW Business Object
mReturnCode = doRfcDatatoBusObj(theObj, function , function.getExportParameterList(), "E");
if (mReturnCode != CxStatusConstants.SUCCEED || checkBapiReturn != CxStatusConstants.SUCCEED)
{
if (theClient != null) vca.releaseClient(theClient);
return CxStatusConstants.FAIL;
}
// Clean up
if (theClient != null) vca.releaseClient(theClient);
// Finally, return success to ICS
traceMessage(JavaConnectorUtil.LEVEL1, 27034, CxMsgFormat.XRD_INFO, theObj.getName(),
null, null, null);
return CxStatusConstants.VALCHANGE;
}//end of try
catch (CxCommon.Exceptions.SetDefaultFailedException sdfe)
{
if (theClient != null) vca.releaseClient(theClient);
String msg = logMessage(20059, CxMsgFormat.XRD_INFO, theObj.getName(), null, null, null);
rtn.setErrorString(msg);
rtn.setStatus(CxStatusConstants.FAIL);
return CxStatusConstants.FAIL;
}
catch (CxCommon.Exceptions.BusObjSpecNameNotFoundException c)
{
if (theClient != null) vca.releaseClient(theClient);
String msg = logMessage(20059, CxMsgFormat.XRD_INFO, theObj.getName(), null, null, null);
rtn.setErrorString(msg);
rtn.setStatus(CxStatusConstants.FAIL);
return CxStatusConstants.FAIL;
}
catch (CwBoHandlerAppResponseTimeout art)
{
if (theClient != null) vca.releaseClient(theClient);
rtn.setErrorString(art.getMessage());
rtn.setStatus(CxStatusConstants.APPRESPONSETIMEOUT);
return CxStatusConstants.APPRESPONSETIMEOUT;
}
catch (CwBoHandlerProcessingFailed cwpf)
{
if (theClient != null) vca.releaseClient(theClient);
rtn.setErrorString(cwpf.getMessage());
rtn.setStatus(CxStatusConstants.FAIL);
return CxStatusConstants.FAIL;
}
catch (Exception e)
{
if (theClient != null) vca.releaseClient(theClient);
rtn.setErrorString(e.getMessage());
rtn.setStatus(CxStatusConstants.FAIL);
return CxStatusConstants.FAIL;
}
catch ( OutOfMemoryError merr ){ // CR 30185
String msg = logMessage(23060, JavaConnectorUtil.XRD_ERROR,
"doVerbForVision()", merr.toString(), null, null);
rtn.setErrorString(msg);
rtn.setStatus(CxStatusConstants.APPRESPONSETIMEOUT);
return CxStatusConstants.APPRESPONSETIMEOUT;
}
catch ( StackOverflowError serr ){ // CR 30185
String msg = logMessage(23060, JavaConnectorUtil.XRD_ERROR,
"doVerbForVision()", serr.toString(), null, null);
rtn.setErrorString(msg);
rtn.setStatus(CxStatusConstants.APPRESPONSETIMEOUT);
return CxStatusConstants.APPRESPONSETIMEOUT;
}
catch (Throwable ex) {
// 23046 EXception raised in: {1} : ErrorMessage: {2}.
String msg = logMessage(23046, JavaConnectorUtil.XRD_ERROR,
"doVerbForVision()",ex.toString(), null, null);
return CxStatusConstants.FAIL;
}
}// end of doVerbforVision
public int callBapiCommit(JCO.Client theClient) throws
CwBoHandlerProcessingFailed, CwBoHandlerAppResponseTimeout
{
int mStatus = CxStatusConstants.FAIL;
try {
traceMessage(JavaConnectorUtil.LEVEL3, 27032, CxMsgFormat.XRD_INFO, null, null, null, null);
try
{
theClient.execute(bapicommit);
}
catch (JCO.Exception e)
{
String msg = logMessage(27019, CxMsgFormat.XRD_ERROR, null, null,
null, null);
throw new CwBoHandlerProcessingFailed(msg);
}
// Read Return
readBapiRc(bapicommit.getExportParameterList().getStructure("RETURN"));
}// end of try
catch (Exception e)
{
String msg = logMessage(27019, CxMsgFormat.XRD_ERROR, null, null,
null, null);
throw new CwBoHandlerProcessingFailed(e.getMessage());
}
// Return Success
return CxStatusConstants.SUCCEED;
}
public void checkBapiRc(JCO.Function function) throws CwBoHandlerProcessingFailed
{
try
{
JCO.ParameterList p = function.getTableParameterList();
this.readBapiRc(p.getTable("RETURN"));
}
catch (CwBoHandlerProcessingFailed cw)
{
throw cw;
}
catch (Exception e)
{
try
{
JCO.ParameterList p = function.getExportParameterList();
if (p != null)
this.readBapiRc(p.getStructure("RETURN"));
else
{
String msg = logMessage(27045, CxMsgFormat.XRD_INFO, null,null, null, null);
throw new CwBoHandlerProcessingFailed(msg);
}
}//end try
catch (JCO.Exception o)
{
String msg = logMessage(27045, CxMsgFormat.XRD_INFO, null,null, null, null);
throw new CwBoHandlerProcessingFailed(msg);
}
}
}// end of checkBapiRc
public void readBapiRc(JCO.Structure Return) throws CwBoHandlerProcessingFailed
{
String type = null;
String no = null;
String message = null;
traceMessage(JavaConnectorUtil.LEVEL4, 27033, CxMsgFormat.XRD_INFO, null, null, null, null);
if (Return.getString("TYPE") != null)
{
// Depending on RETURN ddic structure, number field is either "NUMBER" or "CODE".
try
{
no = Return.getString("NUMBER");
}
catch (JCO.Exception o)
{
no = Return.getString("CODE");
}
message = Return.getString("MESSAGE");
type = Return.getString("TYPE");
if ((type.equalsIgnoreCase("A")) || (type.equalsIgnoreCase("E")))
{
String msg = logMessage(27015, CxMsgFormat.XRD_ERROR, type, no,
message, null);
throw new CwBoHandlerProcessingFailed(msg);
}
else
{
traceMessage(JavaConnectorUtil.LEVEL1, 27016, CxMsgFormat.XRD_INFO,
type, no, message, null);
return;
}
}
// If structure Return is empty, it will be assumed that processing was
successful
traceMessage(JavaConnectorUtil.LEVEL1, 27036, CxMsgFormat.XRD_INFO, type, no, message, null);
}
public void readBapiRc(JCO.Table Return) throws CwBoHandlerProcessingFailed
{
String type = null;
String no = null;
String message = null;
String msg = null;
String errorMsg = "";
int mStatus = CxStatusConstants.SUCCEED;
traceMessage(JavaConnectorUtil.LEVEL4, 27033, CxMsgFormat.XRD_INFO, null, null, null, null);
for (int i=0; i<Return.getNumRows(); i++)
{
try
{
Return.setRow(i);
if (Return.getString("TYPE") != null)
{
type = Return.getString("TYPE");
// Depending on RETURN ddic structure, number field is either "NUMBER" or "CODE".
try
{
no = Return.getString("NUMBER");
}
catch (JCO.Exception e)
{
no = Return.getString("CODE");
}
message = Return.getString("MESSAGE");
}//end if
}//end try
catch (Exception o)
{
// Could not interprete Return structure ==> Failing event
msg = logMessage(27043, CxMsgFormat.XRD_ERROR, type, no,
message, null);
throw new CwBoHandlerProcessingFailed(msg);
}
if (type != null)
{
if ((type.equalsIgnoreCase("A")) || (type.equalsIgnoreCase("E")))
{
msg = logMessage(27015, CxMsgFormat.XRD_ERROR, type, no,
message, null);
mStatus = CxStatusConstants.FAIL;
}//end if
else
{
traceMessage(JavaConnectorUtil.LEVEL1, 27044, CxMsgFormat.XRD_INFO,
type, no, message, null);
}
}//end if type != null
}//end of for
if (mStatus == CxStatusConstants.FAIL)
{
logMessage(27046, CxMsgFormat.XRD_ERROR, msg, null, null, null);
throw new CwBoHandlerProcessingFailed(msg);
}
// If Return is empty, it will be assumed that processing was successful
if (Return.getNumRows() <= 0)
traceMessage(JavaConnectorUtil.LEVEL1, 27036, CxMsgFormat.XRD_INFO, type, no, message, null);
else
traceMessage(JavaConnectorUtil.LEVEL1, 27011, CxMsgFormat.XRD_INFO, null, null, null, null);
}//end of ReadBapiRc
};
以下示例举例说明了一个用于在 Windows 平台上编译定制 BOHandler 的脚本。注意,要运行此脚本,必须在您的机器上安装 JDK。
REM @echo off REM
REM init environment
call "%CROSSWORLDS%"\bin\CWODAEnv.bat
setlocal
REM set classpaths
set WBIA=%CROSSWORLDS%"\lib\WBIA\4.2.0\WBIA.jar
set CWLIB=%CROSSWORLDS%"\lib\CrossWorlds.jar
set AGENT="%CROSSWORLDS%"\ODA\SAP\SAPODA.jar
set JCO_JAR="%CROSSWORLDS%"\ODA\SAP\sapjco.jar
set JCLASSES=%AGENT%;%JCO_JAR%;%CWLIB%;%WBIA%
echo classpath = %JCLASSES%
REM compile the BAPI BOHandler passed as argument
javac -verbose -classpath %JCLASSES% %1
endlocal
pause