最近要把一个很老的系统的接口对接到新的平台里,他原来接口使用的是webservice, 我问了我同事,这个接口支持rfc直连和po调用,(是啥我也不知道,估计这玩意比我年龄都大了吧)

先说一下代码生成


准备

sap连接:
http://xxx.com.cn:xxx/dir/wsdl?p=ic/c2cc333eab52e471f07eea50
注意:这个地址只是用来代码生成的,调用不能写这个地址,写这个xml中最下面有两个地址中的一个作为调用地址

<wsdl:service name="SI_ACDOCA_ZYD_OUTService">
<wsdl:port name="HTTP_Port" binding="p1:SI_ACDOCA_ZYD_OUTBinding">
<soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" location="http://xxx.xxxx.com.cn:xxx/XISOAPAdapter/MessageServlet?senderParty=&senderService=BC_COMMON&receiverParty=&receiverService=&interface=SI_ACDOCA_ZYD_OUT&interfaceNamespace=http%3A%2F%xxxx.com%2Fxi%2Fcom"/>
</wsdl:port>
<wsdl:port name="HTTPS_Port" binding="p1:SI_ACDOCA_ZYD_OUTBinding">
<soap:address xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" location="https://xxx.xxxx.com.cn:xxxx/XISOAPAdapter/MessageServlet?senderParty=&senderService=BC_COMMON&receiverParty=&receiverService=&interface=SI_ACDOCA_ZYD_OUT&interfaceNamespace=http%3A%2F%xxxx.com%xx%2Fcom"/>
</wsdl:port>
</wsdl:service>

环境变量配置

代码生成

方式一

  • 本地新建文件auth.txt

  • 写入内容

    http://用户名:密码@xxxx.xxx.com.cn:xxx/dir/wsdl?p=ic/xxxxxxxxxxxxxxxxxxx

  • 在本地执行命令

    wsimport -d E:\zlb\test -Xauthfile E:\zlb\test\auth.txt -p com.xx.dms.xxxx.xx -encoding utf-8 -keep http://xxxx.xxxx.com.cn:xxx/dir/wsdl?p=ic/xxxxxxxxxxxxxxxxxxxxxxxx

方式二

  • 访问sap地址,将xml保存到本地

  • 在本地执行命令

    wsimport -s . wsdl.xml -p 包名 -encoding utf-8


注意: 一定不要使用代理,会报错

代码调用

引入jar包

