1、WebFlux中,请求和响应不再是WebMVC中的ServletRequest和ServletResponse,而是ServerRequest和ServerResponse
2、加入依赖
如果同时存在spring-boot-starter-web,则会优先用spring-boot-starter-web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
3、案例
User.java
public class User {
private String id;
private String name;
public User(String id, String name) {
super();
this.id = id;
this.name = name;
}
}
UserService .java
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
@Service
public class UserService {
private static final Map<String,User> dataMap = new HashMap<>();
static {
dataMap.put("1",new User("1","用户1"));
dataMap.put("2",new User("2","用户2"));
dataMap.put("3",new User("3","用户3"));
dataMap.put("4",new User("4","用户4"));
dataMap.put("5",new User("5","用户5"));
dataMap.put("6",new User("6","用户6"));
dataMap.put("7",new User("7","用户7"));
}
/**
* 返回用户列表
* @return
*/
public Flux<User> list(){
Collection<User> list = UserService.dataMap.values();
return Flux.fromIterable(list);
}
/**
* 根据id查找用户
* @param id
* @return
*/
public Mono<User> getById(final String id){
return Mono.justOrEmpty(UserService.dataMap.get(id));
}
/**
* 根据id删除指定用户
* @param id
* @return
*/
public Mono<User> delById(final String id){
return Mono.justOrEmpty(UserService.dataMap.remove(id));
}
}
import org.springframework.http.MediaType;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;
@RestController
@RequestMapping("/web_flux/user")
public class WebFluxUserController {
//@Autowired
//private UserService userService;
private final UserService userService;
public WebFluxUserController(final UserService userService){
this.userService=userService;
}
@GetMapping("/test")
public Mono<String> test(){
return Mono.just("hello web_flux");
}
@GetMapping("list")
public Flux<User> list(){
return userService.list();
}
@GetMapping("find")
public Mono<User> findUserById(final String id){
return userService.getById(id);
}
@GetMapping("del")
public Mono<User> delUserById(final String id){
return userService.delById(id);
}
@GetMapping("list_duration")
public Flux<User> list_duration(){
//list.size()*2s 后返回结果
return userService.list().delayElements(Duration.ofSeconds(2));
}
@GetMapping(value = "list_duration_produces",produces = MediaType.APPLICATION_STREAM_JSON_VALUE)
public Flux<User> list_duration_produces(){
//每 2s 后返回结果
return userService.list().delayElements(Duration.ofSeconds(2));
}
}
4、测试
http://localhost:8080/web_flux/user/test
http://localhost:8080/web_flux/user/list
http://localhost:8080/web_flux/user/find?id=1
http://localhost:8080/web_flux/user/list_duration_produces
http://localhost:8080/web_flux/user/del?id=1
http://localhost:8080/web_flux/user/list_duration
5、SpringBoot WebFlux客户端WebClient的介绍和使用
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
//@RunWith(SpringRunner.class) //底层用junit SpringJUnit4ClassRunner
//@SpringBootTest(classes={FbiaoApplication.class})//启动整个springboot工程
public class WebClientTest {
@Test
public void testBase(){
Mono<String> resp = WebClient.create()
.get()
//多个参数也可以直接放到map中,参数名与placeholder对应上即可
.uri("http://localhost:8080/web_flux/user/find?id=1") //使用占位符
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class);
System.out.println(resp.block());
}
}
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
//@RunWith(SpringRunner.class) //底层用junit SpringJUnit4ClassRunner
//@SpringBootTest(classes={FbiaoApplication.class})//启动整个springboot工程
public class WebClientTest {
@Test
public void testPlaceHolder(){
Mono<String> resp = WebClient.create()
.get()
.uri("http://localhost:8080/web_flux/user/find?id={id}",2) //使用占位符
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class);
System.out.println(resp.block());
}
}