《WebService调用总结》

5 篇文章 0 订阅
1 篇文章 0 订阅


背景:

在项目的真实开发场景中,对应不同第三方厂商的时候,会遇到通过WebService接口交互的场景,由于第三方可能会有部署Ngnix负载,导致tool.exe调用异常,SoapUI调用是成功的,Soapui是有通过解析WS的远程文件,生成对应请求头。

W3C组织对其的定义如下,它是一个软件系统,为了支持跨网络的机器间相互操作交互而设计。Web Service服务通常被定义为一组模块化的API,它们可以通过网络进行调用,来执行远程系统的请求服务。

简单的说:WebService即Web服务,它是一种跨编程语言和跨操作系统平台的远程调用技术。

Web Service = SOAP + HTTP + WSDL。其中,SOAP Simple Object Access Protocol)协议是web service的主体,它通过HTTP或者SMTP等应用层协议进行通讯,自身使用XML文件来描述程序的函数方法和参数信息,从而完成不同主机的异构系统间的计算服务处理。这里的WSDL(Web Services Description Language)web 服务描述语言也是一个XML文档,它通过HTTP向公众发布,公告客户端程序关于某个具体的 Web service服务的URL信息、方法的命名,参数,返回值等。

调用方式:

1. 通过动态客户端调用

cfx动态代理模式,不用生成本地WS代理类,通过反射调用WS的对应方法,传入对应参数,访问cxf-server-web项目下的webservice,通过测试jaxws-rt发布WebService web方式。


public class CxfDynamicClientOnJwsRtWeb {
	private static final Logger log = LoggerFactory.getLogger(CxfClient.class);
	private static final String JWS_RT_WSDL_URI = "http://localhost:8080/cxf_server_web/jws_services?wsdl";
	public static void main(String[] args) throws Exception {
		log.info("======CXF-WS Dynamic Client start!======");
		JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
		Client client =  dcf.createClient(JWS_RT_WSDL_URI);
		HTTPConduit conduit = (HTTPConduit)client.getConduit(); 
		HTTPClientPolicy policy = new HTTPClientPolicy(); 
		policy.setConnectionTimeout(10000); 
		policy.setAllowChunking(false); 
		policy.setReceiveTimeout(10000); 
		conduit.setClient(policy);	
		Object[] invokeResult = client.invoke("sum", 17,8);
		log.info("=======sumResult:" + invokeResult[0]);
	}
}

2. 通过动态客户端直接获取到QName调用WebService对应的操作,这种方式针对SIB和SEI的targetNamespace不相同,同时不再同一个包。

/**
 * 根据WS请求获取数据
 *
 * @param wsUrl    接口地址
 * @param wsMethod 接口方法
 * @param params   请求参数
 * @return
 * @throws Exception
 */
public static String getDataByWs3(String wsUrl, String wsMethod, Object... params) throws Exception {
    logger.info("调用WS请求:{},请求方法:{},请求参数:{}", new Object[]{wsUrl, wsMethod, params});
    ResultModel resultModel;
    String result = "";
    try {
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(wsUrl);
        HTTPConduit conduit = (HTTPConduit) client.getConduit();
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setConnectionTimeout(10000);
        policy.setAllowChunking(false);
        policy.setReceiveTimeout(10000);
        conduit.setClient(policy);
        //获取操作对应的Qname
        // QName operateQName = getOperateQName(client, wsMethod);
        //如果Qname已知,可以通过如下方式,直接创建QName
        QName operateQName = new QName("http://portal.webserver.jhip.goodwillcis.com/", "InputPara");
        Object[] resultObj = client.invoke(operateQName, params);
        logger.info("ws请求返回结果:{}", result);
        // Object[] resultObj = WSRequestUtil.doRequest(wsUrl, wsMethod, params);
        result = (String) resultObj[0];
    } catch (Exception e) {
        logger.info("HTTP请求异常地址{},{},{}", wsUrl, e, result);
        throw ApiException.createBizEx("HTTP_ERROR_URL", wsUrl);
    }

    return result;
}

/**
 * 针对SEI和SIB不在统一个包内的情况,先查找操作对应的Qname,
 * client通过Qname调用对应操作
 *
 * @param client
 * @param operation
 * @return
 */
private static QName getOperateQName(Client client, String operation) {
    Endpoint endpoint = client.getEndpoint();
    QName opName = new QName(endpoint.getService().getName().getNamespaceURI(), operation);
    BindingInfo bindingInfo = endpoint.getEndpointInfo().getBinding();
    if (bindingInfo.getOperation(opName) == null) {
        for (BindingOperationInfo operationInfo : bindingInfo.getOperations()) {
            if (operation.equals(operationInfo.getName().getLocalPart())) {
                opName = operationInfo.getName();
                break;
            }
        }
    }
    logger.info("Operation:" + operation + ",namespaceURI:" + opName.getNamespaceURI());
    return opName;
}

