webservice 实现通知支付结果到OA

一,业务场景:

支付中心项目,oa发送支付请求到支付中心,支付完成要给oa回复,这个回复就是用webservice发送的。

我方相当于一个webservice客户端,oa相当于服务端。

二,我需要知道什么

*WSDL地址:

http://10.188.2.93:8081//services/PayService?wsdl

实现方式一,

根据以往的经验,通过webService调用接口

*用命令解析wsdl文件,生成客户端代码 wmimport -keep url

*调用客户端代码中的接口,访问服务端

参考下文

https://www.cnblogs.com/xdp-gacl/p/4260627.html

但是我们这个项目没有解析wsdl文件, 没有使用解析的客户端代码

实现方式二,基于axis实现,本项目采用这种方式实现

可参考:

https://blog.csdn.net/qq_33236248/article/details/80436688

*依赖

compile('com.liferay:org.apache.axis:1.4.LIFERAY-PATCHED-3')
compile('axis:axis-wsdl4j:1.5.1')
compile('commons-discovery:commons-discovery:20040218.194635')

*包装请求参数

定义参数格式,是OA方要求还是,我方定义好通知OA?

请求参数:需要给OA的

// OA付款申请编号
private String oaCode;
// 支付状态
private String payStatus;
// 付款时间
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date paymentDate;

@JsonFormat注解作用:
https://www.cnblogs.com/woshimrf/p/5189435.html

三,代码实现

1,封装请求参数

*原始请求参数

public class CallOaRequest {

    // OA付款申请编号
    private String oaCode;
    // 支付状态
    private String payStatus;
    // 付款时间
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date paymentDate;

*封装1

public class ReqData<T> implements Serializable {

    private static final long serialVersionUID = 6648835178847199263L;

    @JsonProperty("list")
    private List<T> list;

    public List<T> getList() {
        return list;
    }

    public void setList(List<T> list) {
        this.list = list;
    }
}

*封装2

public class ReqService<T> implements Serializable {

    private static final long serialVersionUID = -8153707350660508556L;

    @JsonProperty("Request")
    private ReqData<T> request;

    public ReqData<T> getRequest() {
        return request;
    }

    public void setRequest(ReqData<T> request) {
        this.request = request;
    }
}

*封装3 

@XmlRootElement
public class RestRequest<T> implements Serializable {

    private static final long serialVersionUID = -4637756210826669082L;

    @JsonProperty("Service")
    private ReqService<T> reqService;


    public ReqService<T> getReqService() {
        return reqService;
    }

    public void setReqService(ReqService<T> reqService) {
        this.reqService = reqService;
    }
}

2,业务代码调用工具类

*查询数据,获取webservice入参

同一个oa付款申请编号下,所有数据都支付完成,才可以发送给oa

相比以往处理方式,可使用stream分组

