RestTemplate 的使用与封装

package com.ruiyibd.edp.cloud.consumer.rest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.ruiyibd.edp.framework.web.WebConfiguration;
import com.ruiyibd.edp.framework.web.protocol.ResponseData;
import com.ruiyibd.edp.framework.web.protocol.ResponseDataFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 实现负载均衡的RestTemplate
 * @author Dorne
 * @date 2018-09-17
 */
public class LoadBalancedRestTemplate extends RestTemplate implements InitializingBean {

    @Autowired
    private ResponseDataFactory responseDataFactory;
    @Autowired(required = false)
    private FastJsonHttpMessageConverter fastJsonHttpMessageConverter;
    @Autowired(required = false)
    private List<LoadBalancedInterceptor> interceptors;
    @Autowired
    private LoadBalancedClientHttpRequestFactory clientHttpRequestFactory;

    /**
     * get调用,返回一个ResponseData
     * @param url 路径
     * @return 返回一个ResponseData对象
     */
    public <T extends ResponseData> T get(String url){
        return get(url, new Object[0]);
    }

    /**
     * get调用,返回一个ResponseData
     * @param url 路径
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseData对象
     */
    public <T extends ResponseData> T get(String url, Object... uriVariables){
        return (T)getDataForObject(url, responseDataFactory.getType(), uriVariables);
    }

    /**
     * get调用,返回一个ResponseData
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<E>> T get(String url, Class<E> dataType){
        return get(url, dataType, new Object[0]);
    }

    /**
     * get调用,返回一个ResponseData<List<E>>
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<List<E>>> T getList(String url, Class<E> dataType){
        return getList(url, dataType, new Object[0]);
    }

    /**
     * get调用,返回一个ResponseData
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<E>> T get(String url, Class<E> dataType, Object... uriVariables){
        String body = this.getDataForObject(url, String.class, uriVariables);
        T data = parseData(body, dataType);
        return data;
    }

    /**
     * get调用,返回一个ResponseData<List<E>>
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<List<E>>> T getList(String url, Class<E> dataType, Object... uriVariables){
        String body = this.getDataForObject(url, String.class, uriVariables);
        T data = parseList(body, dataType);
        return data;
    }

    private <T> T getDataForObject(String url, Class<T> dataType, Object... uriVariables){
        if(uriVariables == null || uriVariables.length == 0){
            return this.getForObject(url,dataType);
        }
        return this.getForObject(url, dataType, uriVariables);
    }

    /**
     * get调用,返回一个完整的ResponseEntity
     * @param url 路径
     * @return 返回一个ResponseEntity对象
     */
    public <T extends ResponseData> ResponseEntity<T> getEntity(String url){
        return getEntity(url, new Object[0]);
    }

    /**
     * get调用,返回一个完整的ResponseEntity
     * @param url 路径
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseEntity对象
     */
    public <T extends ResponseData> ResponseEntity<T> getEntity(String url, Object... uriVariables){
        ResponseEntity<T> entity = this.getDataForEntity(url, responseDataFactory.getType(), uriVariables);
        return entity;
    }

    /**
     * get调用,返回一个完整的ResponseEntity
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @return 返回一个ResponseEntity对象
     */
    public <E,T extends ResponseData<E>> ResponseEntity<T> getEntity(String url, Class<E> dataType){
        return getEntity(url, dataType, new Object[0]);
    }

    /**
     * get调用,返回一个完整的ResponseData<List<E>>
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @return 返回一个ResponseEntity对象
     */
    public <E,T extends ResponseData<List<E>>> ResponseEntity<T> getEntityList(String url, Class<E> dataType){
        return getEntityList(url, dataType, new Object[0]);
    }

    /**
     * get调用,返回一个完整的ResponseEntity
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseEntity对象
     */
    public <E,T extends ResponseData<E>> ResponseEntity<T> getEntity(String url, Class<E> dataType, Object... uriVariables){
        ResponseEntity<String> entity = this.getDataForEntity(url, String.class, uriVariables);
        ResponseEntity responseEntity = parseEntity(entity, dataType);
        return responseEntity;
    }

    /**
     * get调用,返回一个完整的ResponseEntity
     * @param url 路径
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseEntity对象
     */
    public <E,T extends ResponseData<List<E>>> ResponseEntity<T> getEntityList(String url, Class<E> dataType, Object... uriVariables){
        ResponseEntity<String> entity = this.getDataForEntity(url, String.class, uriVariables);
        ResponseEntity responseEntity = parseEntityList(entity, dataType);
        return responseEntity;
    }