<webservice-cxf.version>3.4.10</webservice-cxf.version>
            <!--        webservice-->
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-core</artifactId>
                <version>{webservice-cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-frontend-jaxws</artifactId>
                <version>{webservice-cxf.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.cxf</groupId>
                <artifactId>cxf-rt-transports-http-jetty</artifactId>
                <version>${webservice-cxf.version}</version>
            </dependency>
            <!--        webservice-->

封装抽象类

/**
 * @author: lpy
 * @Date: 2023/11/24
 * @desc: P: execute方法的执行参数  R:execute方法的返回值
 */
public abstract class WebServiceExecute<P,R> {


    /**
     * 抽象执行方法,子类需要重写,然后设置
     * @param parameters 请求体(代码自动生成的,例如coszyd01就是包含了items和header的类ZFIACDOCAZYD01)
     * @return
     */
    public abstract R execute(P parameters);

    /**
     * 设置用户名密码,获取到auth后的bean,用来调用接口,并且设置连接信息
     * @param address 调用地址
     * @param username
     * @param password
     * @param serviceClass 生成的代码中的接口名
     * @param <T>
     * @return
     */
    protected <T> T createInstanceAndSetConnectionInf(String address, String username, String password, Class<T> serviceClass){
        JaxWsProxyFactoryBean clientFactory = new JaxWsProxyFactoryBean();
        clientFactory.setAddress(address);
        clientFactory.setServiceClass(SIACDOCAZYDOUT.class);
        clientFactory.setUsername(username);
        clientFactory.setPassword(password);
        T cast = serviceClass.cast(clientFactory.create());

        // 设置连接信息
        setConnectInformation(cast);

        return cast;
    }

    /**
     * 设置连接信息
     * @param service
     * @param <T>
     */
    protected <T> void setConnectInformation(T service) {
        ClientImpl client = (ClientImpl) ClientProxy.getClient(service);
        HTTPConduit http = (HTTPConduit) client.getConduit();
        HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy();
        httpClientPolicy.setConnectionTimeout(30 * 60 * 1000);
        httpClientPolicy.setAllowChunking(false);
        httpClientPolicy.setReceiveTimeout(30 * 60 * 1000);
        http.setClient(httpClientPolicy);
    }


    /**
     * 是否执行成功
     * @param resp
     * @return
     */
    public abstract boolean isExecutedSuccess(R resp);
}

execute方法

/**
 * @author: lpy
 * @Date: 2023/11/23
 */
@Component
@Slf4j
public class CosZYD01Execute extends WebServiceExecute<ZFIACDOCAZYD01, ZFIACDOCAZYD01Response> {
    @Value("{ws.coszyd01.address}")
    private String address;
    @Value("{ws.coszyd01.username}")
    private String username;
    @Value("${ws.coszyd01.password}")
    private String password;

    @Override
    public ZFIACDOCAZYD01Response execute(ZFIACDOCAZYD01 parameters) {

        // 设置访问地址 用户名 密码
        SIACDOCAZYDOUT getConfirmationDeduction = super.createInstanceAndSetConnectionInf(address, username, password, SIACDOCAZYDOUT.class);

        /**执行方法*/
        log.info("coszyd01-execute-paramters:{}", JSON.toJSONString(parameters));
        ZFIACDOCAZYD01Response returnInfo = getConfirmationDeduction.siACDOCAZYDOUT(parameters);
        log.info("coszyd01-execute-return:{}", JSON.toJSONString(returnInfo));

        return returnInfo;
    }

    /**
     * 消息类型: S 成功,E 错误,W 警告,I 信息,A 中断
     *
     * @param resp
     * @return
     */
    @Override
    public boolean isExecutedSuccess(ZFIACDOCAZYD01Response resp) {
        String EV_STATUS = resp.getEVSTATUS();
        return "S".equals(EV_STATUS);
    }
}

调用

@GetMapping("/cos01Test")
    public String tem() {
        CosZYD01ObjectFactory objectFactory = new CosZYD01ObjectFactory();

        // 组装请求体
        // 请求体
        ZFIACDOCAZYD01 parameters= objectFactory.createZFIACDOCAZYD01();
        // header
        ZSFIACDOCZYD01HEADER parameterslist = objectFactory.createZSFIACDOCZYD01HEADER();
        parameterslist.setBUSINESSTYPE("xx");
        parameterslist.setCOMPCODE("xx");

        ZFIACDOCAZYD01.ITITEMS ititems = new ZFIACDOCAZYD01.ITITEMS();
        ZSFIACDOCZYD01ITEM item = objectFactory.createZSFIACDOCZYD01ITEM();

        item.setAMOUNT1(new BigDecimal("114"));
                ititems.getItem().add(item);

        // header赋值
        parameters.setISHEADER(parameterslist);
        // items赋值
        parameters.setITITEMS(ititems);

        // 调用
        ZFIACDOCAZYD01Response resp = cosZYD01Execute.execute(parameters);
        boolean executedSuccess = cosZYD01Execute.isExecutedSuccess(resp);
        return executedSuccess+"";
    }
}

记录

中间花费了很长时间,不是因为代码问题,调试了两天,一直出现405,method is not allowed, 我万万没想到是调用地址的问题,也就是文章一开头那里写的,我万万没想到这个xml竟然不是调用的地址,巨恶心,我讨厌webservice,那里有json这么轻巧啊

参考文献

分类: 随笔

0 条评论

发表评论

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注

ICP备案号: 辽ICP备20003309号