当前位置: 首页 > news >正文

北京网站建设 合一百度搜索首页

北京网站建设 合一,百度搜索首页,教育网站建设开发,建筑工程公司资质背景 服务端的接口一般有固定的返回格式&#xff0c;有数据、返回码和异常时错误信息。结构如下 Data public class BaseResponse<T> {private String code;private String message;private T data;public boolean isSuccess() {return "SUCCESS".equals(cod…

背景

服务端的接口一般有固定的返回格式,有数据、返回码和异常时错误信息。结构如下

@Data
public class BaseResponse<T> {private String code;private String message;private T data;public boolean isSuccess() {return "SUCCESS".equals(code);}
}

正常情况下我们只关注里面的data字段。不做任何处理情况下,需要将BaseResponse类型作为Feign Client方法的返回值,然后在调用Feign的业务代码处手动调用getData()方法来获取数据。这种重复的代码可以抽出来统一处理(请求数据也类似)。

解决方案

使用自定义Decoder来统一处理,重写Object decode(Response response, Type type)方法,其中Response 就是被调用接口返回的响应,Type就是Feign Client方法的返回值,它的实际类型有四种基本情况(其他都是这四种的排列组合),一种是不带泛型的类,一种带固定泛型的类,一种是不固定的T类型的泛型,最后一种是带?的分别如下
不带泛型
带泛型
在这里插入图片描述
在这里插入图片描述

本文只讨论前面两种类型,后面两种类型实际传到Decode中是没法知道实际类型的,除非通过某种方法把返回的实际类型传到Decode中(比如ThreadLocal、方法参数、请求头等等),或者泛型是有上界的,如<T ? extends UpUser>,那么可以通过typegetBounds()方法获取到上界类型,进行序列化。否则无法确定确定类型的,进行反序列化。

现在就是要将Response中的返回值转换成BaseResponse类型,而且是包括BaseResponse里面T这个泛型的,如果T中还带了泛型,不论嵌套几层都需要转换好,这样调用地方可以直接使用。我使用的序列化工具是Gson(ObjectMapper也是类似的)。

带泛型的转换其实是有现有的方法可以直接转的,但是这里有点难处理的是,将BaseResponse类型和参数中的Type合并成一个,作为参数传到GsonfromJson方法中,查看Type类的实现类,发现有一个ParameterizedType接口,这个就是描述了对象的参数类型。每个方法说明如下

public interface ParameterizedType extends Type {/*** 返回里面的泛型,比如List<String>, 那么这个方法返回String,如果是Map<String, Integer>那么这个方法返回{String, Integer}的数组* @since 1.5*/Type[] getActualTypeArguments();/*** 返回当前这个类的类型,比如List<String>, 那么这个方法返回List,如果是Map<String, Integer>那么这个方法返回Map*/Type getRawType();/*** 如果是内部类的情况,这个方法返回的是最外层的类,也就是封闭类,比如O<T>.I<S>这种类型,返回的是O<T>*/Type getOwnerType();
}

要注意一点,Class对象也是实现了Type接口的。

ParameterizedType接口解决了参数合并的问题,自定一个参数类型类,实现这三个方法

import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;public class MyParameterizedType implements ParameterizedType {private Type type;/*** 将Feign Client方法的返回值注入,只要两种类型,一种是ParameterizedTypeImpl,另一种是具体的Class对象*/public MyParameterizedType(Type type) {this.type = type;}/*** 属性Type就是BaseResponse的泛型类型,直接返回type就可以*/@Overridepublic Type[] getActualTypeArguments() {Type[] types = new Type[1];types[0] = type;return types;}/*** 最外层的类型就是我们要与type合并的BaseResponse类型*/@Overridepublic Type getRawType() {return BaseResponse.class;}/*** 这个Owner一般没用到,如果type是个内部类静态类情况下,需要返回最外部的类型,这里直接调用Class对象获取封闭类的方法*/@Overridepublic Type getOwnerType() {if (type instanceof ParameterizedTypeImpl) {ParameterizedTypeImpl typeImpl = (ParameterizedTypeImpl) type; return typeImpl.getRawType().getEnclosingClass();}if (type instanceof Class) {return ((Class) type).getEnclosingClass();}return null;}
}

这样序列化问题就能解决了,现在只要编写Decoder类就可以了。

import com.google.gson.Gson;
import feign.FeignException;
import feign.Response;
import feign.codec.Decoder;import java.io.IOException;
import java.lang.reflect.Type;public class MyDecode implements Decoder {private Gson gson = new Gson();@Overridepublic Object decode(Response response, Type type) throws FeignException, IOException {MyParameterizedType myType = new MyParameterizedType(type);BaseResponse baseResponse = gson.fromJson(response.body().asReader(), myType);if (type instanceof BaseResponse) {return baseResponse;}if (baseResponse.isSuccess()) {return baseResponse.getData();}throw new RuntimeException("返回异常");}
}

这里加了一个BaseResponse判断,如果需要返回整个数据,比如根据BaseResponse的返回码做业务逻辑,就可以在Feign Client的方法返回值直接写带泛型的BaseResponse类型。也加了一个统一的校验,如果要获取数据,需要返回码是正常才行。

总结

这种写法优点就是一次性反序列化到位,后续使用根据泛型里面的类型直接使用,如果不进行泛型合并,只转成BaseResponse类型,如果data的类型是有很多泛型嵌套的,那么可能反序列化类型是有问题的,比如data的类型是List<User>,那么不指定详细的泛型类型,直接转成BaseResponse类型,那么data字段序列化结果会是List<Map<String, String>,没法直接使用的。

关于参数化合并问题,这种思路可以借鉴,运用到其他场景。还有像请求数据统一封装其实也是类似,自定义一个Encoder即可,请求就没有参数泛型的问题了。

http://www.mmbaike.com/news/36515.html

相关文章:

  • 网页设计模拟试题答案seo包括什么
  • 用凡科做的手机网站版怎样创建一个网站
  • wordpress文章加载慢6seo牛人
  • 免费咨询律师网自然搜索优化
  • 上海手机网站建设电话北京本地网络推广平台
  • 郑州大型网站建设电话上海广告公司
  • 邢台市政建设集团网站百度搜图入口
  • 珠江摩尔网站建设app推广拉新平台
  • 怎样做像绿色和平组织类似的网站定制网站多少钱
  • 小程序开发平台到底哪家好湖南关键词优化推荐
  • 青岛胶南市城乡建设局网站手机cpu性能增强软件
  • 网站开发 chrome gimp厦门网站综合优化贵吗
  • 做社交网站开发合肥网络公司seo建站
  • 360网站制作潍坊sem优化托管
  • 可以做请柬的网站网络营销产品
  • 百度小程序官网深圳优化网站
  • 有没有专业做淘宝网站谷歌seo
  • 南阳微网站友情链接交换平台免费
  • 网站建设空间创建app平台
  • 工程建设动态管理网站一个品牌的策划方案
  • 个人网站策划书怎么做怎样利用互联网进行网络推广
  • 西安市建网站找哪家app宣传推广方案
  • 网站建设首页西安seo关键词推广
  • 营销型企业网站百度推广退款投诉
  • 武汉做网站云优化科技搜外友链平台
  • 怎么制作一个最简单的网站app营销推广方案
  • 京东的网站建设介绍大连网站建设
  • 做邀请函好的网站北京seo排名公司
  • 网站实名制 怎么做陕西seo优化
  • 阿里巴巴国际站网页设计教程人工智能培训机构排名