REST(RepresentationalState Transfer)是Roy Fielding 提出的一个描述互联系统架构风格的名词。REST定义了一组体系架构原则,您可以根据这些原则设计以系统资源为中心的Web 服务,包括使用不同语言编写的客户端如何通过 HTTP处理和传输资源状态。

  为什么称为 REST?Web本质上由各种各样的资源组成,资源由URI 唯一标识。浏览器(或者任何其它类似于浏览器的应用程序)将展示出该资源的一种表现方式,或者一种表现状态。如果用户在该页面中定向到指向其它资源的链接,则将访问该资源,并表现出它的状态。这意味着客户端应用程序随着每个资源表现状态的不同而发生状态转移,也即所谓REST。

RestTemplate 是Spring封装的一个Rest风格http请求框架,底层可以切换成HttpClient OkHttp 或者Netty实现,用户只需要关心RestTemplate怎么用而不需要关心底层框架如何操作,使用RestTemplate不需要关心如何手动转换返回的对象和到处都是的异常处理代码,可以让你的代码更简洁更优雅。

主要作用:支持远程服务调用,类似HttpClient,也可以使用它来测试自己的接口

常用的方法:

1.getForEntity方法的返回值是一个ResponseEntity<T>,ResponseEntity<T>是Spring对HTTP请求响应的封装,包括了几个重要的元素,如响应码、contentType、contentLength、响应消息体等。

2.getForObject函数实际上是对getForEntity函数的进一步封装,如果你只关注返回的消息体的内容,对其他信息都不关注,此时可以使用getForObject

3.postForEntity 和getForEntity类似

4.postForObject 如果只关注,返回的消息体,可以直接使用postForObject。用法和getForObject一致

5.postForLocation也是提交新资源,提交成功之后,返回新资源的URI,postForLocation的参数和前面两种的参数一致,只不过返回值为Uri,只需要服务提供者返回一个Uri即可,该Uri表示新资源的位置。

6.其他的还有put(),delete()都不怎么常用

1.使用RestTemplate做测试接口功能代码:

有一个特别的地方,post如果传参数只能用LinkedMultiValueMap

@RunWith(SpringRunner.class)

@SpringBootTest

@WebAppConfiguration

public class UrlOnlineTests {

    private RestTemplate template =new RestTemplate();

    @Test

    public void testGet(){

        try {

            String url = "http://localhost:8080/selectSmallVideo?sdt=20180531&edt=20180531";

            String result = template.getForObject(url, String.class);

            System.err.println(result);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

/**为什么这个地方只能用LinkedMutiValueMap*/

    @Test

    public void testPost(){

        try {

            String url = "http://localhost:8080/selectSmallVideo2";

            LinkedMultiValueMap<String, Integer> map = new LinkedMultiValueMap<>();

            map.add("sdt", 20180531);

            map.add("edt", 20180531);

            String result = template.postForObject(url,map, String.class);

            System.err.println(result);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    @Test

    public void testGet2(){

        try {

            String url = "http://localhost:8080/selectSmallVideo?sdt=20180531&edt=20180531";

            ResponseEntity<String> entity = template.getForEntity(url, String.class);

            HttpStatus code = entity.getStatusCode();

            System.err.println(code);

            System.err.println(entity.toString());

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    @Test

    public void testExchange(){

        try {

            String url = "http://localhost:8080/selectSmallVideo?sdt=20180531&edt=20180531";

            HttpHeaders headers=new HttpHeaders();

            headers.add("devid","");

            headers.add("appver","9.3");

            HttpEntity<String> entity = new HttpEntity<>(null,headers);

            ResponseEntity<String> exchange = template.exchange(url, HttpMethod.GET, entity, String.class);

            System.err.println(exchange.toString());

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

2.使用RestTemplate调用远程接口,可以简化使用HttpClient繁琐

org.springframework.web.client.RestTemplate;

@Bean

  public RestTemplate restTemplate() {

    RestTemplateBuilder restTemplateBuilder = new RestTemplateBuilder();

    RestTemplate restTemplate = restTemplateBuilder.build();

    StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));//设置消息转换器,

    List<HttpMessageConverter<?>> list = new ArrayList<HttpMessageConverter<?>>();

    list.add(stringHttpMessageConverter);

    restTemplate.setMessageConverters(list);

    return restTemplate;

  }

HttpMessageConverter的作用:
1.通过@RequestBody、@ResponseBody注解,可以直接将输入解析成Json、将输出解析成Json,HTTP 请求和响应是基于文本的,通过消息转换器进行转换

2.Http请求响应报文其实都是字符串,当请求报文到java程序会被封装为一个ServletInputStream流,开发人员再读取报文,响应报文则通过ServletOutputStream流,来输出响应报文

从流中只能读取到原始的字符串报文,同样输出流也是。那么在报文到达SpringMVC / SpringBoot和从SpringMVC / SpringBoot出去,都存在一个字符串到java对象的转化问题,这一过程,在SpringMVC / SpringBoot中,是通过HttpMessageConverter来解决的

 @Autowired

  private RestTemplate restTemplate;

  private SimpleDateFormat SDF = new SimpleDateFormat("yyyyMMddHHmmss");

  private ErrorObject sendSms(String tel, String code, Integer templateId) {

    String time = SDF.format(new Date());

    String sig = Encript.md5(accountSid + authToken + time);

    String url = "/2013-12-26/Accounts/" + accountSid + "/SMS/TemplateSMS?sig=" + sig;

    Map<String, Object> entityMap = new HashMap<>();

    entityMap.put("to", tel);

    entityMap.put("appId", appId);

    entityMap.put("templateId", templateId);

    entityMap.put("datas", "[\"" + code + "\"]");

    HttpHeaders headers = new HttpHeaders();

    headers.setContentType(MediaType.APPLICATION_JSON);

    headers.setAccept(Lists.newArrayList(MediaType.APPLICATION_JSON));

    String str = accountSid + ":" + time;

    headers.add("Authorization", Base64.getEncoder().encodeToString(str.getBytes(Charset.forName("UTF-8"))));

    String request = new Gson().toJson(entityMap);

    HttpEntity<String> entity = new HttpEntity<String>(request, headers);

    String result = restTemplate.postForEntity(restUrl + url, entity, String.class).getBody();

    log.debug(result);

    Map<String, Object> retMap = new Gson().fromJson(result, Map.class);

    if (Integer.valueOf(retMap.get("statusCode").toString()).intValue() == 0) {

      return new ErrorObject();

    }

    return new ErrorObject(false, retMap.get("statusMsg").toString(),100);

  }


 

Logo

开源、云原生的融合云平台

更多推荐