远程调用用户微服务及其他注意事项
与其他微服务一样,在购物车微服务中也需要完善 token
字段处理的逻辑,即在购物车微服务中调用用户微服务完成商城用户的鉴权及用户信息的获取。
第一步,增加配置,启用 OpenFeign
并使 FeignClient
类生效。
由于已经引入了 LoadBalancer
依赖和 user-api
依赖,因此这里可以直接通过 OpenFeign
来调用用户微服务中的接口用于商城用户的鉴权和信息获取。
打开 newbee-mall-cloud-shop-cart-web
工程,在项目的启动类 NewBeeMallCloudShopCartServiceApplication
中添加 @EnableFeignClients
注解,并配置相关的 FeignClient
类,代码如下:
@EnableFeignClients(basePackageClasses = {ltd.user.cloud.newbee.openfeign.NewBeeCloudUserServiceFeign.class})
这里使用 basePackageClasses
配置需要使用的 FeignClient
类,即 NewBeeCloudUserServiceFeign
类。接下来就可以直接使用 NewBeeCloudUserServiceFeign
类与用户微服务进行远程通信了。
第二步,修改 token
字段处理类中的逻辑代码。
打开 newbee-mall-cloud-shop-cart-web
工程,修改 TokenToMallUserMethodArgumentResolver
类中对 token
字段处理的逻辑代码,主要引入 NewBeeCloudUserServiceFeign
类,通过调用用户微服务来获取商城用户的数据。
修改后的代码如下:
@Component
public class TokenToMallUserMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Autowired
private NewBeeCloudUserServiceFeign newBeeCloudUserService;
public TokenToMallUserMethodArgumentResolver() {
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(TokenToMallUser.class)) {
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
if (parameter.hasParameterAnnotation(TokenToMallUser.class)) {
String token = webRequest.getHeader("token");
if (null != token && !"".equals(token) && token.length() == 32) {
// 调用用户微服务,根据token字段获取商城用户的数据
Result<MallUserDTO> result = newBeeCloudUserService.getMallUserByToken(token);
if (result == null || result.getResultCode() != 200 ||
result.getData() == null) {
throw new NewBeeMallException.fail(ServiceResultEnum.TOKEN_EXPIRE_ERROR.getResult());
}
MallUserToken mallUserToken = new MallUserToken();
mallUserToken.setToken(token);
mallUserToken.setUserId(result.getData().getUserId());
return mallUserToken;
} else {
NewBeeMallException.fail(ServiceResultEnum.NOT_LOGIN_ERROR.getResult());
}
}
return null;
}
}
如此便完成了在购物车微服务中通过远程通信获取当前登录用户信息的功能。
另外,购物车模块中的所有功能都只与商城用户相关,因此只需要处理商城用户即可。在全局异常处理类 ShopCartServiceExceptionHandler
中,由于购物车模块未涉及管理员用户账户,因此在区分自定义异常时有一些修改,要判断商城用户是否正常登录,未正常登录返回特定的响应代码 416
(管理员用户未正常登录返回的响应代码为 419
),代码如下:
@ExceptionHandler(Exception.class)
public Object handleException (Exception e, HttpServletRequest req) {
Result result = new Result();
result.setResultCode(500);
//区分是否为自定义异常
if (e instanceof NewBeeMallException) {
result.setMessage(e.getMessage());
//判断商城用户是否未正常登录,未正常登录返回特定的响应代码 416 (管理员用户未正常登录返回的响应代码为 419)
if (e.getMessage().equals(ServiceResultEnum.NOT_LOGIN_ERROR.getResult()) || e.getMessage().equals(ServiceResultEnum.TOKEN_EXPIRE_ERROR.getResult())) {
result.setResultCode(416);
} else {
e.printStackTrace();
result.setMessage("未知异常,请查看控制台日志并检查配置文件。");
}
}
return result;
}
此时的 newbee-mall-cloud-shop-cart-service
模块中没有业务代码,目录结构如图 7-1 所示。

这里并未涉及具体的业务代码,主要介绍购物车微服务的模块功能和表结构设计,以及在项目中完成购物车微服务的初始化构建,后续关于购物车微服务改造的实战章节都是基于当前项目来完成的。读者可以根据这些代码自己动手完成微服务编码,如获得这份代码后,以此为基础,自行完成购物车微服务模块所有代码的功能。如果自己实现耗费时间,也可以按照笔者给出的步骤完成服务化拆分。