 /**
     * 通知【OA】支付结果
     *
     * @param ids
     * @return
     */
    @Override
    public String callOaPaymentResult(List<Integer> ids) {

        List<AccountSyncVo> voList = syncAccountService.getWaitSyncOaList(ids);
        //oa_code oa付款申请编号
        Map<String, List<AccountSyncVo>> groupBy = voList.stream().collect(Collectors.groupingBy(AccountSyncVo::getOaCode));
        ArrayList<List<AccountSyncVo>> arrayList = new ArrayList<>(groupBy.values());
        ArrayList<List<AccountSyncVo>> arrayList2 = new ArrayList<>(groupBy.values());
        for (List<AccountSyncVo> syncVos : arrayList) {
            for (AccountSyncVo vo : syncVos) {
                if (!Const.PAYSTATUS.equals(vo.getPayStatus())) {
                    arrayList2.remove(syncVos);
                    break;
                }
            }
        }
        List<CallOaRequest> requestList = new ArrayList<>();
        List<String> oaCodes = new ArrayList<>();
        for (List<AccountSyncVo> entities2 : arrayList2) {
            entities2 = entities2.stream().sorted(Comparator.comparing(AccountSyncVo::getPaymentDate).reversed()).collect(Collectors.toList());
            AccountSyncVo syncVo = entities2.get(0);
            CallOaRequest request = new CallOaRequest();
            BeanUtils.copyProperties(syncVo, request);
            request.setPayStatus("已完成");
            requestList.add(request);
            // OA付款申请编号
            oaCodes.add(syncVo.getOaCode());
        }
        StringBuilder sb = new StringBuilder();
        if (requestList.size() > 0) {
            List<String> failureOaCodes = new ArrayList<>();
            List<OaResponseVo> responseVos = externalApiService.pushMsgToOa(requestList);
            if (responseVos == null || responseVos.size() == 0) {
                failureOaCodes.addAll(oaCodes);
                oaCodes.clear();
            } else {
                for (OaResponseVo vo : responseVos) {
                    if (!StringUtils.isEmpty(vo.getStatus()) && Const.FAILURE.equals(vo.getStatus())) {
                        failureOaCodes.add(vo.getOaCode());
                        String str = "OA申请编号为【" + vo.getOaCode() + "】的数据:" + vo.getMsg() + "\n";
                        sb.append(str);
                    }
                }
                oaCodes.removeAll(failureOaCodes);
            }
            if (oaCodes.size() > 0) {
                syncAccountService.updateSyncOaStatus(oaCodes, 1);
            }
            if (failureOaCodes.size() > 0) {
                syncAccountService.updateSyncOaStatus(failureOaCodes, 2);
            }
        }

        return sb.toString();
    }

*封装请求参数 

@Slf4j
@Service
public class ExternalApiServiceImpl implements ExternalApiService {

    @Value("${PAYMENT_APPLY_OA_URL}")
    private String applyOaUrl;

    @Value("${PAYMENT_APPLY_ORACLE_URL}")
    private String applyOracleUrl;

    @Value("${PAYMENT_ORACLE_USERNAME}")
    private String oracleUsername;

    @Value("${PAYMENT_ORACLE_PASSWORD}")
    private String oraclePassword;

    @Autowired
    private ExternalApiMapper externalApiMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private OaMiddleMapper oaMiddleMapper;

    /**
     * 推送Oracle支付结果到OA
     *
     * @param oaRequestList
     * @return
     */
    @Override
    public List<OaResponseVo> pushMsgToOa(List<CallOaRequest> oaRequestList) {
        log.info(">>>>>> 开始请求访问 [ OA ] 接口: URL == " + applyOaUrl);
        RestRequest restRequest = new RestRequest();
        ReqService reqService = new ReqService();
        ReqData reqData = new ReqData();
        reqData.setList(oaRequestList);
        restRequest.setReqService(reqService);
        reqService.setRequest(reqData);
        List<OaResponseVo> voList;
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            //objectMapper转化为json字符串
            String object = objectMapper.writeValueAsString(restRequest);
            log.info(">>>>> apply [OA]<<<<< object == " + object);
            String response = HttpPostUtil.getServiceClient(applyOaUrl, object);
            if (StringUtils.isEmpty(response)) {
                return null;
            }
            System.out.println("<---[OA]---> response: " + response);
            JSONObject oaMsg = JSONObject.parseObject(response);
            JSONObject serviceRegion = (JSONObject) oaMsg.get("Service");
            JSONArray responseRegion = (JSONArray) serviceRegion.get("Response");
            voList = JSONObject.parseArray(responseRegion.toJSONString(), OaResponseVo.class);
        } catch (Exception e) {
            log.error("对外接口【OA】访问异常:");
            e.printStackTrace();
            return null;
        }
        return voList;
    }

