java RestTemplate调用远程服务接口

来源:互联网 发布:淘宝网大童 编辑:程序博客网 时间:2024/05/22 17:32

1.1.接口域名说明为了说明的方便我这里都假定接口域名是xxx.xxx.xxx。实际使用中如果是其他域名只需将相应域名替代xxx.xxx.xxx即可1.2.format 参数说明 指定接口返回格式。主要包含三种格式:xml、json、php。如果未显式调用format参数,默认返回json格式。具体返回格式可查看具体接口的返回示例(为方便理解用的是GET方式,正式使用中请使用POST)获取xml格式http://xxx.xxx.xxx/Api/seller/api.php?format=xml&cid=1&pid=10000获取json格式http://xxx.xxx.xxx/Api/seller/api.php?format=json&cid=1&pid=100001.3.接口访问权限合作伙伴如果要访问接口至少要提供_pid和签名(签名是由授权码和参数生成)1.3.1.pid 参数说明 每个接口都需要_pid参数,这是合作伙伴的编号,在此文档中有时叫合作伙伴id. 1.3.2.签名参数还需要签名来验证请求的合法性。签名生成规则:md5( $authcode . '&p1=v1&p2=v2&p3=v3&' .$authcode ); md5: 加密算法,32位md5算法$authcode: 授权码p1=v1&p2=v2&p3=v3:传递给接口的参数。多个参数用&连接注:1.所有参数(除_sig参数,注意是所有参数,而不是接口要求的参数)需要按照键名英文排好次序。2.参数要求:除_sig参数本身以外的所有其他参与请求接口的参数。3.其中的‘.’号表示连接符号,即连接多个字符串。请勿理解成可见的字符,如js中字符串连接符号‘+’4.$authcode是授权码,(与_pid一起联系官方获取)。5.请求方式强制为POST。

php中生成签名示例:



分析下php脚本片段,对应java语言



Test.java

