这里在添加openFign之前,为了方便自己,添加了knife4j和mybatisPlus和hutool包
所以就先说下knife4j
引入依赖,这里的依赖是加在父工程的pom里的
com.github.xiaoymin knife4j-spring-boot-starter 3.0.3
这里顺便加个lombook
org.projectlombok lombok true
然后修改配置文件,修改的原因:
Spring MVC的path有两种:ANT_PATH_MATCHER和PATH_PATTERN_PARSER。
Spring Boot微服务默认使用PATH_PATTERN_PARSER。
当Spring Boot 2.6.3和knife4j-3.0.3以及springfox-swagger2-3.0.0集成时,使用默认的PATH_PATTERN_PARSER启动报错。
mvc: path match: matching-strategy: ant_path_matcher
编写配置类,可以自定义,嫌麻烦的可以直接复制
@Configuration
@EnableSwagger2
public class Knife4jConfiguration {
@Bean(value = "defaultApi2")
public Docket defaultApi2() {
String groupName="3.X版本";
Docket docket=new Docket(DocumentationType.OAS_30)
.apiInfo(new ApiInfoBuilder()
.title("")
.description("# 这里记录服务端所有的接口的入参,出参等等信息")
.termsOfServiceUrl("")
.contact(new Contact("tan"," "," "))
.version("3.0")
.build())
//分组名称
.groupName(groupName)
.select()
//这里指定Controller扫描包路径
.apis(RequestHandlerSelectors.basePackage("com.tan.shop.controller"))
.paths(PathSelectors.any())
.build();
return docket;
}
}
这里在之前的controller上加了
@Api(tags = "微服务框架测试");
@ApiOperation("用户id")
来试试效果
@RestController
@RequestMapping("/user")
@RefreshScope
@Api(tags = "微服务框架测试")
public class UserController {
@Value("${tan-shop-user.test.userId}")
private String userId;
@Resource
private UserService userService;
@GetMapping("/getConfigTest")
@ApiOperation("用户id")
public String getConfigTest(){
return userId != null ?userId:"未找到当前配置";
}
}
这里设置下请求头,之后有用到
这里新建一个项目,然后把他注册到nacos上(和上一章一样的步骤)
作为服务提供者,(这里是因为我建好了表,添加mybatis-plus,于是就干脆把整个层级都整好了)
=======================================================================
新建一个数据库,或者直接新建一张表
添加依赖
mysql mysql-connector-java 8.0.29 com.baomidou mybatis-plus-boot-starter 3.5.1
这里要在下配置文件
datasource: url: jdbc:mysql://localhost:3306/cloud_shop (数据库连接参数) username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl(日志) map-underscore-to-camel-case: true (驼峰) mapper-locations: "classpath: mapper/*.xml"
然后idea右键选中表,直接通过插件生成
记得在启动类上加上
@MapperScan
路径是mapper的引用路径
准备好之后,就可正式以正式开始了
首先父工程pom引入依赖
org.springframework.cloud spring-cloud-starter-openfeign 3.1.1 org.springframework.cloud spring-cloud-loadbalancer 3.1.1
在服务提供者的Order模块里,写个接口
这是controller
@Api(tags = "订单服务")
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private OrderInfoService orderInfoService;
/**
* 查询订单号
* @param userId
* @return orderNo
*/
@ApiOperation("查询订单号")
@PostMapping("/getOrderNoByUserId")
public String getOrderNoByUserId(@RequestBody String userId,HttpServletRequest request){
return orderInfoService.getOrderNoByUserId(userId,request.getHeader("Authorization"));
}
这是service和serviceImpl
public interface OrderInfoService extends IService {
/**
* 查询订单号
*
* @param userId
* @param token
* @return OrderNo
*/
String getOrderNoByUserId(String userId,String token);
}
======================================================================================
@Service
public class OrderInfoServiceImpl extends ServiceImpl
implements OrderInfoService{
@Override
public String getOrderNoByUserId(String userId, String token) {
if ("52".equals(userId)){
return "这是订单号;"+"这是设置的token:"+token;
}
return "没有订单号;"+"这是设置的token";
}
之后在消费者的User启动类上添加开启远程调用的注解
@EnableFeignClients
新建一个Feign接口来处理远程调用的请求
@FeignClient(value = "tan-shop-order",fallback = OrderFeignHandler.class)
@Component
public interface OrderServiceFeign {
@PostMapping("/order/getOrderNoByUserId")
String getOrderNo(@RequestBody String userId, @RequestHeader("Authorization")String token);
}
这里 value = "tan-shop-order" 指的是你要调用的服务在nacos上的名字,在配置文件里
fallback = OrderFeignHandler.class 则是异常处理
新建一个类,实现Feign接口接口
@Component
public class OrderFeignHandler implements OrderServiceFeign{
@Override
public String getOrderNo(String userId,String token) {
String fallBack = "当前人数过多,休息一会再试";
return fallBack;
}
}
在User这边编写service和serviceImpl,用来调用openFign;serviceImpl注入openFign接口
public interface UserService {
/**
* 获取订单号
*
* @param userId
* @param request
* @return OrderNo
*/
String getOrderNo(String userId,HttpServletRequest request);
}
==========================================================================
@Service
public class UserServiceImpl implements UserService {
@Resource
private OrderServiceFeign orderServiceFeign;
@Override
public String getOrderNo(String userId, HttpServletRequest request) {
return orderServiceFeign.getOrderNo(userId,request.getHeader("token"));
}
}
这是controller,注入userService
在knife4j上发送请求
之前的代码里的
RequestAttributes currentRequestAttributes = RequestContextHolder.currentRequestAttributes(); HttpServletRequest request = ((ServletRequestAttributes) currentRequestAttributes).getRequest();
是用来获取请求头数据的
可以通过
@RequestHeader("Authorization")
来携带到远程服务
上面提到的fallback = OrderFeignHandler.class 则是异常处理,可以结合 sentinel 做熔断降级
一样的引入依赖
feign: sentinel: enabled: true
修改下代码,没有对应单号,就抛异常
@Override
public String getOrderNoByUserId(String userId, String token) {
if ("52".equals(userId)){
return "这是订单号;"+"这是设置的token:"+token;
}else {
throw new RuntimeException("出异常了");
}
}
=========================================================================
重启项目报了个错
Description:
The Bean Validation API is on the classpath but no implementation could be found
Action:
Add an implementation, such as Hibernate Validator, to the classpath
不知道是怎么回事,但是懒得去找为什么了;他说我缺了,那就给他补上
引入对应依赖
org.hibernate hibernate-validator 5.2.4.Final
=========================================================================
这里userId给个错的
进入异常了
触发熔断降级