1.快速入门

一、简介

RestTemplate是spring提供的http客户端模版,类似JdbcTemplate,它是线程安全的,支持切换不同的http客户端,目前支持HttpClient-4.3, OKHttp3, 基于netty4实现的http客户端和基于java的URLConnection实现的http客户端。

二、引入

RestTemplate默认已经包含在spring-web中,其默认采用java的URLConnection实现的http客户端,如果想更换不同的http客户端需要在pom增加需要的依赖,比如依赖okhttp

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>3.8.1</version>
</dependency>

三、构造实例

  1. 使用默认构造

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
    
  2. 使用okhttp

    @Bean
    public RestTemplate restTemplate() {
        OkHttp3ClientHttpRequestFactory f  =new OkHttp3ClientHttpRequestFactory();
        f.setConnectTimeout(2000);
        f.setReadTimeout(1000);
        f.setWriteTimeout(1000);
        return new RestTemplate(f);
    }
    

四、参数相关

  1. GET,无参或参数直接写死到url中,返回string

    String result = restTemplate.getForObject("http://vstat.v.blog.aa.com/dostat.do?method=getVideoPlayCount&v=85152140|85162109&rt=json", String.class);
    
  2. GET,参数较多,追加到url中

    String url = "http://vstat.v.blog.aa.com/dostat.do";
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
        .queryParam("method", "getVideoPlayCount")
        .queryParam("v", "85152140|85162109")
        .queryParam("rt", "json");
    String rst = restTemplate.getForObject(builder.buildAndExpand().toUri(), String.class);
    
  3. GET,占位符替换

    String url = "http://vstat.v.a.aa.com/dostat.do?method={method}&ids={ids}&rt={rt}&test={test}";
    String rst = restTemplate.getForObject(url, String.class, "getVideoPlayCount", "85152140|85162109;", "json", "测试");
    

    注意:这里的传的参数会进行编码操作,结果会是如下url:

    http://vstat.v.a.aa.com/dostat.do?method=getVideoPlayCount&ids=85152140%7C85162109%3B&rt=json&test=%E6%B5%8B%E8%AF%95

  4. GET,占位符替换(与3一样,只不过参数放到map中)

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("method", "getVideoPlayCount");
    map.put("ids", "85152140|85162109;");
    map.put("rt", "json");
    map.put("test", "测试");
    String url = "http://vstat.v.aa.com/dostat.do?method={method}&ids={ids}&rt={rt}&test={test}";
    String rst = restTemplate.getForObject(url, String.class, map);
    
  5. GET,占位符替换加参数追加:

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("method", "getVideoPlayCount");
    String url = "http://vstat.aa.com/dostat.do?method={method}";
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url)
        .queryParam("v", "85152140|85162109")
        .queryParam("rt", "json");
    String rst = restTemplate.getForObject(builder.buildAndExpand(map).toUri(), String.class);
    
  6. POST与GET类似,但是涉及到POST传参,如下:

    //用于发送post请求的参数
    Map<String, String> postMap = new HashMap<String, String>();
    postMap.put("a", "b");
    String url = "http://{domain}/dostat.do";
    //用于替换路径中的参数
    Map<String, String> map = new HashMap<String, String>();
    map.put("domain", "vstat.aa.com");
    UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(url);
    HttpEntity<Map<String, String>> httpEntity = new HttpEntity<Map<String, String>>(postMap);
    String rst = restTemplate.postForObject(builder.buildAndExpand(map).toUri(), httpEntity, String.class);
    

五、返回值相关

  1. 返回String类型

    上面的例子都是返回String

  2. 返回对象

    CountEntity countEntity = restTemplate.getForObject("http://vstat.aa.com/dostat.do?method=getVideoPlayCount&v=85152140|85162109&rt=json", CountEntity.class);
    

    默认,RestTemplate已经具备jackson来进行反序列化json。注意:如果响应中没有设置application/json的header,那么会报出如下错误:no suitable HttpMessageConverter found for response type此时需要返回String类型,然后使用外部的json工具解析

  3. 只返回http响应头:

    ResponseEntity<Void> rst = restTemplate.getForEntity("http://vstat.v.aa.com/dostat.do?method=getVideoPlayCount&v=85152140|85162109&rt=json", Void.class);
    

六、异常处理

  1. http状态码

    默认情况下,响应头的状态码为1xx或2xx或3xx都认为响应正常,4xx的会抛出HttpClientErrorException异常,5xx的会抛出HttpServerErrorException异常。

    可以继承org.springframework.web.client.DefaultResponseErrorHandler进行异常处理,默认的处理如下:

    public void handleError(ClientHttpResponse response) throws IOException {
        HttpStatus statusCode = getHttpStatusCode(response);
        switch (statusCode.series()) {
            case CLIENT_ERROR:
                throw new HttpClientErrorException(statusCode, response.getStatusText(),
                        response.getHeaders(), getResponseBody(response), getCharset(response));
            case SERVER_ERROR:
                throw new HttpServerErrorException(statusCode, response.getStatusText(),
                        response.getHeaders(), getResponseBody(response), getCharset(response));
            default:
                throw new RestClientException("Unknown status code [" + statusCode + "]");
        }
    }
    

    并设置restTemplate.setErrorHandler();

  2. 超时等其他异常

链接超时或者读取超时都会抛出ResourceAccessException,一般情况下,需要try…catch做处理,但是如果采用hystrix,千万不要捕获异常,因为hystrix会捕获异常进行降级。

七、一些配置

  1. http链接超时和读写超时:需要根据不同的httpclient实现来进行具体配置,一般都在ClientHttpRequestFactory的具体子类中配置,例如okhttp:

    OkHttp3ClientHttpRequestFactory f  =new OkHttp3ClientHttpRequestFactory();
    f.setConnectTimeout(2000);
    f.setReadTimeout(1000);
    
  2. 配置默认参数:如果某些参数确定是每次请求都携带且不变的,可以在初始化的时候就设置进去,例如:

    RestTemplate restTemplate = new RestTemplate();
    Map defaultUriVariables = new HashMap();
    defaultUriVariables.put("host", "a.aa.com");
    restTemplate.setDefaultUriVariables(defaultUriVariables);
    

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章