package com.xxx.client;import com.wdletu.client.util.HttpClientUtils;import org.json.JSONException;import org.json.JSONTokener;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.TreeMap;/** * Created by zhangmy on 2017/8/22. */public class Test {    private static final String url = "http://demo.xxx.xxxx.com/Api/Seller/api.json";    private static final String autoCode = "111";//授权码    private static final String _pid = "4";//合作伙伴id    public static Map<String, String> getData() {        Map<String, String> map = new TreeMap<>();        map.put("method", "orders_list");        map.put("format", "json");        map.put("page", "1");        map.put("size", "5");        map.put("_pid", _pid);        return map;    }    public static String getSign() {        String query = autoCode;        Map<String, String> map = getData();        Set<String> strings = map.keySet();        Iterator<String> iterator = strings.iterator();        while (iterator.hasNext()) {            String key = iterator.next();            String value = map.get(key);            query += "&" + key + "=" + value;        }        query += "&" + autoCode;        return getMD5Str(query);    }    public static void main(String[] args) throws UnsupportedEncodingException, JSONException {        Map<String, String> map = getData();        map.put("_sig", getSign());        String s = HttpClientUtils.doPost(url, map);        System.out.println("unicode转换为中文" + new JSONTokener(s).nextValue().toString());    }    private static String getMD5Str(String str) {        MessageDigest messageDigest = null;        try {            messageDigest = MessageDigest.getInstance("MD5");            messageDigest.reset();            messageDigest.update(str.getBytes("UTF-8"));        } catch (NoSuchAlgorithmException e) {            System.out.println("NoSuchAlgorithmException caught!");            System.exit(-1);        } catch (UnsupportedEncodingException e) {            e.printStackTrace();        }        byte[] byteArray = messageDigest.digest();        StringBuffer md5StrBuff = new StringBuffer();        for (int i = 0; i < byteArray.length; i++) {            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));            else                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));        }        return md5StrBuff.toString();    }}

HttpClientUtil.java

package com.xxx.client.util;import org.apache.commons.collections.MapUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.http.HttpEntity;import org.springframework.util.LinkedMultiValueMap;import org.springframework.util.MultiValueMap;import java.util.Map;/** * Created by zhangmy on 2017/8/22. */public class HttpClientUtils {    private static final Logger LOGGER = LoggerFactory.getLogger(HttpClientUtils.class);    /**     * post请求     *     * @param url     * @param formParams     * @return     */    public static String doPost(String url, Map<String, String> formParams) {        if (MapUtils.isEmpty(formParams)) {            return doPost(url);        }        try {            MultiValueMap<String, String> requestEntity = new LinkedMultiValueMap<>();            formParams.keySet().stream().forEach(key -> requestEntity.add(key, MapUtils.getString(formParams, key, "")));            return RestClient.getClient().postForObject(url, requestEntity, String.class);        } catch (Exception e) {            LOGGER.error("POST请求出错:{}", url, e);        }        return "";    }    /**     * post请求     *     * @param url     * @return     */    public static String doPost(String url) {        try {            return RestClient.getClient().postForObject(url, HttpEntity.EMPTY, String.class);        } catch (Exception e) {            LOGGER.error("POST请求出错:{}", url, e);        }        return "";    }    /**     * get请求     *     * @param url     * @return     */    public static String doGet(String url) {        try {            return RestClient.getClient().getForObject(url, String.class);        } catch (Exception e) {            LOGGER.error("GET请求出错:{}", url, e);        }        return "";    }}

RestClient.java

package com.xxx.client.util;import org.apache.http.Header;import org.apache.http.client.HttpClient;import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.impl.client.HttpClients;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.apache.http.message.BasicHeader;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.context.annotation.Lazy;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import org.springframework.http.converter.FormHttpMessageConverter;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.converter.StringHttpMessageConverter;import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;import org.springframework.stereotype.Component;import org.springframework.web.client.DefaultResponseErrorHandler;import org.springframework.web.client.RestTemplate;import javax.annotation.PostConstruct;import java.nio.charset.Charset;import java.util.ArrayList;import java.util.List;import java.util.concurrent.TimeUnit;/** * Created by zhangmy on 2017/8/22. */@Component@Lazy(false)public class RestClient {    private static final Logger logger = LoggerFactory.getLogger(RestClient.class);    private static RestTemplate restTemplate;    static {        //长连接保持30秒        PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =                new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);        //总连接数1000        poolingHttpClientConnectionManager.setMaxTotal(1000);        //同路由的并发数1000        poolingHttpClientConnectionManager.setDefaultMaxPerRoute(1000);        HttpClientBuilder httpClientBuilder = HttpClients.custom();        httpClientBuilder.setConnectionManager(poolingHttpClientConnectionManager);        // 重试次数,默认是3次,没有开启        httpClientBuilder.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true));        // 保持长连接配置,需要在头添加Keep-Alive        httpClientBuilder.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy());//        RequestConfig.Builder builder = RequestConfig.custom();//        builder.setConnectionRequestTimeout(200);//        builder.setConnectTimeout(5000);//        builder.setSocketTimeout(5000);////        RequestConfig requestConfig = builder.build();//        httpClientBuilder.setDefaultRequestConfig(requestConfig);        List<Header> headers = new ArrayList<>();        headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36"));        headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate"));        headers.add(new BasicHeader("Accept-Language", "zh-CN"));        headers.add(new BasicHeader("Connection", "Keep-Alive"));        httpClientBuilder.setDefaultHeaders(headers);        HttpClient httpClient = httpClientBuilder.build();        // httpClient连接配置,底层是配置RequestConfig        HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);        // 连接超时        clientHttpRequestFactory.setConnectTimeout(5000);        // 数据读取超时时间,即SocketTimeout        clientHttpRequestFactory.setReadTimeout(5000);        // 连接不够用的等待时间,不宜过长,必须设置,比如连接不够用时,时间过长将是灾难性的        clientHttpRequestFactory.setConnectionRequestTimeout(200);        // 缓冲请求数据,默认值是true。通过POST或者PUT大量发送数据时,建议将此属性更改为false,以免耗尽内存。        // clientHttpRequestFactory.setBufferRequestBody(false);        // 添加内容转换器        List<HttpMessageConverter<?>> messageConverters = new ArrayList<>();        messageConverters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));        messageConverters.add(new FormHttpMessageConverter());        /*messageConverters.add(new MappingJackson2XmlHttpMessageConverter());*//*ClassNotFoundException: com.fasterxml.jackson.dataformat.xml.XmlMapper*/        messageConverters.add(new MappingJackson2HttpMessageConverter());        restTemplate = new RestTemplate(messageConverters);        restTemplate.setRequestFactory(clientHttpRequestFactory);        restTemplate.setErrorHandler(new DefaultResponseErrorHandler());        logger.info("RestClient初始化完成");    }    private RestClient() {    }    @PostConstruct    public static RestTemplate getClient() {        return restTemplate;    }}


参考链接:https://www.molloc.com/archives/868