java开发

http调用webservice

2020-09-29  本文已影响0人  DragonRat

工作时由于xml字符串的多样性,soap的方式走不通,可以转变思路用http的方式实现

1、pom文件

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160810</version>
        </dependency>

        <dependency>
            <groupId>org.apache.axis2</groupId>
            <artifactId>axis2-transport-http</artifactId>
            <version>1.7.8</version>
        </dependency>

2、http请求工具类

package com.mpt.crm.utils;


import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;


/**
 * HTTP工具类
 *
 * @author JustryDeng
 * @DATE 2018年9月22日 下午10:29:08
 */
public class HttpSendUtil {

    /**
     * 使用apache的HttpClient发送http
     *
     * @param wsdlURL
     *            请求URL
     * @param contentType
     *            如:application/json;charset=utf8
     * @param content
     *            数据内容
     * @DATE 2018年9月22日 下午10:29:17
     */
    public static String doHttpPostByHttpClient(final String wsdlURL, final String contentType, final String content)
            throws ClientProtocolException, IOException {
        // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        // 创建Post请求
        HttpPost httpPost = new HttpPost(wsdlURL);
        StringEntity entity = new StringEntity(content.toString(), "UTF-8");
        // 将数据放入entity中
        httpPost.setEntity(entity);
        httpPost.setHeader("Content-Type", contentType);
        // 响应模型
        CloseableHttpResponse response = null;
        String result = null;
        try {
            // 由客户端执行(发送)Post请求
            response = httpClient.execute(httpPost);
            // 从响应模型中获取响应实体
            // 注意:和doHttpPostByRestTemplate方法用的不是同一个HttpEntity
            org.apache.http.HttpEntity responseEntity = response.getEntity();
            System.out.println("响应ContentType为:" + responseEntity.getContentType());
            System.out.println("响应状态为:" + response.getStatusLine());
            if (responseEntity != null) {
                result = EntityUtils.toString(responseEntity);
                System.out.println("响应内容为:" + result);
            }
        } finally {
            // 释放资源
            if (httpClient != null) {
                httpClient.close();
            }
            if (response != null) {
                response.close();
            }
        }
        return result;
    }

    /**
     * 使用springframework的RestTemplate发送http
     *
     * @param wsdlURL
     *            请求URL
     * @param contentType
     *            如:application/json;charset=utf8
     * @param content
     *            数据内容
     * @DATE 2018年9月22日 下午10:30:48
     */
    public static String doHttpPostByRestTemplate(final String wsdlURL, final String contentType, final String content) {
        // http使用无参构造;https需要使用有参构造
        RestTemplate restTemplate = new RestTemplate();
        // 解决中文乱码
        List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
        converterList.remove(1);
        HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8);
        converterList.add(1, converter);
        restTemplate.setMessageConverters(converterList);
        // 设置Content-Type
        HttpHeaders headers = new HttpHeaders();
        headers.remove("Content-Type");
        headers.add("Content-Type", contentType);
        // 数据信息封装
        // 注意:和doHttpPostByHttpClient方法用的不是同一个HttpEntity
        org.springframework.http.HttpEntity<String> formEntity = new org.springframework.http.HttpEntity<String>(
                content, headers);
        String result = restTemplate.postForObject(wsdlURL, formEntity, String.class);
        return result;
    }
}

3、http请求类

package com.mpt.crm.controller;


import com.mpt.crm.filter.ClientLoginInterceptor;
import com.mpt.crm.utils.HttpSendUtil;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.http.client.ClientProtocolException;
import org.springframework.web.bind.annotation.*;
import org.w3c.dom.Document;

import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.stream.XMLStreamException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.*;
import javax.xml.ws.soap.SOAPBinding;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.json.XML;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/soap")
public class SoapTestController {


    /**
     * 方法一:用cxf框架
     * @param url
     * @param method
     * @param args
     * @return
     */
    @RequestMapping("/hello")
    @ResponseBody
    public Map<String, Object> hello(String url, String method, String[] args) {
        if (args.length < 1) {
            args = new String[]{""};
        }

        // 创建动态客户端
        JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
        Client client = dcf.createClient(url);
        /* 需要密码的情况需要加上用户名和密码ClientLoginInterceptor */
        client.getOutInterceptors().add(new ClientLoginInterceptor("aaa","bbb"));
        // 命名空间,方法名
        QName name = new QName("http://WebXml.com.cn/", method);
        HashMap<String, Object> map = new HashMap<>();
        try {
            // invoke("方法名",参数1,参数2,参数3....);
            Object[] objects = client.invoke(name, args);
            map.put("result", objects);
            //System.out.println(client.getOutInterceptors());
            return map;
        } catch (java.lang.Exception e) {
            e.printStackTrace();
            map.put("result", "接口调用异常");
            return map;
        }
    }

