对于想了解Spring5WebClient使用SSL的读者,本文将提供新的信息,我们将详细介绍springwebshell,并且为您提供关于java-如何使用SpringWebClient禁用cook
对于想了解Spring 5 WebClient使用SSL的读者,本文将提供新的信息,我们将详细介绍spring webshell,并且为您提供关于java-如何使用Spring WebClient禁用cookie、spring 5 webclient使用指南、spring boot webflux webclient 应该何如正确使用?、spring boot使用WebClient调用HTTP服务代码示例的有价值信息。
本文目录一览:- Spring 5 WebClient使用SSL(spring webshell)
- java-如何使用Spring WebClient禁用cookie
- spring 5 webclient使用指南
- spring boot webflux webclient 应该何如正确使用?
- spring boot使用WebClient调用HTTP服务代码示例
Spring 5 WebClient使用SSL(spring webshell)
我正在尝试查找WebClient使用的示例。我的目标是使用Spring 5 WebClient使用https和自签名证书查询REST服务
有什么例子吗?
答案1
小编典典切勿在生产中使用此TrustManagerFactory。它仅用于测试目的,因此非常不安全。
@Beanpublic WebClient createWebClient() throws SSLException { SslContext sslContext = SslContextBuilder .forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build(); ClientHttpConnector httpConnector = HttpClient.create().secure { t -> t.sslContext(sslContext) } return WebClient.builder().clientConnector(httpConnector).build();}
答案2
小编典典像Spring 5.1.1长相(spring启动2.1.0)移除HttpClientOptions
从ReactorClientHttpConnector
,所以你不能配置选项在创建实例ReactorClientHttpConnector
现在有效的一种选择是:
val sslContext = SslContextBuilder .forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build()val httpClient = HttpClient.create().secure { t -> t.sslContext(sslContext) }val webClient = WebClient.builder().clientConnector(ReactorClientHttpConnector(httpClient)).build()
基本上,在创建HttpClient时,我们将配置不安全的 sslContext,然后将该httpClient传递给ReactorClientHttpConnector
全局使用。
另一个选项是TcpClient
使用不安全的sslContext 进行配置并使用它来创建HttpClient实例,如下所示:
val sslContext = SslContextBuilder .forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build()val tcpClient = TcpClient.create().secure { sslProviderBuilder -> sslProviderBuilder.sslContext(sslContext) }val httpClient = HttpClient.from(tcpClient)val webClient = WebClient.builder().clientConnector(ReactorClientHttpConnector(httpClient)).build()
java-如何使用Spring WebClient禁用cookie
有谁知道在Spring WebClient中是否有使用Reactor Netty HttpClient禁用cookie管理的方法?
我注意到WebClient.Builder和HttpClient API都提供了一种将cookie添加到出站请求的方法,但是我正在寻找一种方法来完全禁止它们(如果存在).类似于在Apache的HttpComponentClientBuilder上禁用Cookie管理.
在发送请求之前删除User-Agent标头的示例代码.
public class Main {
public static void main(String[] args) {
HttpClient httpClient = HttpClient.create().doOnRequest((request,connection) -> {
request.requestHeaders().remove("User-Agent");
});
WebClient client = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
Mono<String> r = client.get().uri("https://www.google.com").retrieve()
.bodyToMono(String.class);
System.out.println(r.block());
}
}
spring 5 webclient使用指南
序
之前写了一篇restTemplate使用实例,由于spring 5全面引入reactive,同时也有了restTemplate的reactive版webclient,本文就来对应展示下webclient的基本使用。
请求携带header
- 携带cookie
@Test
public void testWithCookie(){
Mono<String> resp = WebClient.create()
.method(HttpMethod.GET)
.uri("http://baidu.com")
.cookie("token","xxxx")
.cookie("JSESSIONID","XXXX")
.retrieve()
.bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
- 携带basic auth
@Test
public void testWithBasicAuth(){
String basicAuth = "Basic "+ Base64.getEncoder().encodeToString("user:pwd".getBytes(StandardCharsets.UTF_8));
LOGGER.info(basicAuth);
Mono<String> resp = WebClient.create()
.get()
.uri("http://baidu.com")
.header(HttpHeaders.AUTHORIZATION,basicAuth)
.retrieve()
.bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
- 设置全局user-agent
@Test
public void testWithHeaderFilter(){
WebClient webClient = WebClient.builder()
.defaultHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36")
.filter(ExchangeFilterFunctions
.basicAuthentication("user","password"))
.filter((clientRequest, next) -> {
LOGGER.info("Request: {} {}", clientRequest.method(), clientRequest.url());
clientRequest.headers()
.forEach((name, values) -> values.forEach(value -> LOGGER.info("{}={}", name, value)));
return next.exchange(clientRequest);
})
.build();
Mono<String> resp = webClient.get()
.uri("https://baidu.com")
.retrieve()
.bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
get请求
- 使用placeholder传递参数
@Test
public void testUrlPlaceholder(){
Mono<String> resp = WebClient.create()
.get()
//多个参数也可以直接放到map中,参数名与placeholder对应上即可
.uri("http://www.baidu.com/s?wd={key}&other={another}","北京天气","test") //使用占位符
.retrieve()
.bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
- 使用uriBuilder传递参数
@Test
public void testUrlBiulder(){
Mono<String> resp = WebClient.create()
.get()
.uri(uriBuilder -> uriBuilder
.scheme("http")
.host("www.baidu.com")
.path("/s")
.queryParam("wd", "北京天气")
.queryParam("other", "test")
.build())
.retrieve()
.bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
post表单
@Test
public void testFormParam(){
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("name1","value1");
formData.add("name2","value2");
Mono<String> resp = WebClient.create().post()
.uri("http://www.w3school.com.cn/test/demo_form.asp")
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.body(BodyInserters.fromFormData(formData))
.retrieve().bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
post json
- 使用bean来post
static class Book {
String name;
String title;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
@Test
public void testPostJson(){
Book book = new Book();
book.setName("name");
book.setTitle("this is title");
Mono<String> resp = WebClient.create().post()
.uri("http://localhost:8080/demo/json")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(Mono.just(book),Book.class)
.retrieve().bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
- 直接post raw json
@Test
public void testPostRawJson(){
Mono<String> resp = WebClient.create().post()
.uri("http://localhost:8080/demo/json")
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject("{\n" +
" \"title\" : \"this is title\",\n" +
" \"author\" : \"this is author\"\n" +
"}"))
.retrieve().bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
post二进制--上传文件
@Test
public void testUploadFile(){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
HttpEntity<ClassPathResource> entity = new HttpEntity<>(new ClassPathResource("parallel.png"), headers);
MultiValueMap<String, Object> parts = new LinkedMultiValueMap<>();
parts.add("file", entity);
Mono<String> resp = WebClient.create().post()
.uri("http://localhost:8080/upload")
.contentType(MediaType.MULTIPART_FORM_DATA)
.body(BodyInserters.fromMultipartData(parts))
.retrieve().bodyToMono(String.class);
LOGGER.info("result:{}",resp.block());
}
下载二进制
- 下载图片
@Test
public void testDownloadImage() throws IOException {
Mono<Resource> resp = WebClient.create().get()
.uri("http://www.toolip.gr/captcha?complexity=99&size=60&length=9")
.accept(MediaType.IMAGE_PNG)
.retrieve().bodyToMono(Resource.class);
Resource resource = resp.block();
BufferedImage bufferedImage = ImageIO.read(resource.getInputStream());
ImageIO.write(bufferedImage, "png", new File("captcha.png"));
}
- 下载文件
@Test
public void testDownloadFile() throws IOException {
Mono<ClientResponse> resp = WebClient.create().get()
.uri("http://localhost:8080/file/download")
.accept(MediaType.APPLICATION_OCTET_STREAM)
.exchange();
ClientResponse response = resp.block();
String disposition = response.headers().asHttpHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION);
String fileName = disposition.substring(disposition.indexOf("=")+1);
Resource resource = response.bodyToMono(Resource.class).block();
File out = new File(fileName);
FileUtils.copyInputStreamToFile(resource.getInputStream(),out);
LOGGER.info(out.getAbsolutePath());
}
错误处理
@Test
public void testRetrieve4xx(){
WebClient webClient = WebClient.builder()
.baseUrl("https://api.github.com")
.defaultHeader(HttpHeaders.CONTENT_TYPE, "application/vnd.github.v3+json")
.defaultHeader(HttpHeaders.USER_AGENT, "Spring 5 WebClient")
.build();
WebClient.ResponseSpec responseSpec = webClient.method(HttpMethod.GET)
.uri("/user/repos?sort={sortField}&direction={sortDirection}",
"updated", "desc")
.retrieve();
Mono<String> mono = responseSpec
.onStatus(e -> e.is4xxClientError(),resp -> {
LOGGER.error("error:{},msg:{}",resp.statusCode().value(),resp.statusCode().getReasonPhrase());
return Mono.error(new RuntimeException(resp.statusCode().value() + " : " + resp.statusCode().getReasonPhrase()));
})
.bodyToMono(String.class)
.doOnError(WebClientResponseException.class, err -> {
LOGGER.info("ERROR status:{},msg:{}",err.getRawStatusCode(),err.getResponseBodyAsString());
throw new RuntimeException(err.getMessage());
})
.onErrorReturn("fallback");
String result = mono.block();
LOGGER.info("result:{}",result);
}
- 可以使用onStatus根据status code进行异常适配
- 可以使用doOnError异常适配
- 可以使用onErrorReturn返回默认值
小结
webclient是新一代的async rest template,api也相对简洁,而且是reactive的,非常值得使用。
doc
- restTemplate使用实例
- Decode ByteArray with spring 5 WebFlux framework
spring boot webflux webclient 应该何如正确使用?
我再尝试使用 webclient,因为 restTemplate 已经进入维护,但是有些细节不太了解,我写了一个简单的例子:
参考链接: https://spring.io/guides/gs/reactive-rest-service/
代码结构:
有一个 test 的入口 WebClientTestController
@RestController
@RequestMapping("/test")
public class WebClientTestController {
private final WebClient webClient;
public WebClientTestController(WebClient webClient) {
this.webClient = webClient;
}
@GetMapping
public Mono<Object> main() {
new SimpleAsyncTaskExecutor()
.execute(
() -> {
for (int i = 0; i <= 65536; ++i) {
System.out.println(
webClient
.get()
.uri("http://127.0.0.1:8080/hello")
.retrieve()
.bodyToMono(String.class)
.block()
+ i);
}
});
return Mono.empty();
}
}
appConfig
@Configuration
public class AppConfig {
@Bean
public WebClient webClient(WebClient.Builder builder) throws SSLException {
final SslContext sslContext =
SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();
HttpClient httpClient =
HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
return builder.clientConnector(new ReactorClientHttpConnector(httpClient)).build();
}
}
我再 window 上启动并访问: curl http://127.0.0.1:8080/test
可以得到正常输出:
一样的代码,我再 linux 上测试,得到错误:
请求成功的数量 ≈ ulimit -n
我想知道 webclient 的使用注意事项以及原理细节,为什么在 linux 上,这样用会每次请求打开一个 sockt 直到请求失败?
期望能得到回复,感谢~
spring boot使用WebClient调用HTTP服务代码示例
这篇文章主要介绍了spring boot使用WebClient调用HTTP服务代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
这篇文章主要介绍了spring boot使用WebClient调用HTTP服务代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
WebClient的请求模式属于异步非阻塞,能够以少量固定的线程处理高并发的HTTP请求
WebClient是Spring WebFlux模块提供的一个非阻塞的基于响应式编程的进行Http请求的客户端工具,从Spring5.0开始提供
在Spring Boot应用中
1.添加Spring WebFlux依赖
org.springframework.bootspring-boot-starter-webflux
2.使用
(1)Restful接口demoController.java
package com.example.demo.controller; import com.example.demo.domain.MyData; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @RestController @RequestMapping("/api") public class demoController { @GetMapping(value = "/getHeader", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}) public MyData getHeader(HttpServletRequest request) { int id = 0; if (request.getParameter("id") != null) { id = Integer.valueOf(request.getParameter("id")); } String name = request.getParameter("name"); //header String userAgent = "USER_AGENT――" + request.getHeader(HttpHeaders.USER_AGENT); userAgent += " | ACCEPT_CHARSET――" + request.getHeader(HttpHeaders.ACCEPT_CHARSET); userAgent += " | ACCEPT_ENCODING――" + request.getHeader(HttpHeaders.ACCEPT_ENCODING); userAgent += " | contextpath――" + request.getcontextpath(); userAgent += " | AuthType――" + request.getAuthType(); userAgent += " | PathInfo――" + request.getPathInfo(); userAgent += " | Method――" + request.getmethod(); userAgent += " | QueryString――" + request.getQueryString(); Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { System.out.println(cookie.getName() + ":" + cookie.getValue()); } } MyData data = new MyData(); data.setId(id); data.setName(name); data.setother(userAgent); return data; } @PostMapping(value = "/getPost", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}) public MyData getPost(HttpServletRequest request) { int id = 0; if (request.getParameter("id") != null) { id = Integer.valueOf(request.getParameter("id")); } String name = request.getParameter("name"); System.out.println(name + "," + id); MyData data = new MyData(); data.setId(id); data.setName(name); return data; } /** * POST传JSON请求 */ @PostMapping(value = "/getPostJson", produces = {MediaType.APPLICATION_JSON_UTF8_VALUE}) public MyData getPostJson(@RequestBody(required = true) MyData data) { System.out.println(data.getId()); System.out.println(data.getName()); return data; } }
MyData.java
package com.example.demo.domain; public class MyData { private int id; private String name; private String other; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getother() { return other; } public void setother(String other) { this.other = other; } }
(2)WebClient使用
DemoApplicationTests.java
package com.example.demo; import com.example.demo.domain.MyData; import org.junit.Test; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.reactive.function.BodyInserters; import org.springframework.web.reactive.function.client.WebClient; import reactor.core.publisher.Mono; import java.time.Duration; import java.time.temporal.ChronoUnit; public class DemoApplicationTests { private WebClient webClient = WebClient.builder() .baseUrl("http://127.0.0.1:8080") .defaultHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko)") .defaultCookie("ACCESS_TOKEN", "test_token").build(); @Test public void WebGetDemo() { try { Mono resp = webClient.method(HttpMethod.GET).uri("api/getHeader?id={id}&name={name}", 123, "abc") .retrieve() .bodyToMono(MyData.class); MyData data = resp.block(); System.out.println("WebGetDemo result----- " + data.getString()); } catch (Exception e) { e.printstacktrace(); } } @Test public void WebPostDemo() { MultiValueMap formData = new LinkedMultiValueMap(2); formData.add("id", "456"); formData.add("name", "xyz"); Mono response = webClient.method(HttpMethod.POST).uri("/api/getPost") .contentType(MediaType.APPLICATION_FORM_URLENCODED) .body(BodyInserters.fromFormData(formData)) .retrieve() .bodyToMono(MyData.class).timeout(Duration.of(10, ChronoUnit.SECONDS)); System.out.println(response); MyData data = response.block(); System.out.println("WebPostDemo result----- " + data.getString()); } @Test public void WebPostJson() { MyData requestData = new MyData(); requestData.setId(789); requestData.setName("lmn"); Mono response = webClient.post().uri("/api/getPostJson") .contentType(MediaType.APPLICATION_JSON_UTF8) .syncBody(requestData) .retrieve() .bodyToMono(MyData.class).timeout(Duration.of(10, ChronoUnit.SECONDS)); MyData data = response.block(); System.out.println("WebPostJson result----- " + data.getString()); } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小编。
今天的关于Spring 5 WebClient使用SSL和spring webshell的分享已经结束,谢谢您的关注,如果想了解更多关于java-如何使用Spring WebClient禁用cookie、spring 5 webclient使用指南、spring boot webflux webclient 应该何如正确使用?、spring boot使用WebClient调用HTTP服务代码示例的相关知识,请在本站进行查询。
本文标签: