通用Java REST端点如何校验传入类型参数与对象实际类型是否一致
解决方案
前提说明
Java中Object.getClass()是native实现,返回值永远是实例的实际运行时类型,不会返回泛型声明的父类类型。你遇到的拿不到子类类型的问题,90%以上是因为REST接口的JSON反序列化框架(如Jackson、Gson)没有配置多态反序列化规则,框架无法识别子类映射关系,直接将入参反序列成了父类IdBaseClass的实例。
简单类型校验实现
以下代码可直接在createItemWithId方法中复用,适合初学者快速落地:
public Response createItemWithId(IdType idType, IdBaseDto<IdBaseClass> idDto) { // 取当前id对应的期望类型 Class<? extends IdBaseClass> expectedType = idType.getIdClass(); // 取实际接收的配置实例 IdBaseClass actualConfig = idDto.getConfig(); // 校验逻辑二选一即可 // 方案1:兼容继承场景,只要是期望类型的子类/实现类就通过校验 if (!expectedType.isInstance(actualConfig)) { return Response.status(Response.Status.BAD_REQUEST) .entity("参数类型不匹配,期望类型:" + expectedType.getSimpleName()) .build(); } // 方案2:严格匹配类型,必须和期望类型完全一致才通过 // if (!expectedType.equals(actualConfig.getClass())) { // return Response.status(Response.Status.BAD_REQUEST) // .entity("参数类型不匹配,期望类型:" + expectedType.getSimpleName()) // .build(); // } // 后续业务逻辑 }
反序列化配置(如果校验一直失败需要做)
如果运行后一直提示类型不匹配,说明确实是反序列化的问题,以常用的Jackson框架为例,只需给父类IdBaseClass加上多态注解即可:
// 配置多态识别规则,通过json中的idType字段判断映射到哪个子类 @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "idType") @JsonSubTypes({ @JsonSubTypes.Type(value = SAMPLE_ONE.class, name = "FIRST"), @JsonSubTypes.Type(value = SAMPLE_TWO.class, name = "SECOND"), @JsonSubTypes.Type(value = SAMPLE_THREE.class, name = "THIRD") }) public abstract class IdBaseClass { // 原有类逻辑不变 }
配置完成后,客户端请求时只需在config对应的JSON结构中新增一个idType字段,取值和路径参数中的id枚举值一致即可,框架会自动将JSON反序列为对应的子类实例,后续的类型校验就可以正常生效。
内容的提问来源于stack exchange,提问作者SandyTheTerribleCoder
相关产品推荐
相关产品推荐