3、 HttpURLConnection调用方式

    基于上面的两种方式调用还无果的情况,可以通过SoapUI获取对应的请求头报文信息,在代码里面动态拼接对应的请求头信息,进行调用相当于模拟各种Http请求。

最终是通过封装请求头参数的形式;

String tokenTem = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:por=\"http://portal.webserver.jhip.goodwillcis.com/\">\n" +
        "   <soapenv:Header/>\n" +
        "   <soapenv:Body>\n" +
        "      <por:getUserDetailInfo>\n" +
        "         <!--Optional:-->\n" +
        "         <por:InputPara><![CDATA[\n" +
        "         <REQUEST>\n" +
        "\t<SESSION_ID>{}</SESSION_ID>\n" +
        "<SYSTEM_CODE>{}</SYSTEM_CODE>\n" +
        "</REQUEST>\n" +
        "]]></por:InputPara>\n" +
        "      </por:getUserDetailInfo>\n" +
        "   </soapenv:Body>\n" +
        "</soapenv:Envelope>";
   
  String dataByWs2 = SpringContextHolder.getBean(ApiUtils.class).getDataByJHWs(url, method, tokenXml);
 
 protected final RestTemplate restTemplate = buildRestTemplate();
 
 public static RestTemplate buildRestTemplate() {

    RestTemplate restTemplate = new RestTemplate();
    SimpleClientHttpRequestFactory repFac = getUnsafeClientHttpRequestFactory();
    repFac.setConnectTimeout(60000);
    repFac.setReadTimeout(60000);
    restTemplate.setRequestFactory(repFac);
    return restTemplate;
}
private static SimpleClientHttpRequestFactory getUnsafeClientHttpRequestFactory() {
    TrustManager[] byPassTrustManagers = new TrustManager[]{new X509TrustManager() {

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {
        }
    }};
    final SSLContext sslContext;
    try {
        sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, byPassTrustManagers, new SecureRandom());
        sslContext.getSocketFactory();
    } catch (NoSuchAlgorithmException | KeyManagementException e) {
        throw new RuntimeException(e);
    }

    return new SimpleClientHttpRequestFactory() {
        @Override
        protected void prepareConnection(HttpURLConnection connection,
                                         String httpMethod) throws IOException {
            super.prepareConnection(connection, httpMethod);
            if (connection instanceof HttpsURLConnection) {
                ((HttpsURLConnection) connection).setHostnameVerifier(new SkipHostnameVerifier());
                ((HttpsURLConnection) connection).setSSLSocketFactory(
                        sslContext.getSocketFactory());
            }
        }
    };
}

private static class SkipHostnameVerifier implements HostnameVerifier {

    @Override
    public boolean verify(String s, SSLSession sslSession) {
        return true;
    }

}

 /**
 * 根据WS请求获取数据
 *
 * @param wsUrl    接口地址
 * @param wsMethod 接口方法
 * @param body   请求参数
 * @return
 * @throws Exception
 */
public String getDataByJHWs(String wsUrl, String wsMethod, String body) throws Exception {

    HttpHeaders headers = new HttpHeaders();
    String response = "";
    headers.set("Content-Type", "application/soap+xml;charset=UTF-8");
    HttpEntity httpEntity = new HttpEntity<>(body, headers);
    ResponseEntity<String> responseEntity = null;
    try {
        responseEntity = restTemplate.exchange(wsUrl, HttpMethod.POST, httpEntity, String.class);
        response = responseEntity.getBody();
    } catch(Exception e) {
        logger.info("HTTP请求结果JSON解析异常地址{}", wsUrl, e.getMessage());
        throw ApiException.createBizEx("HTTP_ERROR_URL", wsUrl, e.getMessage());
    }
    return  response;
}

通过postman就可以进行接口的调用,但是需要配置请求头信息,请求头信息是从SoapUI拷贝出来的。

content-type:text/xml  

请求体body,选择raw 以及通过XML(text/xml),进行数据调用
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:por="http://portal.webserver.jhip.goodwillcis.com/">
   <soapenv:Header/>
   <soapenv:Body>
      <por:getUserDetailInfo>
         <!--Optional:-->
         <por:InputPara><![CDATA[
         <REQUEST>
	<SESSION_ID>b5c579f2-49c4-453e-b7a2-db4a00e6b125</SESSION_ID>
<SYSTEM_CODE>HIS_SET</SYSTEM_CODE>
</REQUEST>
]]></por:InputPara>
      </por:getUserDetailInfo>
   </soapenv:Body>
</soapenv:Envelope>

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值