前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java Spring 使用AOP代理方法 类型转换异常java.lang.ClassCastException 原因及解决办法

Java Spring 使用AOP代理方法 类型转换异常java.lang.ClassCastException 原因及解决办法

作者头像
heasy3
发布2021-01-29 10:25:14
9440
发布2021-01-29 10:25:14
举报

有一段代码 有时会出现类型转换异常 很诡异 排查原因发现是spring aop造成的。

项目中我使用了aop进行自定义权限,若权限不通过 返回固定的ResponseVo 对应字段为:

代码语言:javascript
复制
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResponseVo<T> {

    @JsonProperty("response_code")
    private Integer responseCode;
    @JsonProperty("verbose_msg")
    private String verboseMsg;

    private T data;
}

为了开发方便 不需要每个controller都写一个ResponseVo的构建 使用了ResponseBodyAdvice来帮助构建,之前的文章里写过

说白了就说Controller方法只需要返回一个任意对象 由spring将其封装到ResponseVo的data字段中。

下面的是使用ResponseBodyAdvice的效果 上面是正常写法

这个接口比较简单可能没太大对比度

但是在鉴权的aop中 若权限通过则调用方法 返回方法结果

若不通过 则返回内容为:

是一个ResponseVo

报错内容为 不能把ResponseVo转为BaseInfoVo,且堆栈中看不出任何自己写的代码引用。

测试时发现 有权限时 这个接口不报错,没有权限时就会报类型转换异常。找到这个规律 就很容易知道问题出在哪了。

原因是: spring在代理这个方法时 知道这个方法声明的返回值为BaseInfoVo,但当权限不通过时 我通过切面将其返回值改为了ResponseVo,但R不能转为B 就会报类型转换异常。

解决办法有2种:

1 Controller的返回类型统一为ResponseVo,这样就没办法使用ResponseBodyAdvice了。

2 将方法的返回值声明为所有可能被返回类型的共同接口:1 Object 因为Object是所有类的父类 2或声明一个接口由R和Q分别实现 但这样做意义不大。 缺点是返回值都为Object的话 语义不明确

最终选用了方法1

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-01-25 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档