SpringBoot 同步和异步网络请求

这篇具有很好参考价值的文章主要介绍了SpringBoot 同步和异步网络请求。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于

本文主要介绍springboot下的一些网络请求方式,包含同步请求和异步请求。

正文

1. ResTemplata方式

这种方式是同步请求。

此处再次介绍同步和异步的区别:

同步,是指一个任务接着一个任务,当上一个任务完成时,才可以开启下一个任务。在网络请求中是指,当向网络服务器发送网络请求时,服务器会对请求进行处理,处理结束后会响应对应的内容。在接收到响应内容前,是不能继续发送请求的,需要等待接收到网络响应才可以继续。

异步,是指可以开启一个任务队列,可以满足多个任务同时进行,当队列中有任务结束,就可以继续添加新任务。当向网络服务器发送网络请求后,只要在等待响应的任务数没有超过设定的限额,就可以继续进行发送任务。例如,1000人参加只有100台设备的考试,首先可以让100人参加,如果其中有人提前完成,就可以让第101人进入考试。这样的方式,可以提高效率,达到减少网络请求时间的目的。

具体实现代码如下:

Map<String, Object> map = new HashMap<>();
// map中存放我想要发送的json键值对
map.put("a", "123456789");
map.put("b", 1);

LinkedMultiValueMap<String, String> newmap = new LinkedMultiValueMap<>();
// newmap是对发送json字符串进行打包的map包
newmap.add("data",  JSONObject.toJSONString(map));

// 构造请求
HttpHeaders httpHeaders = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/x-www-form-urlencoded;charset=UTF-8");
// 这串字符的请求类型,这里为表单形式
httpHeaders.setContentType(type);
HttpEntity<LinkedMultiValueMap<String, String>> httpEntity = new HttpEntity<>(newmap, httpHeaders);
// 打包成发送的实体数据
ResponseEntity<String> apiResponse = restTemplate.postForEntity("http://127.0.0.1:8081/placesearch",httpEntity,String.class);
此处发送请求,此处会一直阻塞等待,直到请求结果返回,然后才继续执行下面的部分
String result = apiResponse.getBody();

这里的数据处理方式其实是有点过于冗杂了(我代码写得太烂了)。此处发送的请求是给另一个springboot的接口,由于不明的原因,设置了很多种形式,对面的接口都无法正常接收到发送的数据,然后我就找啊找啊找,最后在某次不起眼的尝试后,终于发送数据成功了,对面接收到数据了。

接收端的代码:

@RequestMapping(value = "/placesearch", method = RequestMethod.POST)
@ResponseBody
public String placesearch(String data){
    System.out.println(data);
    // 这里的data就是我上面要发送的map键值对,形式为字符串,需要转为json格式
}

由于功能实现了,所以就没有研究有没有其它的数据打包方式,有兴趣的童鞋可以继续研究研究。

补充一个restTemplate网络请求的具体配置:

// restTemplate网络请求设置
SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setConnectTimeout(10*100);
requestFactory.setReadTimeout(10*1000);
RestTemplate client = new RestTemplate(requestFactory);
HttpHeaders httpHeaders = new HttpHeaders();
MediaType type = MediaType.parseMediaType("application/x-www-form-urlencoded;charset=UTF-8");
httpHeaders.setContentType(type);

2. WebClient方式

这是一种异步的请求方式。在我的项目中,用的是这种方式,因为可以减少程序运行时间,加快任务完成速度。

Map<String, ArrayList<List<String>>> rawMap = new HashMap<>();
rawMap.put("data", dis);
// 此处rawMap仍然是一个map类型的数据

WebClient client = WebClient.create();
@SuppressWarnings("rawtypes")
Flux<Map> mapFlux = client.post().uri("http://127.0.0.1:8080/api").contentType(MediaType.APPLICATION_FORM_URLENCODED).body(BodyInserters.fromFormData("data",JSONObject.toJSONString(rawMap))).retrieve().bodyToFlux(Map.class);

mapFlux.collectList().subscribe(maps -> {
    String result = (String) maps.get(0).get("res");
    // api接口返回的是一个json数据,如{"res":"1"};
    System.out.println(result);
});

