美文网首页
RestTemplate 抓包及使用

RestTemplate 抓包及使用

作者: 北海北_6dc3 | 来源:发表于2020-02-21 22:42 被阅读0次

配置

定义bean方式一

@Configuration
public class SpringConfig {
    @Bean
    public RestTemplate getRestTemplate() {
        System.setProperty("http.proxyHost", "127.0.0.1");
        System.setProperty("http.proxyPort", "8888");
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
        int mseconds = Integer.valueOf(8000);
        httpRequestFactory.setConnectionRequestTimeout(mseconds);
        httpRequestFactory.setConnectTimeout(mseconds);
        httpRequestFactory.setReadTimeout(mseconds);
        return new RestTemplate(httpRequestFactory);
    }
}

定义bean方式二

@Configuration
public class SpringConfig {
    @Bean
    public RestTemplate getRestTemplate() {
        RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory() {{
            setProxy(new java.net.Proxy(java.net.Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)));
        }});
        return restTemplate;
    }
}

说明:设置代理8888是为了fiddler抓包。
参见:
https://www.okcode.net/article/47473

那么我们第一种和第二种定义有什么区别尼?

ClientHttpRequestFactory接口主要提供了两种实现方式

  • 一种是SimpleClientHttpRequestFactory,使用J2SE提供的方式(既java.net包提供的方式)创建底层的Http请求连接HttpURLConnection,默认使用此方式。
  • 一种方式是使用HttpComponentsClientHttpRequestFactory方式,底层使用HttpClient访问远程的Http服务,使用HttpClient可以配置连接池和证书等信息。

参见:
https://stackoverflow.com/questions/25698072/simpleclienthttprequestfactory-vs-httpcomponentsclienthttprequestfactory-for-htt
https://juejin.im/entry/5b21c6d55188257d9b79e1e8

By default RestTemplate uses SimpleClientHttpRequestFactory which depends on default configuration of HttpURLConnection.
If you want to use HttpComponentsClientHttpRequestFactory - it has a connection pooling configuration which SimpleClientHttpRequestFactory does not have.

model定义

@Data
public class AuthInfo implements Serializable {
    private String CSPID;
    private String UserID;
    private String ContentID;
    private String ProductID;
    private String ServiceID;
    private String Token;
}

调用

    public String auth(AuthInfo authInfo) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        //如果对方返回类型不为json,不加这句话,会报404错误。
        headers.set("Accept","*/*");
        HttpEntity<AuthInfo> entity = new HttpEntity<AuthInfo>(authInfo, headers);
        ResponseEntity<String> responseEntity = restTemplate.postForEntity(authUrl, entity, String.class);
        String result = responseEntity.getBody();
        System.out.println(result);
        return result;
    }

坑1:对方返回类型为Content-Type: text/html; charset=UTF-8,如果accept类型不匹配,会报404,故,需要增加headers.set("Accept","/");
坑2:参数要求首字母大写。如定义。
要求格式:

{
    "CSPID": 2316,
    "ContentID": "asdf",
    "ProductID": "asfs",
    "UserID": "sdfs",
    "Token": "sfss",
    "ServiceID":"20171902141"
}

我们序列化的格式

{
    "cspid": 2316,
    "contentID": "asdf",
    "productID": "asfs",
    "userID": "sdfs",
    "token": "sfss",
    "serviceID":"20171902141"
}

如何处理参数大写问题?

首先我们需要确认,restTemplate使用的什么序列化json.
消息转换核心代码

        //getMessageConverters()获取消息转换 的方法
        for (HttpMessageConverter<?> messageConverter : getMessageConverters()) {
            if (messageConverter instanceof GenericHttpMessageConverter) {
                GenericHttpMessageConverter<Object> genericMessageConverter = (GenericHttpMessageConverter<Object>) messageConverter;
                if (genericMessageConverter.canWrite(requestBodyType, requestBodyClass, requestContentType)) {
                   .......
                    genericMessageConverter.write(
                            requestBody, requestBodyType, requestContentType, httpRequest);
                    return;
                }
            }
            else if (messageConverter.canWrite(requestBodyClass, requestContentType)) {
                 .....
            }
        }



    //messageConverters包含的转换器
    public List<HttpMessageConverter<?>> getMessageConverters() {
        return this.messageConverters;
    }
    //messageConverters初始化
    public RestTemplate() {
        this.messageConverters.add(new ByteArrayHttpMessageConverter());
        this.messageConverters.add(new StringHttpMessageConverter());
        this.messageConverters.add(new ResourceHttpMessageConverter());
        this.messageConverters.add(new SourceHttpMessageConverter<Source>());
        this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());

        if (romePresent) {
            this.messageConverters.add(new AtomFeedHttpMessageConverter());
            this.messageConverters.add(new RssChannelHttpMessageConverter());
        }

        if (jackson2XmlPresent) {
            this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
        }
        else if (jaxb2Present) {
            this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
        }

        if (jackson2Present) {
            this.messageConverters.add(new MappingJackson2HttpMessageConverter());
        }
        else if (gsonPresent) {
            this.messageConverters.add(new GsonHttpMessageConverter());
        }
    }

    //加载jackson2Present 的条件
    private static final boolean jackson2Present =
            ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
                    RestTemplate.class.getClassLoader()) &&
            ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator",
                    RestTemplate.class.getClassLoader());

    //成功加载,即为成功。
    public static boolean isPresent(String className, ClassLoader classLoader) {
        try {
            forName(className, classLoader);
            return true;
        }
        catch (Throwable ex) {
            // Class or one of its dependencies is not present...
            return false;
        }
    }

以下是messageConverters运行时 包含的对象.

image.png

我们可以看到,消息转换器默认使用的是jackson2。
所以我们需要使用@JsonProperty
参见:
https://blog.csdn.net/qingguiyu/article/details/79215448
使用后和@Data使用,发现会生成多份数据。需要移除@Data,将@JsonProperty放到get方法上。
参见:
https://blog.csdn.net/weixin_41450959/article/details/87691788

其他一些技巧:
https://www.cnblogs.com/soul-wonder/p/8890728.html
连接池信息
https://juejin.im/post/5d2c72cde51d4555fd20a3f6

相关文章

网友评论

      本文标题:RestTemplate 抓包及使用

      本文链接:https://www.haomeiwen.com/subject/bmxhqhtx.html