Java开发--36--Springboot的响应式编程
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java开发--36--Springboot的响应式编程,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5959字,纯文字阅读大概需要9分钟。
内容图文
一、WebFlux 简介
以下内容来自官网,有做部分表述优化
Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于Spring MVC,它不需要依赖Servlet API,它是完全异步非阻塞的,并且基于 Reactor 来实现响应式流规范。
1.1、Spring WebFlux有两种表现形式:基于配置和基于注释。
基于注释的实现方式如以下实例:
@RestController
@RequestMapping("/users")
public class MyRestController {
@GetMapping("/{user}")
public Mono<User> getUser(@PathVariable Long user) {
// ...
}
@GetMapping("/{user}/customers")
public Flux<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@DeleteMapping("/{user}")
public Mono<User> deleteUser(@PathVariable Long user) {
// ...
}
}
基于配置的实现方式,把路由和具体请求逻辑分离开,如以下实例:
@Configuration
public class RoutingConfiguration {
@Bean
public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
return route(GET("/{user}").and(accept(APPLICATION_JSON)), userHandler::getUser)
.andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
.andRoute(DELETE("/{user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
}
}
@Component
public class UserHandler {
public Mono<ServerResponse> getUser(ServerRequest request) {
// ...
}
public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
// ...
}
public Mono<ServerResponse> deleteUser(ServerRequest request) {
// ...
}
}
1.2、编码器和解码器
Spring WebFlux使用HttpMessageReader和HttpMessageWriter接口来转换HTTP请求和响应,可以通过CodecConfigurer得到它们的默认配置:
public interface CodecConfigurer {
...
List<HttpMessageReader<?>> getReaders();
List<HttpMessageWriter<?>> getWriters();
...
}
Springboot提供了CodecCustomizer接口,允许你进一步定制编解码器,通过其customize()
方法可以获取到CodecConfigurer对象,从而可以注册新的编解码工具,或对现有的编解码工具进行替换等。如以下实例:
@Configuration
public class MyConfiguration {
@Bean
public CodecCustomizer myCodecCustomizer() {
return codecConfigurer -> {
// ...
}
}
}
1.3、静态资源
Springboot默认从类路径的以下目录/static
、/public
、/resources
、/META-INF/resources
加载静态资源,默认将静态资源映射在/**
的路径下。除了以上标准静态资源外,特殊情况下如果静态资源被打包成了webjars的格式,那么访问这些资源的路径就变成了/webjars/**
Spring WebFlux应用程序不严格依赖Servlet API,因此不能将它们部署为war文件,也不使用src/main/webapp目录。
二、代码实例实现
1、添加pom依赖
<!-- 导入spring-boot-starter-webflux包 -->
<dependency>
<!--
spring-boot-starter-web和spring-boot-starter-webflux不能同时引入,
因为spring-boot-starter-web的优先级较高,
同时引入会导致Springboot自动配置starter-web,而不是starter-webflux
-->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2、controller/UserController.java
@RestController
@RequestMapping("/api/v1/user")
public class UserController {
private final UserService userService;
// 构造函数
public UserController(final UserService userService) {
this.userService = userService;
}
// 测试接口,测试接口是否能正常使用
@GetMapping("/test")
public Mono<String> test(){
// Mono.just返回一个对象
return Mono.just("hello 随亦小宝宝");
}
// 功能描述:根据id找用户
@GetMapping("find")
public Mono<User> findByid(final String id){
return userService.getById(id);
}
// 功能描述:删除用户
@GetMapping("del")
public Mono<User> del(final String id){
return userService.del(id);
}
// 功能描述:列表
// 响应类型produces,此处配置将数据一个一个流式输出,即拿到一个反馈一个
@GetMapping(value="list",produces=MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<User> list(){
// delayElements延迟对象,括号中是延迟秒数,此处是1秒
return userService.list().delayElements(Duration.ofSeconds(1));
}
}
3、domain/User.java
public class User {
private String id;
private String name;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public User(String id, String name) {
super();
this.id = id;
this.name = name;
}
}
4、service/UserService.java
@Service
public class UserService {
private static final Map<String, User> dataMap = new HashMap<>();
// mapper存储初始数据,用于模拟数据库
static{
dataMap.put("1", new User("1", "AAAAAAAAA"));
dataMap.put("2", new User("2", "BBBBBBBBB"));
dataMap.put("3", new User("3", "CCCCCCCCC"));
dataMap.put("4", new User("4", "DDDDDDDDD"));
dataMap.put("5", new User("5", "EEEEEEEEE"));
dataMap.put("6", new User("6", "FFFFFFFFF"));
dataMap.put("7", new User("7", "GGGGGGGGG"));
}
// 功能描述:返回用户列表
public Flux<User> list(){
Collection<User> list = UserService.dataMap.values();
// 将list转换为Flux异步序列
return Flux.fromIterable(list);
}
// 功能描述:根据id查找用户
public Mono<User> getById(final String id){
return Mono.justOrEmpty(UserService.dataMap.get(id));
}
// 功能描述:根据id删除用户
public Mono<User> del(final String id){
return Mono.justOrEmpty(UserService.dataMap.remove(id));
}
}
5、xiangyingApplication.java
@SpringBootApplication
public class XiangyingApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(XiangyingApplication.class, args);
}
}
6、项目演示
测试接口:
查看所有用户(这里实际上是一个一个输出展示的)
根据id查找用户
根据id删除用户
可见id=1的用户已经被删除掉了
三、WebFlux客户端WebClient
test/……/WebClientTest.java
// 测试类
public class WebClientTest {
@Test
public void testBase1(){
Mono<String> bodyMono = WebClient.create().get()
// 取id=1的对象
.uri("http://localhost:8080/api/v1/user/find?id=3")
.accept(MediaType.APPLICATION_JSON)
.retrieve().bodyToMono(String.class);
System.out.println(bodyMono.block());
}
@Test
public void testBase2(){
Mono<String> bodyMono = WebClient.create().get()
// 取id=2的对象
.uri("http://localhost:8080/api/v1/user/find?id={id}",2)
.accept(MediaType.APPLICATION_JSON)
.retrieve().bodyToMono(String.class);
System.out.println(bodyMono.block());
}
}
运行代码(右键类–>Run):
运行效果演示:
四、总结
项目代码结构如下所示:
内容总结
以上是互联网集市为您收集整理的Java开发--36--Springboot的响应式编程全部内容,希望文章能够帮你解决Java开发--36--Springboot的响应式编程所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。