这里的请求是异步的,即发送请求后,不会一直阻塞在请求语句,会继续执行后面的语句,而每次返回的结果都用mapFlux进行收集和处理,我在上面对结果进行了打印,这个任务是在收到返回结果后进行,与整体的任务进程无关。

如果需要在短期内实现大量上面的请求,就需要配置线程池大小,具体代码如下:

ConnectionProvider connectionProvider = ConnectionProvider.builder("myConnectionPool").maxConnections(100000).pendingAcquireMaxCount(100000).build();
// 这里将线程池增加到100000,基本上不会出现线程池爆满
ReactorClientHttpConnector clientHttpConnector = new ReactorClientHttpConnector(HttpClient.create(connectionProvider));

Map<String, String> res = new HashMap<>();
// mapAll是多个键值对,值为发送内容,键为记录内容
for(String key: mapAll.keySet()){
    WebClient client = WebClient.builder().clientConnector(clientHttpConnector).build();
        
    @SuppressWarnings("rawtypes")
     Flux<Map> mapFlux = client.post().uri("http://127.0.0.1:8080/api").contentType(MediaType.APPLICATION_FORM_URLENCODED).body(BodyInserters.fromFormData("data",JSONObject.toJSONString(mapAll.get(key)))).retrieve().bodyToFlux(Map.class);
     mapFlux.collectList().subscribe(maps -> {
         String result = (String) maps.get(0).get("res");
         System.out.println(result);
     });
}

配置线程池大小的目的是为了防止加入的请求数量超过设定的最大数量,导致线程阻塞。一开始我没有设置数量,所以出现了问题,经过线程池数量设置后,完美解决了这个问题。

3. httpAsyncClient方式

这个方法没有具体研究,直接上代码:

// 使用httpAsyncClient实现异步请求,效果和webClient差不多,但是代码更加复杂
CloseableHttpAsyncClient httpAsyncClient = HttpAsyncClients.createDefault();

httpAsyncClient.start();

String requestPath = "http://127.0.0.1:8080/api";

HttpPost post = new HttpPost(requestPath);

List<NameValuePair> list = new ArrayList<>();

list.add(new BasicNameValuePair("data", JSONObject.toJSONString(rawMap)));

post.setEntity(new UrlEncodedFormEntity(list, "utf-8"));

httpAsyncClient.execute(post, new Back());

Back()方法代码:

class Back implements FutureCallback<HttpResponse>{
        Back(){}