    private <T> ResponseEntity<T> getDataForEntity(String url, Class<T> dataType, Object... uriVariables){
        if(uriVariables == null || uriVariables.length == 0){
            return this.getForEntity(url,dataType);
        }
        return this.getForEntity(url, dataType, uriVariables);
    }

    /**
     * post调用,返回一个ResponseData对象
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @return 返回一个ResponseData对象
     */
    public <T extends ResponseData> T post(String url, Object request){
        return (T)this.post(url, request, new Object[0]);
    }

    /**
     * post调用,返回一个ResponseData对象
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseData对象
     */
    public <T extends ResponseData> T post(String url, Object request, Object... uriVariables){
        return (T)this.postDataForObject(url, request, responseDataFactory.getType(), uriVariables);
    }

    /**
     * post调用,返回一个ResponseData对象
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<E>> T post(String url, Object request, Class<E> dataType){
        return this.post(url, request, dataType, new Object[0]);
    }

    /**
     * post调用,返回一个ResponseData对象
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<List<E>>> T postList(String url, Object request, Class<E> dataType){
        return this.postList(url, request, dataType, new Object[0]);
    }

    /**
     * post调用,返回一个ResponseData对象
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<E>> T post(String url, Object request, Class<E> dataType, Object... uriVariables){
        String body = this.postDataForObject(url, request, String.class, uriVariables);
        T data = parseData(body, dataType);
        return data;
    }

    /**
     * post调用,返回一个ResponseData对象
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个ResponseData对象
     */
    public <E,T extends ResponseData<List<E>>> T postList(String url, Object request, Class<E> dataType, Object... uriVariables){
        String body = this.postDataForObject(url, request, String.class, uriVariables);
        T data = parseList(body, dataType);
        return data;
    }

    private <T> T postDataForObject(String url, Object request ,Class<T> dataType, Object... uriVariables){
        Object realRequest = parseRequest(request);
        if(uriVariables == null || uriVariables.length == 0){
            return this.postForObject(url, realRequest, dataType);
        }
        return this.postForObject(url, realRequest, dataType, uriVariables);
    }

    /**
     * post调用,直接放回ResponseEntity<ResponseData<E>>的对象。
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @return 返回一个完整的ResponseEntity
     */
    public <T extends ResponseData> ResponseEntity<T> postEntity(String url, Object request){
        ResponseEntity<T> entity = this.postEntity(url, request, new Object[0]);
        return entity;
    }

    /**
     * post调用,直接放回ResponseEntity<ResponseData<E>>的对象。
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param uriVariables url中参数变量值
     * @return 返回一个完整的ResponseEntity
     */
    public <T extends ResponseData> ResponseEntity<T> postEntity(String url, Object request, Object... uriVariables){
        ResponseEntity<T> entity = this.postDataForEntity(url, request, responseDataFactory.getType(), uriVariables);
        return entity;
    }

    /**
     * post调用,直接放回ResponseEntity<ResponseData<E>>的对象。
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @return 返回一个完整的ResponseEntity
     */
    public <E,T extends ResponseData<E>> ResponseEntity<T> postEntity(String url, Object request, Class<E> dataType){
        return this.postEntity(url, request, dataType, new Object[0]);
    }

    /**
     * post调用,直接放回ResponseEntity<ResponseData<E>>的对象。
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @return 返回一个完整的ResponseEntity
     */
    public <E,T extends ResponseData<List<E>>> ResponseEntity<T> postEntityList(String url, Object request, Class<E> dataType){
        return this.postEntityList(url, request, dataType, new Object[0]);
    }

    /**
     * post调用,直接放回ResponseEntity<ResponseData<E>>的对象。
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个完整的ResponseEntity
     */
    public <E,T extends ResponseData<E>> ResponseEntity<T> postEntity(String url, Object request, Class<E> dataType, Object... uriVariables){
        ResponseEntity<String> entity = this.postDataForEntity(url, request, String.class, uriVariables);
        ResponseEntity<T> responseEntity = parseEntity(entity, dataType);
        return responseEntity;
    }

    /**
     * post调用,直接放回ResponseEntity<ResponseData<E>>的对象。
     * @param url 路径
     * @param request 如果是Map对象,作为表单方式提交;<br/>
     *                如果为HttpEntity,按照HttpEntity的规则执行;<br/>
     *                其他则会使用json格式通过requestBody提交
     * @param dataType ResponseData中data的类型
     * @param uriVariables url中参数变量值
     * @return 返回一个完整的ResponseEntity
     */
    public <E,T extends ResponseData<List<E>>> ResponseEntity<T> postEntityList(String url, Object request, Class<E> dataType, Object... uriVariables){
        ResponseEntity<String> entity = this.postDataForEntity(url, request, String.class, uriVariables);
        ResponseEntity responseEntity = parseEntityList(entity, dataType);
        return responseEntity;
    }

