1、引入webFlux依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
如果引入webFlux的微服务之前,pom.xml中引入了`spring-boot-starter-web`的依赖,需要将`spring-boot-starter-web`依赖注释掉或者删除掉,因为webFlux的依赖与web的依赖是不兼容的。
2、编写调用的业务代码
这里可以根据需求调用远程服务。为了简便,在此次实验中只是在当前的服务下实现了一个业务代码。
例如:根据id查询支付记录。
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
@TableName("payment")
public class Payment {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String serial;
}
public interface PaymentMapper extends BaseMapper<Payment> {
}
@Slf4j
@Service
public class PaymentService {
@Resource
private PaymentMapper paymentMapper;
public Payment getById(Integer id) {
Payment payment = paymentMapper.selectById(id);
return payment;
}
}
@Slf4j
@RestController
@RequestMapping("/payment")
public class PaymentController {
@Resource
private PaymentService paymentService;
//根据id查询支付
@GetMapping("/getById")
public CommonResult<Payment> getPaymentById(Integer id) {
Payment payment = paymentService.getById(id);
if (payment != null) {
return new CommonResult<>(200, "数据查询成功", payment);
} else {
return new CommonResult<>(444, "数据查询失败", null);
}
}
}
3、WebFlux调用业务代码
@RestController
@RequestMapping("/webFlux")
public class WebFluxController {
@Resource
private WebFluxService webFluxService;
@GetMapping("/getById")
public Mono<CommonResult> getById(Integer id) {
return webFluxService.getPayment(id);
}
}
@Slf4j
@Service
public class WebFluxService {
public Mono<CommonResult> getPayment(Integer id) {
String path = "/payment/getById";
WebClient webClient = WebClient.builder()
.baseUrl("http://localhost:8001").build();
WebClient.ResponseSpec responseSpec = webClient.get()
.uri(uriBuilder -> uriBuilder.path(path).queryParam("id", id).build())
.header("Content-type", "application/json")
.retrieve();
Mono<ResponseEntity<String>> response = responseSpec.toEntity(String.class);
return response.flatMap(responseEntity -> {
//响应结构
HttpHeaders httpHeaders = responseEntity.getHeaders();
HttpStatus httpStatus = responseEntity.getStatusCode();
String body = responseEntity.getBody();
CommonResult commonResult = new CommonResult();
if (httpStatus == httpStatus.OK) {
commonResult = JSONObject.parseObject(body, CommonResult.class);
} else {
commonResult.setCode(500);
commonResult.setMessage("调用出错了");
}
return Mono.just(commonResult);
}).onErrorResume(exception -> {
log.error("使用webFlux远程调用失败:" + exception.getMessage());
CommonResult commonResult = new CommonResult();
commonResult.setCode(500);
commonResult.setMessage("调用出错了");
return Mono.just(commonResult);
});
}
}
使用WebClient.builder()
来创建一个web请求的链路。
尝试使用@Resource WebClient webClient;
的方式进行注入,发现无法注入,所以这里采用WebClient.builder()
的方式创建web请求的链路。
4、WebFlux的全局异常处理类
@Slf4j
@Component
@Order(-2) //这里将全局处理错误程序的顺序设置为-2,是为了让它比@Order(-1)注册的DefaultErrorWebExceptionHandler处理程序更高的优先级
public class GlobalErrorConfig extends AbstractErrorWebExceptionHandler {
public GlobalErrorConfig(DefaultErrorAttributes g, ApplicationContext applicationContext,
ServerCodecConfigurer serverCodecConfigurer) {
super(g, new WebProperties.Resources(), applicationContext);
super.setMessageWriters(serverCodecConfigurer.getWriters());
super.setMessageReaders(serverCodecConfigurer.getReaders());
}
@Override
protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);
}
private Mono<ServerResponse> renderErrorResponse(final ServerRequest request) {
Map<String, Object> errorPropertiesMap = getErrorAttributes(request, false);
int httpCode = errorPropertiesMap.get("status") == null ? 500 : Integer.parseInt(errorPropertiesMap.get("status").toString());
CommonResult commonResult = new CommonResult();
if (HttpStatus.NOT_FOUND.value() == httpCode) {
commonResult.setCode(404);
commonResult.setMessage("请求的资源不存在");
return ServerResponse.status(HttpStatus.NOT_FOUND)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(commonResult));
} else {
commonResult.setCode(500);
commonResult.setMessage("除404之外的错误");
return ServerResponse.status(HttpStatus.OK)
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(commonResult));
}
}
}