    /**
     * 推送OA支付请求到Oracle
     *
     * @param request
     * @return
     */
    @Override
    public String pushMsgToOracle(CallOracleRequest request) {
        log.info(">>>>>> 开始请求访问 [ Oracle ] 接口: URL == " + applyOracleUrl);
        OracleRequest oracleRequest = new OracleRequest();
        OracleInput oracleInput = new OracleInput();
        OracleParameters parameters = new OracleParameters();
        BeanUtils.copyProperties(request, parameters);
        OracleRestHeader restHeader = new OracleRestHeader();
        // 封装请求头(此处请求头非Http请求头),请求体(非http请求体此处只有请求入参,http请求体包含此处请求+请求体)
        oracleInput.setRestHeader(restHeader);
        oracleInput.setParameters(parameters);
        oracleRequest.setOracleInput(oracleInput);
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            String object = objectMapper.writeValueAsString(oracleRequest);
            log.info(">>>>apply[Oracle]<<<< object == " + object);
            String up = oracleUsername + ":" + oraclePassword;
            String response = HttpPostUtil.getHttpClient(applyOracleUrl, object, up);
            System.out.println("<---[Oracle]---> response: " + response);
            JSONObject oracleMsg = JSONObject.parseObject(response);
            JSONObject outputParameters = (JSONObject) oracleMsg.get("OutputParameters");
            //oracle响应码响应消息
            String status = (String) outputParameters.get("X_RETURN_STATUS");
            String msg = (String) outputParameters.get("X_MSG_DATA");
            log.info(">>>>>> 收到来自【Oracle】的响应:msg == " + msg);
            if (StringUtils.isNotEmpty(status) && !Const.S.equals(status)) {
                return msg;
            }
        } catch (Exception e) {
            log.error("对外接口【Oracle】访问异常");
            e.printStackTrace();
            return "E";
        }
        return "";
    }

3,webservice工具类

/**
 * webService
 *
 * @param path url
 * @param stringObject 入参
 * @return
 */