    /**
     * 方法二:自己用jax-ws的方式实现
     * @param url 请求地址
     * @param targetNamespace 名称空间
     * @param pName 端口名
     * @param method 方法名
     * @param argsName 参数名
     * @param args  参数
     * @return
     * @throws Exception
     */
    @RequestMapping("/getSoap")
    @ResponseBody
    public Map getSoap(String url, String targetNamespace, String pName, String method, String[] argsName, String[] args) throws Exception {
        QName serviceName = new QName(targetNamespace, method);

        //WSDL中定义的端口的QName
        QName portName = new QName(targetNamespace, pName);

        //创建动态Service实例
        Service service = Service.create(serviceName);
        service.addPort(portName, SOAPBinding.SOAP11HTTP_BINDING, url);

        //创建一个dispatch实例
        Dispatch<SOAPMessage> dispatch = service.createDispatch(portName, SOAPMessage.class, Service.Mode.MESSAGE);

        // Use Dispatch as BindingProvider
        BindingProvider bp = (BindingProvider) dispatch;

        // 配置RequestContext以发送SOAPAction HTTP标头
        Map<String, Object> rc = dispatch.getRequestContext();
        rc.put(BindingProvider.SOAPACTION_USE_PROPERTY, Boolean.TRUE);
        rc.put(BindingProvider.SOAPACTION_URI_PROPERTY, targetNamespace + method);

        // 获取预配置的SAAJ MessageFactory
        MessageFactory factory = ((SOAPBinding) bp.getBinding()).getMessageFactory();

        // 创建SOAPMessage请求
        SOAPMessage request = null;
        request = factory.createMessage();
        // 请求体
        SOAPBody body = request.getSOAPBody();

        // Compose the soap:Body payload
        QName payloadName = new QName(targetNamespace, method);

        SOAPBodyElement payload = body.addBodyElement(payloadName);
        if (args.length > 0) {
            for (int i = 0; i < argsName.length; i++) {
                payload.addChildElement(argsName[i]).setValue(args[i]);
            }
        }

        SOAPMessage reply = null;

        try {
            //调用端点操作并读取响应
            //request.writeTo(System.out);
            reply = dispatch.invoke(request);
            //reply.writeTo(System.out);
        } catch (WebServiceException wse) {
            wse.printStackTrace();
        }
        // 处理响应结果
        Document doc = reply.getSOAPPart().getEnvelope().getBody().extractContentAsDocument();
        HashMap<String, Object> map = new HashMap<>();
        map.put("result", XML.toJSONObject(format(doc)).toString());
        //System.out.println(XML.toJSONObject(format(doc)).toString());
        return map;

    }

    // Document对象转字符串
    public static String format(Document doc) throws Exception {
        // XML转字符串
        String xmlStr = "";
        try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            t.setOutputProperty("encoding", "UTF-8");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            t.transform(new DOMSource(doc), new StreamResult(bos));
            xmlStr = bos.toString();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        return xmlStr;
    }


    /**
     * 方法三:使用HTTP调用WebService
     *
     *
     */
    @RequestMapping("/http")
    @ResponseBody
    public void test() throws XMLStreamException, ClientProtocolException, IOException {
        // webservice的wsdl地址
        final String wsdlURL = "http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl";
        // 设置编码。(因为是直接传的xml,所以我们设置为text/xml;charset=utf8)
        final String contentType = "text/xml;charset=utf8";

        /// 拼接要传递的xml数据(注意:此xml数据的模板我们根据wsdlURL从SoapUI中获得,只需要修改对应的变量值即可)
        String name = "15.239.210.27";
        StringBuffer xMLcontent = new StringBuffer("");
        xMLcontent.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap"
                + "/envelope/\" xmlns:web=\"http://WebXml.com.cn/\">\n");
        xMLcontent.append("   <soapenv:Header/>\n");
        xMLcontent.append("   <soapenv:Body>\n");
        xMLcontent.append("      <web:getCountryCityByIp>\n");
        xMLcontent.append("         <!--Optional:-->\n");
        xMLcontent.append("         <web:theIpAddress>" + name + "</web:theIpAddress>\n");
        xMLcontent.append("      </web:getCountryCityByIp>\n");
        xMLcontent.append("   </soapenv:Body>\n");
        xMLcontent.append("</soapenv:Envelope>");

        // 调用工具类方法发送http请求
        String responseXML = HttpSendUtil.doHttpPostByRestTemplate(wsdlURL,contentType, xMLcontent.toString());
        // 当然我们也可以调用这个工具类方法发送http请求
        // String responseXML = HttpSendUtil.doHttpPostByRestTemplate(wsdlURL, contentType, xMLcontent.toString());

        //System.out.println(XML.toJSONObject(responseXML));
        Object soapBody =XML.toJSONObject(responseXML).getJSONObject("soap:Envelope").getJSONObject("soap:Body").getJSONObject("getCountryCityByIpResponse").getJSONObject("getCountryCityByIpResult").get("string");
        System.out.println(soapBody);
        // 利用axis2的OMElement,将xml数据转换为OMElement
//        OMElement omElement = OMXMLBuilderFactory
//                .createOMBuilder(new ByteArrayInputStream(responseXML.getBytes()), "utf-8").getDocumentElement();
//
//        // 根据responseXML的数据样式,定位到对应element,然后获得其childElements,遍历
//        Iterator<OMElement> it = omElement.getFirstElement().getFirstElement().getFirstElement().getChildElements();
//        while (it.hasNext()) {
//            OMElement element = it.next();
//            System.out.println("属性名:" + element.getLocalName() + "\t属性值:" + element.getText());
//        }
//        JSONObject jsonObject= JSON.parseObject(res);
//        String data = jsonObject.getString("data");
//        JSONObject jsondata= JSON.parseObject(data);
//        String token = jsondata.getString("access_token");

    }


}

4、xml字符串根据soapui获取

上一篇 下一篇

猜你喜欢

热点阅读