Spring boot 通过RFC连接SAP部署到Docker(二)
成家上文
8.实现CustomJcoService类的方法CustomJcoServiceImpl
package com.cfmoto.sap.api.service.impl;
import com.cfmoto.sap.api.config.CustomDestinationDataProvider;
import com.cfmoto.sap.api.config.JcoProviderConfig;
import com.cfmoto.sap.api.service.CustomJcoService;
import com.cfmoto.sap.api.utils.CustomBusinessException;
import com.cfmoto.sap.api.utils.R;
import com.sap.conn.jco.*;
import com.sap.conn.jco.ext.DestinationDataProvider;
import com.sap.conn.jco.ext.Environment;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
public class CustomJcoServiceImpl implements CustomJcoService {
@Autowired
private JcoProviderConfig jcoProviderConfig;
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat( "yyyy-MM-dd" );
//构造方法之后执行
@PostConstruct
public void init(){
/**
* 初始化配置参数 连接池
*/
Properties connectProperties = new Properties();
//ERP服务器IP地址
connectProperties.setProperty(DestinationDataProvider.JCO_ASHOST, jcoProviderConfig.getJcoAshost() );
//实例编号
connectProperties.setProperty(DestinationDataProvider.JCO_SYSNR, jcoProviderConfig.getJcoSysnr() );
//客户端
connectProperties.setProperty(DestinationDataProvider.JCO_CLIENT, jcoProviderConfig.getJcoClient() );
//用户名
connectProperties.setProperty(DestinationDataProvider.JCO_USER, jcoProviderConfig.getJcoUser() );
//密码
connectProperties.setProperty(DestinationDataProvider.JCO_PASSWD, jcoProviderConfig.getJcoPasswd() );
// JCO_PEAK_LIMIT - 同时可创建的最大活动连接数,0表示无限制,默认为JCO_POOL_CAPACITY的值
// 如果小于JCO_POOL_CAPACITY的值,则自动设置为该值,在没有设置JCO_POOL_CAPACITY的情况下为0
connectProperties.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, jcoProviderConfig.getJcoPoolCapacity() );
//同时可创建的最大活动连接数,0表示无限制,默认为JCO_POOL_CAPACITY的值
connectProperties.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, jcoProviderConfig.getJcoPeakLimit() );
//语言
connectProperties.setProperty(DestinationDataProvider.JCO_LANG, jcoProviderConfig.getJcoLang() );
//开启R/3需要该行配置
connectProperties.setProperty(DestinationDataProvider.JCO_SAPROUTER, jcoProviderConfig.getJcoSaprouter() );
CustomDestinationDataProvider provider = new CustomDestinationDataProvider();
Environment.registerDestinationDataProvider( provider );
provider.addDestinationProperties( jcoProviderConfig.getJcoDestName(), connectProperties );
}
//测试连接是否连通
@Override
public R pingCalls(String destName ){
JCoDestination dest;
try{
dest = JCoDestinationManager.getDestination( destName );
dest.ping();
return new R<>( R.SUCCESS, "success" );
}catch( JCoException e ){
return new R<>( R.FAIL, ExceptionUtils.getFullStackTrace( e ) );
}
}
/**
* 传入功能名称和Map类型参数
* @param functionName
* @param paramMap
* @return
*/
@Override
public R execute( String functionName, Map<String, Object> paramMap ) {
Map resultMap = new HashMap();
//传入参数 ---------------------------------------------------------------------------------------------------------------------------------------
try {
JCoDestination conn = JCoDestinationManager.getDestination( jcoProviderConfig.getJcoDestName() );
JCoFunction fun = conn.getRepository().getFunction( functionName );
if( fun==null ){
return new R( R.FAIL,functionName+"不存在" );
}
JCoParameterList input = fun.getImportParameterList();
if( paramMap != null ){
for( Iterator<Map.Entry<String, Object>> it = paramMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Object> pairs = it.next();
if( pairs.getValue() instanceof List) {
setTableParamList( fun, pairs );
} else if( pairs.getValue() instanceof Map ) {
setImportParameterList( fun, pairs );
} else {
input.setValue( "" + pairs.getKey(), pairs.getValue() );
}
}
}
JCoContext.begin( conn );
try {
//执行方法
fun.execute( conn );
} finally {
JCoContext.end( conn );
}
if( fun.getExportParameterList() != null ) {
getExportParameterList( fun, resultMap );
}
if( fun.getTableParameterList() != null ) {
getTableParameterList( fun, resultMap );
}
} catch( JCoException e ) {
return new R( R.FAIL, ExceptionUtils.getFullStackTrace( e ) );
} catch ( CustomBusinessException e) {
return new R( R.FAIL, ExceptionUtils.getFullStackTrace( e ) );
}catch ( Exception e ){
return new R( R.FAIL, ExceptionUtils.getFullStackTrace( e ) );
}
return new R<Map>( resultMap );
}
//设置表格传入参数
private void setTableParamList( JCoFunction fun, Map.Entry<String, Object> pairs ) throws CustomBusinessException{
JCoTable tb = fun.getTableParameterList().getTable( "" + pairs.getKey() );
List ls = (List) pairs.getValue();
for( int i = 0; i < ls.size(); i++ ) {
Map<String, String> m = (Map<String, String>) ls.get( i );
tb.appendRow();
for( JCoFieldIterator jft = tb.getFieldIterator(); jft.hasNextField(); ) {
JCoField p = jft.nextField();
if( "date".equalsIgnoreCase( p.getTypeAsString() ) ) {
if( m.containsKey( p.getName() ) ) {
if( !"".equals( m.get( p.getName() ) ) ) {
try {
p.setValue( simpleDateFormat.parse( m.get( p.getName() ) ) );
} catch (ParseException e) {
throw new CustomBusinessException( e );
}
} else {
p.setValue( "" );
}
}
} else {
if( m.containsKey( p.getName() ) ) {
if( m.get( p.getName() ) == null ) {
throw new CustomBusinessException( "参数" + p.getName() + "为null" );
}
p.setValue( m.get( p.getName() ) );
}
}
}
}
}
//设置列表传入参数
private void setImportParameterList(JCoFunction fun, Map.Entry<String, Object> pairs) throws CustomBusinessException{
Map<String, String> pairsMap = (Map<String, String>) pairs.getValue();
JCoStructure jcos = fun.getImportParameterList().getStructure( "" + pairs.getKey() );
for( JCoFieldIterator jft = jcos.getFieldIterator(); jft.hasNextField(); ) {
JCoField jf = jft.nextField();
if( "date".equalsIgnoreCase( jf.getTypeAsString() ) ) {
if( pairsMap.containsKey( jf.getName() ) ) {
if( !"".equals( pairsMap.get( jf.getName() ) ) ) {
try {
jf.setValue( simpleDateFormat.parse( pairsMap.get( jf.getName() ) ) );
} catch (ParseException e) {
throw new CustomBusinessException( e );
}
} else {
jf.setValue( "" );
}
} else {
throw new CustomBusinessException( "参数错误,没有准备参数【" + jf.getName() + "】" );
}
} else {
if( pairsMap.containsKey( jf.getName() ) ) {
if( pairsMap.get( jf.getName() ) == null ) {
throw new CustomBusinessException( "参数" + jf.getName() + "为null" );
}
jf.setValue( pairsMap.get( jf.getName() ) );
}
}
}
}
/**
* 获取输出参数列表
* @param fun
* @param resultMap
*/
private static void getExportParameterList( JCoFunction fun, Map resultMap ){
for( Iterator<JCoField> it = fun.getExportParameterList().iterator(); it.hasNext(); ) {
JCoField o = it.next();
if( o.isTable() ) {
JCoTable tb = (JCoTable) o;
List resultList = new ArrayList();
for( int i = 0; i < tb.getNumRows(); i++ ) {
Map retMap = new HashMap();
tb.setRow( i );
retMap = new HashMap();
for( JCoRecordFieldIterator itA = tb.getRecordFieldIterator(); itA.hasNextField(); ) {
JCoField field = itA.nextField();
retMap.put( field.getName(), tb.getString( field.getName() ) );
}
resultList.add( retMap );
}
resultMap.put( "" + o.getName(), resultList );
} else if( o.isStructure() ) {
JCoStructure st = o.getStructure();
Map resutStructureMap = new HashMap();
for( JCoFieldIterator jft = st.getFieldIterator(); jft.hasNextField(); ) {
JCoField jf = jft.nextField();
resutStructureMap.put( jf.getName(), jf.getValue() );
}
resultMap.put( "" + o.getName(), resutStructureMap );
} else {
resultMap.put( "" + o.getName(), o.getValue() );
}
}
}
private static void getTableParameterList( JCoFunction fun, Map resultMap ){
for( Iterator<JCoField> it = fun.getTableParameterList().iterator(); it.hasNext(); ) {
JCoField o = it.next();
if( o.isTable() ) {
JCoTable tb = o.getTable();
List resultList = new ArrayList();
for( int i = 0; i < tb.getNumRows(); i++ ) {
Map retMap = new HashMap();
tb.setRow( i );
retMap = new HashMap();
for( JCoRecordFieldIterator itA = tb.getRecordFieldIterator(); itA.hasNextField(); ) {
JCoField field = itA.nextField();
retMap.put( field.getName(), tb.getString( field.getName() ) );
}
resultList.add( retMap );
}
resultMap.put( "" + o.getName(), resultList );
} else if( o.isStructure() ) {
JCoStructure st = o.getStructure();
Map resutStructureMap = new HashMap();
for( JCoFieldIterator jft = st.getFieldIterator(); jft.hasNextField(); ) {
JCoField jf = jft.nextField();
resutStructureMap.put( jf.getName(), jf.getValue() );
}
resultMap.put( "" + o.getName(), resutStructureMap );
} else {
resultMap.put( "" + o.getName(), o.getValue() );
}
}
}
}
9.添加异常类
package com.cfmoto.sap.api.utils;
/**
* 自定义异常类,可以处理一些配置
*/
public class CustomBusinessException extends Exception{
public CustomBusinessException(){
super();
}
public CustomBusinessException( String message ){
super( message );
}
public CustomBusinessException( String message, Throwable throwable ){
super( message, throwable );
}
public CustomBusinessException( Throwable cause ){
super( cause );
}
public CustomBusinessException( String message, Throwable cause,
boolean enableSuppression,
boolean writableStackTrace ) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
10.添加响应信息主体
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of the pig4cloud.com developer nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
* Author: lengleng ([email protected])
*/
package com.cfmoto.sap.api.utils;
import java.io.Serializable;
/**
* 响应信息主体
*
* @param <T>
* @author lengleng
*/
public class R<T> implements Serializable {
private static final long serialVersionUID = 1L;
public static final int NO_LOGIN = -1;
public static final int SUCCESS = 0;
public static final int FAIL = 1;
public static final int NO_PERMISSION = 2;
private String msg = "success";
private int code = SUCCESS;
private T data;
public R() {
super();
}
public R(T data) {
super();
this.data = data;
}
public R(T data, String msg) {
super();
this.data = data;
this.msg = msg;
}
public R(Throwable e) {
super();
this.msg = e.getMessage();
this.code = FAIL;
}
public R(int code , String msg) {
super();
this.msg = msg;
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
此刻项目已经写好
接下来我们测试
建立一个controller测试CustomJcoController
package com.cfmoto.sap.api.controller;
import com.cfmoto.sap.api.config.JcoProviderConfig;
import com.cfmoto.sap.api.service.CustomJcoService;
import com.cfmoto.sap.api.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/customJco")
public class CustomJcoController {
@Autowired
private CustomJcoService customJcoService;
@Autowired
private JcoProviderConfig jcoProviderConfig;
@GetMapping("/pingJco")
public R pingCalls() {
R r = customJcoService.pingCalls( jcoProviderConfig.getJcoDestName() );
return r;
}
/**
* 传入功能名称和Map类型参数
* @param
* @return
*/
@PostMapping("/executeJcoFunction")
public R executeJcoFunction( @RequestBody Map<String,Object> param ){
Map<String, Object> paramMap = new HashMap<String, Object>();
String functionName = (String) param.get( "functionName" );
paramMap = (Map<String, Object>) param.get( "paramMap" );
if ( functionName==null ){
return new R( R.FAIL,"param未包含functionName参数" );
}
return customJcoService.execute( functionName, paramMap );
}
}
使用POSTMan测试