public static String getServiceClient(String path, String stringObject) {
    String response = "";
    try {
        Service service = new Service();
        Call call = (Call) service.createCall();
        call.setTargetEndpointAddress(path);
        call.setOperationName(new QName("weaver.zzn.aj", "payResult"));
        Object[] param = new Object[]{stringObject};
        response = (String) call.invoke(param);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return response;
}
public class HttpPostUtil {

    private static final String BASICAUTH = "AN_JI:AJ_1113";

    /**
     * webService
     *
     * @param path url
     * @param stringObject 入参
     * @return
     */
    public static String getServiceClient(String path, String stringObject) {
        String response = "";
        try {
            Service service = new Service();
            Call call = (Call) service.createCall();
            call.setTargetEndpointAddress(path);
            call.setOperationName(new QName("weaver.zzn.aj", "payResult"));
            Object[] param = new Object[]{stringObject};
            response = (String) call.invoke(param);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return response;
    }


    public static void main(String[] args) {
        try {
            //字符集
            String encodingStyle = "utf-8";
            //WSDL的地址
            String endpoint = "http://www.webxml.com.cn/WebServices/RandomFontsWebService.asmx?wsdl";
            //命名空间,在WSDL中对应的标签是:参见说明第3条                                    
            String targetNamespace = "http://WebXml.com.cn/";
            //具体方法的调用URI,在WSDL中对应的标签是:参见说明第4条
            String soapActionURI = "http://WebXml.com.cn/getCharFonts";
            //具体调用的方法名,在WSDL中对应的标签是:参见说明第5条
            String method = "getCharFonts";
            //调用接口的参数的名字
            String[] paramNames = {"byFontsLength"};
            //调用接口的参数的值
            Integer[] paramValues = {1};

            Service service = new Service();
            Call call = (Call) service.createCall();
//            call.setTimeout(new Integer(20000));  //设置超时时间
            call.setSOAPActionURI(soapActionURI);
            call.setTargetEndpointAddress(new java.net.URL(endpoint));  //设置目标接口的地址
            call.setEncodingStyle(encodingStyle);//设置传入服务端的字符集格式如utf-8等
            call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);//返回值类型:String
            call.setOperationName(new QName(targetNamespace, method));// 具体调用的方法名,可以由接口提供方告诉你,也可以自己从WSDL中找
            call.setUseSOAPAction(true);
            call.addParameter(new QName(targetNamespace, paramNames[0]),
                    org.apache.axis.encoding.XMLType.XSD_INTEGER,
                    javax.xml.rpc.ParameterMode.IN);// 接口的参数
//            call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);// 设置返回类型  ,如String
            call.setReturnClass(java.lang.String[].class); //返回字符串数组类型
            // 给方法传递参数,并且调用方法 ,如果无参,则new Obe
            String[] result = (String[]) call.invoke(new Object[]{paramValues[0]});
            // 打印返回值
            System.out.println("result is " + result.toString());
            if (result != null && result.length > 0) {
                for (int i = 0; i < result.length; i++) {
                    System.out.println(result[i]);
                }
            }
        } catch (Exception e) {
            System.err.println(e.toString());
        }
    }

    /**
     * Http调用
     *
     * @param path
     * @param stringObject
     */
    public static String getHttpClient(String path, String stringObject, String up) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        String content = "";
        // 创建HttpGet请求,相当于在浏览器输入地址
        HttpPost httpPost = new HttpPost(path);
        //请求头:1,请求格式 2,用户名:密码基础认证
        httpPost.addHeader("Content-Type", "application/json");
        byte[] encodeBase = Base64.encodeBase64(up.getBytes());
        String authorization = new String(encodeBase);
        authorization = "Basic " + authorization;
        httpPost.addHeader("Authorization", authorization);
        //把请求体json字符串封装成StringEntity
        StringEntity stringEntity = new StringEntity(stringObject, "utf-8");
        stringEntity.setContentEncoding("UTF-8");
        httpPost.setEntity(stringEntity);
        CloseableHttpResponse response = null;
        try {
            // 执行请求,相当于敲完地址后按下回车。获取响应
            response = httpclient.execute(httpPost);
            // 判断返回状态是否为200
            if (response.getStatusLine().getStatusCode() == 200) {
                // 解析响应,获取数据
                content = EntityUtils.toString(response.getEntity(), "UTF-8");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                // 关闭资源
                try {
                    response.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            // 关闭浏览器
            try {
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return content;
    }

}

**********************WSDL文件******************************

This XML file does not appear to have any style information associated with it. The document tree is shown below.

<wsdl:definitions xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:tns="weaver.zzn.aj" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" targetNamespace="weaver.zzn.aj">

<wsdl:types>

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="weaver.zzn.aj">

<xsd:element name="payResult">

<xsd:complexType>

<xsd:sequence>

<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:string"/>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

<xsd:element name="payResultResponse">

<xsd:complexType>

<xsd:sequence>

<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:string"/>

</xsd:sequence>

</xsd:complexType>

</xsd:element>

</xsd:schema>

</wsdl:types>

<wsdl:message name="payResultRequest">

<wsdl:part name="parameters" element="tns:payResult"/>

</wsdl:message>

<wsdl:message name="payResultResponse">

<wsdl:part name="parameters" element="tns:payResultResponse"/>

</wsdl:message>

<wsdl:portType name="PayServicePortType">

<wsdl:operation name="payResult">

<wsdl:input name="payResultRequest" message="tns:payResultRequest"/>

<wsdl:output name="payResultResponse" message="tns:payResultResponse"/>

</wsdl:operation>

</wsdl:portType>

<wsdl:binding name="PayServiceHttpBinding" type="tns:PayServicePortType">

<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>

<wsdl:operation name="payResult">

<wsdlsoap:operation soapAction=""/>

<wsdl:input name="payResultRequest">

<wsdlsoap:body use="literal"/>

</wsdl:input>

<wsdl:output name="payResultResponse">

<wsdlsoap:body use="literal"/>

</wsdl:output>

</wsdl:operation>

</wsdl:binding>

<wsdl:service name="PayService">

<wsdl:port name="PayServiceHttpPort" binding="tns:PayServiceHttpBinding">

<wsdlsoap:address location="http://10.188.2.93:8081//services/PayService"/>

</wsdl:port>

</wsdl:service>

</wsdl:definitions>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值