    private <T> ResponseEntity<T> postDataForEntity(String url, Object request ,Class<T> dataType, Object... uriVariables){
        Object realRequest = parseRequest(request);
        if(uriVariables == null || uriVariables.length == 0){
            return this.postForEntity(url, realRequest, dataType);
        }
        return this.postForEntity(url, realRequest, dataType, uriVariables);
    }

    private Object parseRequest(Object request){
        Object realRequest = request;
        if(request == null){
            return new HttpEntity(new LinkedMultiValueMap(), new HttpHeaders());
        }
        if(!(request instanceof HttpEntity)){
            HttpHeaders requestHeaders = new HttpHeaders();
            if(!(request instanceof Map)){
                requestHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
            }
            HttpEntity requestEntity = new HttpEntity(request, requestHeaders);
            realRequest = requestEntity;
        }
        return realRequest;
    }

    /**
     * ResponseEntity<String>中body为jaon字符串,里面的body执行 this.parseData(String body,Class<E> dataType)。
     * 转化成ResponseEntity<ResponseData<E>>的对象
     * @param source
     * @param dataType ResponseData中data的类型
     * @return
     */
    public <E,T extends ResponseData<E>> ResponseEntity<T> parseEntity(ResponseEntity<String> source, Class<E> dataType){
        String body = source.getBody();
        ResponseData responseData = parseData(body, dataType);
        ResponseEntity responseEntity = new ResponseEntity(responseData, source.getHeaders(), source.getStatusCode());
        return responseEntity;
    }

    /**
     * ResponseEntity<String>中body为jaon字符串,里面的body执行 this.parseData(String body,Class<E> dataType)。
     * 转化成ResponseEntity<ResponseData<E>>的对象
     * @param source
     * @param dataType ResponseData中data的类型
     * @return
     */
    public <E,T extends ResponseData<E>> ResponseEntity<T> parseEntityList(ResponseEntity<String> source, Class<E> dataType){
        String body = source.getBody();
        ResponseData responseData = parseList(body, dataType);
        ResponseEntity responseEntity = new ResponseEntity(responseData, source.getHeaders(), source.getStatusCode());
        return responseEntity;
    }

    /**
     * json字符串序列化为ResponseData对象
     * @param body
     * @param dataType ResponseData中data的类型
     * @param <T>
     * @return
     */
    public <T extends ResponseData> T parseData(String body,Class dataType){
        ResponseData responseData = (ResponseData)JSON.parseObject(body, responseDataFactory.getType());
        JSONObject jsonData  = (JSONObject)responseData.getData();
        Optional.ofNullable(jsonData).ifPresent(j -> {
            Object data = JSON.parseObject(jsonData.toJSONString(),dataType);
            responseData.setData(data);
        });
        return (T)responseData;
    }

    /**
     * json字符串序列化为ResponseData<List>对象
     * @param body
     * @param dataType ResponseData中data的类型
     * @param <T>
     * @return
     */
    public <T extends ResponseData> T parseList(String body,Class dataType){
        ResponseData responseData = (ResponseData)JSON.parseObject(body, responseDataFactory.getType());
        JSONArray jsonData  = (JSONArray)responseData.getData();
        Optional.ofNullable(jsonData).ifPresent(j -> {
            List data = JSON.parseArray(jsonData.toJSONString(),dataType);
            responseData.setData(data);
        });
        return (T)responseData;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        this.setRequestFactory(clientHttpRequestFactory);
        if(interceptors != null){
            this.getInterceptors().addAll(interceptors);
        }
        List<HttpMessageConverter<?>> converters = this.getMessageConverters();
        if(fastJsonHttpMessageConverter != null){
            int i = 0;
            for(HttpMessageConverter converter : converters){
                if(converter instanceof MappingJackson2HttpMessageConverter){
                    converters.remove(converter);
                    converters.add(i, fastJsonHttpMessageConverter);
                    break;
                }
                i ++;
            }
        }
        converters.forEach(converter -> {
            if(converter instanceof StringHttpMessageConverter){
                StringHttpMessageConverter sc = (StringHttpMessageConverter)converter;
                WebConfiguration.setStringHttpMessageConverter(sc);
            }
        });
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值