        @Override
        public void completed(HttpResponse httpResponse) {
            try{
                org.apache.http.HttpEntity responseEntity = httpResponse.getEntity();
                System.out.println(EntityUtils.toString(responseEntity));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void failed(Exception e) {
            System.out.println("failed");
        }

        @Override
        public void cancelled() {

        }
    }

使用方式较为复杂,所以不太推荐使用。

总结

本文介绍了三种网络访问请求方式,第一种比较适合用于同步请求,第二种比较适合用于异步请求,第三种仅供学习参考,用起来还是不太方便。

对于需要在springboot下进行网络访问请求的童靴,可以参考学习。文章来源地址https://www.toymoban.com/news/detail-404407.html

到了这里,关于SpringBoot 同步和异步网络请求的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 微信小程序中封装请求,使用Async await方法,将异步请求变为同步请求方法

    介绍 微信小程序中,很多 API 都是异步的,无法同步处理。可以使用高级封装,通过 async await 方法来同步处理。 方法 在小程序右上角的 详情 里选择 本地设置 , 勾选 ES6转ES5 ,如下所示: 由于 Async Await 是 ES7 语法,所以在小程序里勾选 es6 转 ES5 会报错: ReferenceError: regene

    2024年02月08日
    浏览(42)
  • 微信小程序——异步请求使用async/await实现同步

            在小程序的开发中,我们知道网络请求wx.requset是一个异步请求的API,当我们使用它时,会出现请求还没有结束,我们下面写的处理数据的代码就已经执行了从而导致了我们写的程序出现问题,那么我们该怎么解决这个问题呢?今天我们用async/await来实现一下吧。

    2024年02月11日
    浏览(30)
  • 同步_异步请求和Ajax并利用axios框架简化

    目录 同步和异步 原生的Ajax 创建XMLHttpRequest对象 常用方法 常用属性 axios框架 同步请求:发送请求后,会做出回应,回应的内容会覆盖浏览器中的内容,这样会打断其他正常的操作,显得不太友好,并且请求时会携带所有的信息。 异步请求:前端正常输入时,可以同时与后端

    2024年02月13日
    浏览(29)
  • verilog|关于异步复位,同步释放的几个思考

    异步复位,同步释放是一种常见的设计思路,那么 什么情况下,复位信号需要做“异步复位,同步释放”处理? 一般来说,同步系统,都使用异步复位。这是因为同步复位的电路实现,比异步复位的电路实现,要浪费更多电路资源。 未在本模块时钟域做过“异步复位,同步

    2023年04月15日
    浏览(27)
  • Vue 网络处理 - axios 异步请求的使用,请求响应拦截器(最佳实践)

    目录 一、axiox 1.1、axios 简介 1.2、axios 基本使用 1.2.1、下载核心 js 文件. 1.2.2、发送 GET 异步请求 1.2.3、发送 POST 异步请求 1.2.4、发送 GET、POST 请求最佳实践 1.3、请求响应拦截器 1.3.1、拦截器解释 1.3.2、请求拦截器的使用 1.3.3、响应拦截器的使用 1.3.4、拦截器在 Vue 脚手架中的

    2024年02月04日
    浏览(33)
  • 【微信小程序】使用 wx.request 方法进行异步网络请求

    在微信小程序中,你可以使用 wx.request 方法进行异步网络请求,并将获取到的列表数据渲染到 UI 上。 首先,在页面的 data 中定义一个数组变量,用于存储获取到的列表数据,例如: 然后,在页面的生命周期函数 onLoad 或需要触发网络请求的函数中,使用 wx.request 方法发送异

    2024年02月16日
    浏览(42)
  • Redux工具包(二) - Redux Toolkit的异步操作(发送网络请求)

    Redux Toolkit异步操作 在之前的开发中,我们通过redux-thunk中间件让dispatch中可以进行异步操作, 其实Redux Toolkit工具包默认已经给我们集成了Thunk相关的功能, 我们可以通过 createAsyncThunk 函数创建一个异步的action createAsyncThunk函数有参数: 参数一: 传入事件类型type 参数二: 传入一个

    2024年02月01日
    浏览(32)
  • 在redux中如何进行异步操作?在redux中如何发送网络请求?

    Redux是一个非常受欢迎的状态管理库,它使得在应用程序中共享和管理数据变得更加容易。尽管Redux本身是一个同步状态管理库,但它提供了许多支持异步操作的工具,包括Redux-Thunk、Redux-Saga和Redux-Observable。在本文中,我们将探讨在Redux中进行异步操作的不同方法,并深入了解

    2023年04月09日
    浏览(35)
  • 18、全文检索--Elasticsearch-- SpringBoot 整合 Spring Data Elasticsearch(异步方式(Reactive)和 传统同步方式 分别操作ES的代码演示)

    启动命令行窗口,执行:elasticsearch 命令即可启动 Elasticsearch 服务器 三种查询方式解释: 方法名查询: 就是全自动查询,只要按照规则来定义查询方法 ,Spring Data Elasticsearch 就会帮我们生成对应的查询语句,并且生成方法体。 @Query 查询 : 就是半自动查询, 按照 S

    2024年03月12日
    浏览(54)
  • Java网络开发(Tomcat同步数据增删改查)—— 用Jsp语法实现同步请求的 增删改查

    在jsp的同步请求下如何实现数据的增删查改; 如何控制只能操作自己的数据; 背景:如果新增一条图书信息,表格中记录的是图书的id,如果要知道具体的类型需要查另一张表;而前端显示时,需要以下拉框的形式进行选择。在新增成功后,再跳转回到显示所有信息的页面。

    2024年02月08日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包