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 implements Serializable {

    private static final long serialVersionUID = 6648835178847199263L;

    @JsonProperty("list")
    private List list;

    public List getList() {
        return list;
    }

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

*封装2

public class ReqService implements Serializable {

    private static final long serialVersionUID = -8153707350660508556L;

    @JsonProperty("Request")
    private ReqData request;

    public ReqData getRequest() {
        return request;
    }

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

*封装3 

@XmlRootElement
public class RestRequest implements Serializable {

    private static final long serialVersionUID = -4637756210826669082L;

    @JsonProperty("Service")
    private ReqService reqService;


    public ReqService getReqService() {
        return reqService;
    }

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

2,业务代码调用工具类

*查询数据,获取webservice入参

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

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

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

        List voList = syncAccountService.getWaitSyncOaList(ids);
        //oa_code oa付款申请编号
        Map> groupBy = voList.stream().collect(Collectors.groupingBy(AccountSyncVo::getOaCode));
        ArrayList> arrayList = new ArrayList<>(groupBy.values());
        ArrayList> arrayList2 = new ArrayList<>(groupBy.values());
        for (List syncVos : arrayList) {
            for (AccountSyncVo vo : syncVos) {
                if (!Const.PAYSTATUS.equals(vo.getPayStatus())) {
                    arrayList2.remove(syncVos);
                    break;
                }
            }
        }
        List requestList = new ArrayList<>();
        List oaCodes = new ArrayList<>();
        for (List 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 failureOaCodes = new ArrayList<>();
            List 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 pushMsgToOa(List 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 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.

你可能感兴趣的:(WebService,支付中心)