简介:
在微服务开发过程中,我们经常会使用openfeign来进行服务调用。然而,有时候当我们调用服务时却遇到了一个令人困惑的错误,即"Type definition error: [simple type, class XXX]"。这个问题导致了服务调用的返回结果无法被正确序列化,给开发和调试带来了不便。本篇博客将详细探讨这个问题的原因以及解决方案。
问题背景
当OpenFeign调用远程服务并接收返回结果时,它会尝试将返回的数据序列化为本地对象。在这个过程中,如果OpenFeign无法正确地将JSON数据映射到目标类的实例,就会抛出“Type definition error”的异常。
以下是我们的代码示例,展示了在openfeign服务调用过程中出现异常的情况:
// 这是返回类
@Data
public class BaseResponse<T> implements Serializable {
private int code;
private T data;
private String message;
public BaseResponse(int code, T data, String message) {
this.code = code;
this.data = data;
this.message = message;
}
public BaseResponse(int code, T data) {
this(code, data, "");
}
public BaseResponse(int code, String message) {
this(code, null, message);
}
}
这是服务A的代码
@Slf4j
@RestController
@RequiredArgsConstructor
public class PayController implements PayFacade {
private final TestUserFeign testUserFeign;
@Override
public BaseResponse<Boolean> testPay(Long uid, HttpServletRequest request) {
try{
BaseResponse baseResponse = testUserFeign.consumeAmount(uid, 100L);
if(baseResponse.getCode() != 0){
return ResultUtils.error(baseResponse.getCode(), baseResponse.getMessage());
}
}catch (Exception e){
return ResultUtils.error(500, e.getMessage());
}
return ResultUtils.success("成功");
}
}
这是服务B的代码
@RestController
@RequiredArgsConstructor
@Slf4j
public class UserController implements UserFacade {
private final UserService userService;
@Override
public BaseResponse consumeAmount(Long uid, Long amount) {
if (StringUtils.isAnyBlank(uid.toString(), amount.toString())) {
throw new RuntimeException("参数不能为空");
}
userService.consumeAmount(uid, amount);
return ResultUtils.success("成功");
}
}
在上述代码示例中,我们期望通过调用B服务的的consumeAmount()方法获取B服务返回的数据,然后在A服务中处理返回结果。然而,当我们尝试调用getData()方法时,却遇到了"Type definition error: [simple type, class XXX]"的异常,导致无法正常处理返回结果。
问题原因
直接说原因,这个问题通常出现在对象序列化的过程中。openfeign在将服务端返回的数据序列化成对象时,要求对象必须有无参构造器。如果对象没有提供无参构造器,就会导致序列化失败,进而出现"Type definition error: [simple type, class XXX]"的异常。
解决方案
要解决这个问题,我们需要为对象提供一个无参构造器。无参构造器是Java对象序列化和反序列化的基础,它允许对象在没有参数的情况下被实例化,从而顺利进行序列化操作。通过注解添加@NoArgsConstructor
@NoArgsConstructor
@Data
public class BaseResponse<T> implements Serializable {
//
}
总结
OpenFeign服务调用返回结果报错,特别是涉及“Type definition error”的问题,通常与目标类的序列化有关。确保目标类具有公开的无参构造器,并检查相关注解和配置,通常可以解决这类问题。