SpringBoot集成SAP,本地IDEA启动和Windows服务器部署

网上有关Springboot集成SAP有各种各样的说法,我这里提供一个我调通的方案。如下pom配置,sapjco3.dll 放在"%JAVA_HOME%\bin\",否则报nested exception is java.lang.NoClassDefFoundError: Could not initialize class com.sap.conn.jco.JCo,服务器部署时也是这样放置,

sapjco3.dll和sapjco3.jar放在resources\lib下

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.demo</groupId>
        <artifactId>OPM</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <groupId>com.demo</groupId>
    <artifactId>open-manager</artifactId>
    <packaging>jar</packaging>
    <name>open-manager</name>
    <description>open-manager</description>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>com.demo</groupId>
            <artifactId>common</artifactId>
            <!--不加版本无法引用-->
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.sapjco3</groupId>
            <artifactId>sapjco</artifactId>
            <version>3.0</version>
            <scope>system</scope>
            <systemPath>${pom.basedir}/src/main/resources/lib/sapjco3.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
    <profiles>
        <!-- 本地环境 -->
        <profile>
            <id>local</id>
            <properties>
                <spring.profiles.active>local</spring.profiles.active>
            </properties>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
        </profile>
        <!-- 开发环境 -->
        <profile>
            <id>dev</id>
            <properties>
                <spring.profiles.active>dev</spring.profiles.active>
            </properties>
        </profile>
        <!-- 生产环境 -->
        <profile>
            <id>prod</id>
            <properties>
                <spring.profiles.active>prod</spring.profiles.active>
            </properties>
        </profile>
    </profiles>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!--为false,取消本地的system的jar打入-->
                    <includeSystemScope>true</includeSystemScope>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.3.0</version>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/webapp</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <!-- true表示利用占位符进行替换 -->
                <filtering>true</filtering>
                <includes>
                    <!--Maven 资源过滤是为文本文件设计的(如属性文件、XML 等)-->
                    <include>**/*.properties</include>
                    <include>application.yml</include>
                    <!-- ${spring.profiles.active}就是我们指定的环境,会被替换掉 -->
                    <include>application-${spring.profiles.active}.yml</include>
                    <include>**/*.xml</include>
                    <include>**/*.html</include>
                    <include>**/*.json</include>
                    <include>webapp/</include>
                </includes>
                <excludes>
                    <!-- 排除目录 -->
                    <exclude>lib/**</exclude>
                    <exclude>**/*.jar</exclude>
                    <exclude>**/*.dll</exclude> <!--sapjco3.dll "%JAVA_HOME%\bin\"-->
                    <exclude>**/*.jks</exclude>
                    <exclude>**/*.png</exclude>
                </excludes>
            </resource>
            <!-- 新增:单独处理二进制文件(不进行过滤) -->
            <resource>
                <directory>src/main/resources/lib</directory>
                <filtering>false</filtering>
                <targetPath>BOOT-INF/lib</targetPath>  <!-- 关键修改 -->
                <includes>
                    <include>sapjco3.jar</include>
                </includes>
            </resource>
            <!-- 处理其他资源 -->
            <resource>
                <directory>src/main/resources</directory>
                <filtering>false</filtering>
                <targetPath>BOOT-INF/classes</targetPath>
                <excludes>
                    <exclude>lib/**</exclude> <!-- 排除已单独处理的 lib 目录 -->
                </excludes>
                <includes>
                    <include>**/*.jks</include>
                    <include>**/*.png</include>
                </includes>
            </resource>
        </resources>
    </build>

</project>
java 复制代码
package com.demo.openmanager.sap;

import com.demo.common.util.StringUtils;
import com.sap.conn.jco.JCoDestination;
import com.sap.conn.jco.JCoDestinationManager;
import com.sap.conn.jco.JCoException;
import com.sap.conn.jco.ext.DestinationDataProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;


@Slf4j
public class XpJco {
    @Value("${sap.host}")
    private String SAP_HOST;

    @Value("${sap.client}")
    private String SAP_CLIENT;

    @Value("${sap.sysno}")
    private String SAP_SYS_NO;

    @Value("${sap.user}")
    private String SAP_USER;

    @Value("${sap.pass}")
    private String SAP_PASS;

    @Value("${sap.lang}")
    private String SAP_LANG;

    @Value("${sap.poolCapacity}")
    private String SAP_POOL_CAPACITY;

    @Value("${sap.peakLimit}")
    private String SAP_PEAK_LIMIT;

    @Value("${sap.jcoSaprouter}")
    private String SAP_JCO_SAPROUTER;


    public synchronized JCoDestination getJCoDestination(String filename) {
        JCoDestination destination = null;
        try {
            destination = JCoDestinationManager.getDestination(filename);
        } catch (JCoException e) {
            e.printStackTrace();
        }
        return destination;
    }

    private static boolean creatSapPros(String filename, String host, String sysno, String client, String user, String pass,
                                        String lang, String pool_capacity, String peak_limit, String JCO_SAPROUTER) {
        Properties pros = new Properties();
        boolean iscreate = false;
        pros.clear(); // 先清空
        pros.setProperty(DestinationDataProvider.JCO_ASHOST, host);
        pros.setProperty(DestinationDataProvider.JCO_SYSNR, sysno);
        pros.setProperty(DestinationDataProvider.JCO_CLIENT, client);
        pros.setProperty(DestinationDataProvider.JCO_USER, user);
        pros.setProperty(DestinationDataProvider.JCO_PASSWD, pass);
        pros.setProperty(DestinationDataProvider.JCO_LANG, lang);
        pros.setProperty(DestinationDataProvider.JCO_POOL_CAPACITY, pool_capacity);
        pros.setProperty(DestinationDataProvider.JCO_PEAK_LIMIT, peak_limit);
        if (StringUtils.isNoneBlank(JCO_SAPROUTER)) {
            pros.setProperty(DestinationDataProvider.JCO_SAPROUTER, JCO_SAPROUTER);
        }
        iscreate = createFiles(filename, pros);
        if (iscreate) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * @param filename
     * @return
     */
    private static boolean isFileExist(String filename) {
        File file = new File(filename + ".jcoDestination");
        log.info("JCO path:" + file.getPath());
        log.info("JCO AbsolutePath:" + file.getAbsolutePath());
        // 最后会放在Q:\IdeaWork\OPM\tz02_ywk_jco.jcoDestination
        // 环境上是放在启动jar包所在同级目录
        return file.exists();
    }

    /**
     * @param filename
     * @param pros
     * @return
     */
    private static boolean createFiles(String filename, Properties pros) {
        File file = new File(filename + ".jcoDestination");

        FileOutputStream fos = null;
        if (!file.exists()) {
            try {
                log.info("********* 正在写入文件 **********");
                fos = new FileOutputStream(file, false);
                pros.store(fos, "Author: ljb");
                fos.close();
                return true;
            } catch (FileNotFoundException e) {
                log.info("-------- 找不到文件! ---------");
                e.printStackTrace();
                return false;
            } catch (IOException e) {
                log.info("-------- 内容写入失败! ---------");
                e.printStackTrace();
                return false;
            } finally {
                try {
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } else {
            return false;
        }
    }


    public synchronized JCoDestination getJCoDestination() {
        boolean isexist = false; // 判断文件是否存在
        boolean isCreate = false; // 创建pro文件
        JCoDestination destination;
        String filename = "tz02_ywk_jco";
        isexist = XpJco.isFileExist(filename);
        log.info("-- 获取JCoDestination isexist==" + isexist);
        if (isexist == true) {
            try {
                destination = JCoDestinationManager.getDestination(filename);
                return destination;
            } catch (JCoException e) {
                log.info("-- 获取JCoDestination失敗! --");
                e.printStackTrace();
                return null;
            }
        } else {
            isCreate = XpJco.creatSapPros(filename, SAP_HOST, SAP_SYS_NO, SAP_CLIENT, SAP_USER, SAP_PASS, SAP_PASS,
                    SAP_POOL_CAPACITY, SAP_PEAK_LIMIT, SAP_JCO_SAPROUTER);
            if (isCreate == true) {
                try {
                    destination = JCoDestinationManager.getDestination(filename);
                    log.info("获取JCoDestination!成功");
                    return destination;
                } catch (JCoException e) {
                    log.info("无法获取JCoDestination!");
                    e.printStackTrace();
                    return null;
                }
            } else { // 如果文件不存在
                return null;
            }
        }
    }
}
相关推荐
军军君012 小时前
基于Springboot+UniApp+Ai实现模拟面试小工具三:后端项目基础框架搭建上
前端·vue.js·spring boot·面试·elementui·微信小程序·uni-app
草履虫建模3 小时前
Ajax原理、用法与经典代码实例
java·前端·javascript·ajax·intellij-idea
简放4 小时前
Spring-AI系列-AI模型API
spring boot·aigc·openai
泉城老铁4 小时前
Gitee上开源主流的springboot框架一探究竟
spring boot·后端·架构
Unity___4 小时前
Unity Editor下拉框,支持搜索,多层级
windows·unity·游戏引擎
Yang's5 小时前
四种高效搭建SpringBoot项目的方式详解
java·spring boot·后端
bing_1585 小时前
在Spring Boot 开发中 Bean 的声明和依赖注入最佳的组合方式是什么?
java·spring boot·后端·bean
别来无恙1495 小时前
Spring Boot + MyBatis 实现用户登录功能详解(基础)
spring boot·后端·mybatis
TinpeaV6 小时前
Elasticsearch8 Windows安装教程
windows·spring boot·后端·elasticsearch