Springboot之访问web资源

Springboot之访问web资源

在springmvc中,访问web资源是重要的知识。

其中springboot整合了主要两种访问web资源的方式。

RestTemplate访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-enf0xrnP-1591437322240)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606163826291.png)][外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NujXUVNI-1591437322243)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606172842857.png)]

(来源于极客时间丁雪丰老师课件)

以一个例子来说明访问方法:

1.restemplate 配置方式:

//一般采用builder模式进行构建和配置
//或者以构造器的方式进行构建
	@Bean
	public RestTemplate restTemplate(RestTemplateBuilder builder) {
//		return new RestTemplate();
		return builder.build();
	}

2.构建uri

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xx1kQl4K-1591437322248)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606172153278.png)]

使用UriComponentBuilder类进行资源访问绑定,采用builder模式进行传参

URI uri = UriComponentsBuilder
		.fromUriString("http://localhost:8080/coffee/{id}")
		.build(1);

3.确定资源访问方式:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6iQu3qc7-1591437322252)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606170111427.png)]

(来源于极客时间丁雪丰老师课件)

例如:

		//getForEntity()方法以get方式在指定的uri上查询资源并以entity——coffee类型访问实体list
		ResponseEntity<Coffee> c = restTemplate.getForEntity(uri, Coffee.class);
		log.info("Response Status: {}, Response Headers: {}", c.getStatusCode(), c.getHeaders().toString());
		log.info("Coffee: {}", c.getBody());
		
		//以post方式去更新资源,则需要创建一个Coffee类对象,作为请求体传进去,同时
		//调用postForObject()方法来返回更新掉的资源类型
		String coffeeUri = "http://localhost:8080/coffee/";
		Coffee request = Coffee.builder()
				.name("Americano")
				.price(BigDecimal.valueOf(25.00))
				.build();
		Coffee response = restTemplate.postForObject(coffeeUri, request, Coffee.class);
		log.info("New Coffee: {}", response);

		String s = restTemplate.getForObject(coffeeUri, String.class);
		log.info("String: {}", s);

RestTemplate访问之升级版

传递 HTTP Header
• RestTemplate.exchange()
• RequestEntity / ResponseEntity

官网上对于这个的介绍是

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j5xy5Zrt-1591437322255)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606173437376.png)]

URI uri = UriComponentsBuilder
				.fromUriString("http://localhost:8080/coffee/?name={name}")
				.build("mocha");
RequestEntity<Void> req = RequestEntity.get(uri)
				.accept(MediaType.APPLICATION_XML)
				.build();
ResponseEntity<String> resp = restTemplate.exchange(req, String.class);
log.info("Response Status: {}, Response Headers: {}",  resp.getStatusCode(),resp.getHeaders().toString());
log.info("Coffee: {}", resp.getBody());

类型转换
• JsonSerializer / JsonDeserializer
• @JsonComponent

解析泛型对象
• RestTemplate.exchange()
• ParameterizedTypeReference

在解析泛型对象时应借助ParameterizedTypeReference

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9dDoUcnO-1591437322258)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606171908582.png)]

		String coffeeUri = "http://localhost:8080/coffee/";
		Coffee request = Coffee.builder()
				.name("Americano")
				.price(Money.of(CurrencyUnit.of("CNY"), 25.00))
				.build();
		Coffee response = restTemplate.postForObject(coffeeUri, request, Coffee.class);
		log.info("New Coffee: {}", response);

		ParameterizedTypeReference<List<Coffee>> ptr =
				new ParameterizedTypeReference<List<Coffee>>() {};
		ResponseEntity<List<Coffee>> list = restTemplate
				.exchange(coffeeUri, HttpMethod.GET, null, ptr);
		list.getBody().forEach(c -> log.info("Coffee: {}", c));

这里贴出restTemplate的exchange()方法的介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Xkj0rbNU-1591437322259)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606173046950.png)]

定制化RestTemplate

默认是实现SipleClientHttpRequestFactory

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cw9xbGWN-1591437322260)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606174532167.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GTmieXZT-1591437322262)(C:\Users\18221\AppData\Roaming\Typora\typora-user-images\image-20200606174326914.png)]

这方面的应用可以以下面的例子来说明

1.定义一个链接保持时间的策略类,主要是通过实现ConnectionKeepAliveStrategy接口

public class CustomConnectionKeepAliveStrategy implements ConnectionKeepAliveStrategy {
    private final long DEFAULT_SECONDS = 30;

    @Override
    public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
        return Arrays.asList(response.getHeaders(HTTP.CONN_KEEP_ALIVE))
                .stream()
                .filter(h -> StringUtils.equalsIgnoreCase(h.getName(), "timeout")
                        && StringUtils.isNumeric(h.getValue()))
                .findFirst()
                .map(h -> NumberUtils.toLong(h.getValue(), DEFAULT_SECONDS))
                .orElse(DEFAULT_SECONDS) * 1000;
    }
}

2.创建一个requestFactory

	@Bean
	public HttpComponentsClientHttpRequestFactory requestFactory() {
        //先创建链接管理器对象,来设置最大链接个数
		PoolingHttpClientConnectionManager connectionManager =
				new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS);
		connectionManager.setMaxTotal(200);
		connectionManager.setDefaultMaxPerRoute(20);

        //创建可关闭的httpclient
		CloseableHttpClient httpClient = HttpClients.custom()
				.setConnectionManager(connectionManager)
				.evictIdleConnections(30, TimeUnit.SECONDS)
				.disableAutomaticRetries()
				// 有 Keep-Alive 认里面的值,没有的话永久有效
				//.setKeepAliveStrategy(DefaultConnectionKeepAliveStrategy.INSTANCE)
				// 换成自定义的
				.setKeepAliveStrategy(new CustomConnectionKeepAliveStrategy())
				.build();
		//包装上这个属性
		HttpComponentsClientHttpRequestFactory requestFactory =
				new HttpComponentsClientHttpRequestFactory(httpClient);

		return requestFactory;
	}

4.调用的主要方法:

	@Override
	public void run(ApplicationArguments args) throws Exception {
		URI uri = UriComponentsBuilder
				.fromUriString("http://localhost:8080/coffee/?name={name}")
				.build("mocha");
		RequestEntity<Void> req = RequestEntity.get(uri)
				.accept(MediaType.APPLICATION_XML)
				.build();
		ResponseEntity<String> resp = restTemplate.exchange(req, String.class);
		log.info("Response Status: {}, Response Headers: {}", resp.getStatusCode(), resp.getHeaders().toString());
		log.info("Coffee: {}", resp.getBody());

		String coffeeUri = "http://localhost:8080/coffee/";
		Coffee request = Coffee.builder()
				.name("Americano")
				.price(Money.of(CurrencyUnit.of("CNY"), 25.00))
				.build();
		Coffee response = restTemplate.postForObject(coffeeUri, request, Coffee.class);
		log.info("New Coffee: {}", response);

		ParameterizedTypeReference<List<Coffee>> ptr =
				new ParameterizedTypeReference<List<Coffee>>() {};
		ResponseEntity<List<Coffee>> list = restTemplate
				.exchange(coffeeUri, HttpMethod.GET, null, ptr);
		list.getBody().forEach(c -> log.info("Coffee: {}", c));
	}

izedTypeReference<List>() {};
ResponseEntity<List> list = restTemplate
.exchange(coffeeUri, HttpMethod.GET, null, ptr);
list.getBody().forEach(c -> log.info(“Coffee: {}”, c));
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值