自定義HttpMessageConverter實現RestTemplate的exchange方法返回自定義格式數據


一 概述

 實現如下效果代碼,且可正常獲取到返回數據:

ResponseEntity<JsonObject> resEntity = restTemplate
.exchange(url, HttpMethod.GET, requestEntity, JsonObject.class,uriVariables);

 restTemplate的get和POST請求都有類型參數設置,所以可以直接返回轉換成自定義的格式.比如:

restTemplate.getForObject("http://www.baiud.com",JsonObject.class);

但是exchange是無法指定返回類型的,只能使用spring默認提供的幾種轉換器轉換的格式,定義其他格式會報錯或者返回實體body為空

restTemplate的post方法支持設置header,但是get方法不支持,假如現在有個需求,使用get方法需要設置header權限,且返回我想要的格式,那么自定義HttpMessageConverter就派上用場了

也提現了spring非常強大的可擴展性

二 步驟

新建自定義轉換類:

/**
 * 接口請求返回數據格式轉換處理類,只處理String->JsonObject
 */
public class StringToJsonObjectMessageConverter extends AbstractHttpMessageConverter<JsonObject> {

    public StringToJsonObjectMessageConverter() {
        super(StandardCharsets.UTF_8,MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML); //設置支付類型
    }
    /**
     * HttpMessageConvert是否處理接受的這個類
     */
    @Override
    protected boolean supports(Class<?> aClass) {
        //isAssignableFrom: 判定此Class對象所表示的類或接口與指定的 Class 參數所表示的類或接口是否相同,或是否是其超類或超接口
        return JsonObject.class==aClass;
    }

    //對數據進行處理並返回
    @Override
    protected JsonObject readInternal(Class<? extends JsonObject> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
        //數據轉換
        String temp = StreamUtils.copyToString(httpInputMessage.getBody(),Charset.forName("UTF-8"));
        return Tools.getGsonInstance().fromJson(temp, JsonObject.class);
    }

    //處理如何輸出數據到response
    @Override
    protected void writeInternal(JsonObject jsonObject, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
        //可繼續處理轉換后的格式數據
        httpOutputMessage.getBody().write(jsonObject.getAsByte());
    }
}

配置修改自定義類順序:

    @Bean
    public RestTemplate restTemplate() {
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        httpRequestFactory.setConnectionRequestTimeout(30 * 1000);
        httpRequestFactory.setConnectTimeout(30 * 3000);
        httpRequestFactory.setReadTimeout(30 * 3000);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        // 支持返回JsonObject類型數據,需要在String之前,因為String支付所有的類型會直接解析
        restTemplate.getMessageConverters().set(1,new StringToJsonObjectMessageConverter());
        //spring轉換默認編碼是ISO_8859_1,如果亂碼可修改支持中文編碼
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }

斷點查看:

三 原理

exchage方法源碼點進去,看一下就知道了

        //獲取HttpMessageConverter集合
        Iterator var8 = RestTemplate.this.getMessageConverters().iterator();
        //按照索引順序進行迭代循環解析
        while(var8.hasNext()) {
            HttpMessageConverter<?> messageConverter = (HttpMessageConverter)var8.next();
            if (messageConverter instanceof GenericHttpMessageConverter) {
                GenericHttpMessageConverter<Object> genericConverter = (GenericHttpMessageConverter)messageConverter;
                if (genericConverter.canWrite((Type)requestBodyType, requestBodyClass, requestContentType)) {
                    if (!requestHeadersx.isEmpty()) {
                        requestHeadersx.forEach((key, values) -> {
                            httpHeadersx.put(key, new LinkedList(values));
                        });
                    }

                    if (RestTemplate.this.logger.isDebugEnabled()) {
                        if (requestContentType != null) {
                            RestTemplate.this.logger.debug("Writing [" + requestBody + "] as \"" + requestContentType + "\" using [" + messageConverter + "]");
                        } else {
                            RestTemplate.this.logger.debug("Writing [" + requestBody + "] using [" + messageConverter + "]");
                        }
                    }
                    //解析成功直接返回,不會走后面解析器
                    genericConverter.write(requestBody, (Type)requestBodyType, requestContentType, httpRequest);
                    return;
                }
            } else if (messageConverter.canWrite(requestBodyClass, requestContentType)) {
                if (!requestHeadersx.isEmpty()) {
                    requestHeadersx.forEach((key, values) -> {
                        httpHeadersx.put(key, new LinkedList(values));
                    });
                }

                if (RestTemplate.this.logger.isDebugEnabled()) {
                    if (requestContentType != null) {
                        RestTemplate.this.logger.debug("Writing [" + requestBody + "] as \"" + requestContentType + "\" using [" + messageConverter + "]");
                    } else {
                        RestTemplate.this.logger.debug("Writing [" + requestBody + "] using [" + messageConverter + "]");
                    }
                }

                messageConverter.write(requestBody, requestContentType, httpRequest);
                return;
            }
        }
        //如果都沒有解析成功.拋異常
        String message = "Could not write request: no suitable HttpMessageConverter found for request type [" + requestBodyClass.getName() + "]";
        if (requestContentType != null) {
            message = message + " and content type [" + requestContentType + "]";
        }

        throw new RestClientException(message);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM