问题: 通过openfeign调用的接口, 响应的实体里面取出来的包装的data对象, 不能转换为指定对象, 抛异常unsupportedoperationexception 报错linkedmap不能转换为xxxxx
解决:响应实体, 增加泛型定义
不多说,上代码。
/**
* 操作消息结构定义
*
* @author zengyujie
*/
@Getter
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
public static String SUCCESS_CODE = "1";
public static String FAIL_CODE="500";
private String code;
private String msg;
private T data;
/**
* 初始化一个新创建的 Result 对象,使其表示一个空消息。
*/
public Result() {
}
/**
* 初始化一个新创建的 Result 对象
*
* @param code 状态码
* @param msg 返回内容
*/
public Result(String code, String msg) {
this.code=code;
this.msg=msg;
}
/**
* 初始化一个新创建的 Result 对象
*
* @param code 状态码
* @param msg 返回内容
* @param data 数据对象
*/
public Result(String code, String msg, T data) {
this.code=code;
this.msg=msg;
if (!Objects.isNull(data)) {
this.data=data;
}
}
public Result<T> setCode(String code) {
this.code = code;
return this;
}
public Result<T> setData(T data) {
this.data = data;
return this;
}
public Result<T> setMsg(String msg) {
this.msg = msg;
return this;
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static <T> Result<T> success() {
return new Result<>(SUCCESS_CODE,"操作成功");
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static <T> Result<T> success(T t) {
return new Result<>(SUCCESS_CODE,"操作成功",t);
}
/**
* 返回成功消息
*
* @return 成功消息
*/
public static <T> Result<T> success(String msg) {
return new Result<>(SUCCESS_CODE,msg);
}
/**
* 返回错误消息
*
* @return
*/
public static <T> Result<T> error() {
return Result.error("操作失败");
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @return 警告消息
*/
public static <T> Result<T> error(String msg) {
return Result.error(FAIL_CODE, msg);
}
/**
* 返回错误消息
*
* @param msg 返回内容
* @param data 数据对象
* @return 警告消息
*/
public static <T> Result<T> error(String msg, T data) {
return new Result<>(FAIL_CODE, msg, data);
}
/**
* 返回错误消息
*
* @param code 状态码
* @param msg 返回内容
* @return 警告消息
*/
public static <T> Result<T> error(String code, String msg) {
return new Result<>(code, msg, null);
}
}
通常, 我们用得最多的是:
/**
* 返回成功消息
*
* @return 成功消息
*/
public static <T> Result<T> success(T t) {
return new Result<>(SUCCESS_CODE,"操作成功",t);
}
对应controller的定义:
/**
* 分页查询
*
* @param ckCommQuery 筛选条件
* @param pageIndex 页面索引
* @param pageSize 页面条数
* @return 查询结果
*/
@ApiOperation("分页查询")
@RequestMapping("/list-page")
public Result<PageUtils<CkCommPushdw>> listPage(@RequestBody CkCommPushdw ckCommPushdw, @RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize){
return Result.success(ckCommPushdwService.queryPage( ckCommPushdw,pageIndex,pageSize));
}
对应的@FeignClient接口定义:
/**
* 分页查询
*
* @param CkCommPushdw 筛选条件
* @param pageIndex 页面索引
* @param pageSize 页面条数
* @return 查询结果
*/
@RequestMapping("xxxxxx/list-page")
Result<PageUtils<CkCommPushdw>> listPage(@RequestBody CkCommPushdw ckCommPushdw, @RequestParam("pageIndex") int pageIndex, @RequestParam("pageSize") int pageSize);
那么, 这样的话,我们在调用listPage这个函数的时候,渠道的result里面就可以愉快的直接用啦。
有的小伙伴们可能疑惑这个Result为什么跟其他开源框架的不一样,直接继承HashMap不好么? map是方便, 但是, 想过接口代码变更的时候漏改会是什么后果么? 直接用实体类的话,编译的时候是不是就能提前发现了呢 ?
上调用的代码:
public void getCommQueryResult(String dataDate){
CkCommPushdw ckCommPushdw = new CkCommPushdw();
ckCommPushdw.setState("2");
ckCommPushdw.setDataDate(dataDate);
//1. 看这里 调用了 ckCommClient 定义的 CkCommPushdw 的 listPage
Result<PageUtils<CkCommPushdw>> result = ckCommClient.listPage(ckCommPushdw,1,500);
if (Result.SUCCESS_CODE.equals(result.getCode() )){
//2. 看这里 如果查到数据
PageUtils<CkCommPushdw> pageUtils = result.getData();
//3. 看这里
List<CkCommPushdw> ckCommPushdws = pageUtils.getList();
//如果响应有记录
boolean updateResult = false;
if (ckCommPushdws.size()>=1){
//根据数据日期进行更新
updateResult = jwCxService.update(Wrappers
.<JwCx>update()
.lambda()
.set(JwCx::getState,"2")
//where date_date = ckCommPushdw.getDataDate() and state='1'
.eq(JwCx::getDataDate,ckCommPushdw.getDataDate())
.eq(JwCx::getState,"1")
);
log.("数据更新完成,更新结果为 {}", updateResult );
}else {
log.info("没查到有 {} 日期已完成的记录",ckCommPushdw.getDataDate());
}
}else {
log.info("额, 调用远程服务没反馈 {}", JSON.toJSONString(result));
}
}