位置: IT常识 - 正文

Java后端通用接口设计(java后端代码例子)

编辑:rootadmin
Java后端通用接口设计 1、接口的响应要明确表示接口的处理结果

推荐整理分享Java后端通用接口设计(java后端代码例子),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:java后端接口开发详细教程,java后端接口怎么调用接口,java后端接口怎么写,java后端数据接口,java后端接口设计规范,java后端接口设计规范,java后端数据接口,java后端数据接口,内容如对您有帮助,希望把文章链接给更多的朋友!

为了将接口设计得更合理,我们需要考虑如下两个原则:

对外隐藏内部实现。即服务A调用服务B,如果服务B异常,但是我们不要直接把服务B的状态码、错误描述直接暴露给用户;

设计接口结构时,明确每个字段的含义,以及客户端的处理方式。

比如下面这个是我们设计的接口的响应:

@Datapublic class APIResponse<T> { private boolean success; private T data; private int code; private String message;}

接口的设计逻辑:

如果出现非 200 的 HTTP 响应状态码,就代表请求没有到服务,可能是网络出问题、网络超时,或者网络配置的问题。这时,肯定无法拿到服务端的响应体,客户端可以给予友好提示,比如让用户重试,不需要继续解析响应结构体。

如果 HTTP 响应码是 200,解析响应体查看 success,为 false 代表下单请求处理失败,可能是因为服务参数验证错误,也可能是因为服务操作失败。这时,根据服务定义的错误码表和 code,做不同处理。比如友好提示,或是让用户重新填写相关信息,其中友好提示的文字内容可以从 message 中获取。

success 为 true 的情况下,才需要继续解析响应体中的 data 结构体。data 结构体代表了业务数据。

1.1、通过ResponseBodyAdvice完成自动包装响应体Java后端通用接口设计(java后端代码例子)

为了代码会更简洁,我们的业务逻辑中可以通过ResponseBodyAdvice完成响应体的包装。

@RestControllerAdvice@Slf4jpublic class APIResponseAdvice implements ResponseBodyAdvice<Object> { //自动处理APIException,包装为APIResponse @ExceptionHandler(APIException.class) public APIResponse handleApiException(HttpServletRequest request, APIException ex) { log.error("process url {} failed", request.getRequestURL().toString(), ex); APIResponse apiResponse = new APIResponse(); apiResponse.setSuccess(false); apiResponse.setCode(ex.getErrorCode()); apiResponse.setMessage(ex.getErrorMessage()); return apiResponse; } //仅当方法或类没有标记@NoAPIResponse才自动包装 @Override public boolean supports(MethodParameter returnType, Class converterType) { return returnType.getParameterType() != APIResponse.class && AnnotationUtils.findAnnotation(returnType.getMethod(), NoAPIResponse.class) == null && AnnotationUtils.findAnnotation(returnType.getDeclaringClass(), NoAPIResponse.class) == null; } //自动包装外层APIResposne响应 @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { APIResponse apiResponse = new APIResponse(); apiResponse.setSuccess(true); apiResponse.setMessage("OK"); apiResponse.setCode(2000); apiResponse.setData(body); return apiResponse; }}

实现了 @NoAPIResponse 自定义注解。如果某些 @RestController 的接口不希望实现自动包装的话,可以标记这个注解:

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface NoAPIResponse {}

在 ResponseBodyAdvice 的 support 方法中,我们排除了标记有这个注解的方法或类的自动响应体包装。比如,对于刚才我们实现的测试客户端 client 方法不需要包装为 APIResponse,就可以标记上这个注解:

@GetMapping("client")@NoAPIResponsepublic String client(@RequestParam(value = "error", defaultValue = "0") int error){}

这样我们在代码中,就统一了响应体的处理,不用担心有些程序员别出心裁自己搞一套。

2、要考虑接口变迁的版本控制策略

接口不可能一成不变,需要根据业务需求不断增加内部逻辑。如果做大的功能调整或重构,涉及参数定义的变化或是参数废弃,导致接口无法向前兼容,这时接口就需要有版本的概念。在考虑接口版本策略设计时,我们需要注意的是,最好一开始就明确版本策略,并考虑在整个服务端统一版本策略。

第一,版本策略最好一开始就考虑。第二,版本实现方式要统一。

为了实现上面的目的,我们可以通过注解的方式为接口增加基于 URL 的版本号:首先,创建一个注解来定义接口的版本。@APIVersion 自定义注解可以应用于方法或 Controller 上:

@Target({ElementType.METHOD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)public @interface APIVersion { String[] value();}

然后,定义一个 APIVersionHandlerMapping 类继承 RequestMappingHandlerMapping。

public class APIVersionHandlerMapping extends RequestMappingHandlerMapping { @Override protected boolean isHandler(Class<?> beanType) { return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class); } @Override protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) { Class<?> controllerClass = method.getDeclaringClass(); //类上的APIVersion注解 APIVersion apiVersion = AnnotationUtils.findAnnotation(controllerClass, APIVersion.class); //方法上的APIVersion注解 APIVersion methodAnnotation = AnnotationUtils.findAnnotation(method, APIVersion.class); //以方法上的注解优先 if (methodAnnotation != null) { apiVersion = methodAnnotation; } String[] urlPatterns = apiVersion == null ? new String[0] : apiVersion.value(); PatternsRequestCondition apiPattern = new PatternsRequestCondition(urlPatterns); PatternsRequestCondition oldPattern = mapping.getPatternsCondition(); PatternsRequestCondition updatedFinalPattern = apiPattern.combine(oldPattern); //重新构建RequestMappingInfo mapping = new RequestMappingInfo(mapping.getName(), updatedFinalPattern, mapping.getMethodsCondition(), mapping.getParamsCondition(), mapping.getHeadersCondition(), mapping.getConsumesCondition(), mapping.getProducesCondition(), mapping.getCustomCondition()); super.registerHandlerMethod(handler, method, mapping); }}

RequestMappingHandlerMapping 的作用,是根据类或方法上的 @RequestMapping 来生成 RequestMappingInfo 的实例。我们覆盖 registerHandlerMethod 方法的实现,从 @APIVersion 自定义注解中读取版本信息,拼接上原有的、不带版本号的 URL Pattern,构成新的 RequestMappingInfo,来通过注解的方式为接口增加基于 URL 的版本号。

最后,要通过实现 WebMvcRegistrations 接口,来生效自定义的 APIVersionHandlerMapping

@SpringBootApplicationpublic class CommonMistakesApplication implements WebMvcRegistrations { @Override public RequestMappingHandlerMapping getRequestMappingHandlerMapping() { return new APIVersionHandlerMapping(); }}

这样,就实现了在 Controller 上或接口方法上通过注解,来实现以统一的 Pattern 进行版本号控制,使用时:

@GetMapping(value = "/api/user")@APIVersion("v4")public int right4() { return 4;}

访问url为 http://localhost:8080/v4/api/user

使用框架来明确 API 版本的指定策略,不仅实现了标准化,更实现了强制的 API 版本控制。假如我们的接口强制要求必须要有版本号,可以改动APIVersionHandlerMapping代码,在获取不到@APIVersion注解时,就给予报错提示。

本文链接地址:https://www.jiuchutong.com/zhishi/300049.html 转载请保留说明!

上一篇:为什么我会选择 AI-TestOps 让测试更智能(为什么我会选择那个对我一般的男人结婚)

下一篇:HTTP加密/HTTPS工作过程

  • oppo系统分身隐藏了怎么找(oppo系统分身隐藏了,在怎么找出来啊)

    oppo系统分身隐藏了怎么找(oppo系统分身隐藏了,在怎么找出来啊)

  • iqooneo3有红外线功能吗(iqooneo3有红外线遥控功能吗)

    iqooneo3有红外线功能吗(iqooneo3有红外线遥控功能吗)

  • 华为手机怎么指纹开锁(华为手机怎么指纹设置)

    华为手机怎么指纹开锁(华为手机怎么指纹设置)

  • 微信怎么打出满屏爱心(微信怎么打出满屏抱抱)

    微信怎么打出满屏爱心(微信怎么打出满屏抱抱)

  • 一台笔记本电脑多重(一台笔记本电脑屏幕的面积大约是4)

    一台笔记本电脑多重(一台笔记本电脑屏幕的面积大约是4)

  • 儿童电话手表怎么调整时间(儿童电话手表怎么充电)

    儿童电话手表怎么调整时间(儿童电话手表怎么充电)

  • imessage和短信怎么切换

    imessage和短信怎么切换

  • 表格有加有减怎么求和(表格有加有减怎么自动求和)

    表格有加有减怎么求和(表格有加有减怎么自动求和)

  • 向下填充快捷键excel(EXCEL表格向下填充快捷键)

    向下填充快捷键excel(EXCEL表格向下填充快捷键)

  • 手机摔碎了里面的照片还可以恢复吗(手机摔碎了里面的东西怎么办)

    手机摔碎了里面的照片还可以恢复吗(手机摔碎了里面的东西怎么办)

  • 华为Nova5健康时间怎么解除(华为nova2s健康使用手机)

    华为Nova5健康时间怎么解除(华为nova2s健康使用手机)

  • 闲鱼上的直拍什么意思(闲鱼的直拍和直出有啥区别)

    闲鱼上的直拍什么意思(闲鱼的直拍和直出有啥区别)

  • 苹果电脑返回键是哪个(苹果电脑返回键怎么弄)

    苹果电脑返回键是哪个(苹果电脑返回键怎么弄)

  • 苹果6s的尺寸和6的尺寸是一样的吗(苹果手机6s尺寸分别是什么)

    苹果6s的尺寸和6的尺寸是一样的吗(苹果手机6s尺寸分别是什么)

  • ghz指的是计算机的(计算机gc是什么)

    ghz指的是计算机的(计算机gc是什么)

  • 黄钻和svip会员有什么区别(黄钻和svip会员一样吗)

    黄钻和svip会员有什么区别(黄钻和svip会员一样吗)

  • 苹果手机上的通讯录怎么弄到另一个手机上(苹果手机上的通讯录怎么删除)

    苹果手机上的通讯录怎么弄到另一个手机上(苹果手机上的通讯录怎么删除)

  • 淘宝ld指的是什么意思(淘宝ld号是什么意思)

    淘宝ld指的是什么意思(淘宝ld号是什么意思)

  • 中国移动微信公众号怎么关注(中国移动微信公众号)

    中国移动微信公众号怎么关注(中国移动微信公众号)

  • 手机如何使用移动硬盘(手机如何使用移动数据)

    手机如何使用移动硬盘(手机如何使用移动数据)

  • 小米手机wifi已连接,但无法访问互联网(小米手机wifi已保存已停用怎么回事)

    小米手机wifi已连接,但无法访问互联网(小米手机wifi已保存已停用怎么回事)

  • 在win7系统中怎么解决桌面右下角时间消失?(win7系统中怎样没有智能卡这一选项)

    在win7系统中怎么解决桌面右下角时间消失?(win7系统中怎样没有智能卡这一选项)

  • 职工薪酬纳税调减的情况
  • 税后经营净利润怎么求
  • 企业所得税汇算清缴账务处理
  • 项目差旅费能计入项目费用吗
  • 利润表的营业成本包括哪些
  • 甲供材能否开具增值税专用发票
  • 发出商品是用进货吗
  • 资产负债表试算平衡表是什么
  • 企业为什么要进行环境分析
  • 抵债物品销售
  • 跨区域缴纳社保
  • 医院外聘专家费用由科室承担吗
  • 文化用品利润怎么样
  • 出口退免税收汇相关业务
  • 查企业有记录吗
  • 购买商品用于赠送
  • 预付加油卡发票可以报销吗
  • 生产成本包括哪三类
  • 民非提供服务收到的现金怎么算
  • 出差补贴算工资薪金吗
  • 股派发红利是涨还是跌
  • 销售补差是怎么算的
  • 本年利润和利润总额的关系
  • 贷款的钱转账了怎么办
  • 公司员工意外险怎么买
  • 以旧换新的概念
  • codeigniter 教程
  • slam方法
  • 出口流程步骤
  • 免抵退税额好难懂
  • 物业公司购买空调合法吗
  • 如何快速搭建前端界面
  • Chatgpt私有化部署(全流程)
  • php如何定义二维数组
  • thinkphp v5.0.24
  • php红包源码
  • php framework框架
  • 房产置换怎么做账务处理
  • Python列表元素的删除
  • 模具固定资产如何核算
  • 利息收入可以冲减开发成本的法律依据
  • 房地产企业的开发成本和开发费用有什么区
  • etcd4
  • 织梦系统
  • 保险中介手续费规定最新
  • SQL Server 2008 r2 完全卸载方法分享
  • 个税申报哪些可以减免
  • 人力资源行业税收优惠
  • 企业分期收款销售商品,即商品已经交付
  • 养老保险和工伤失业保险不在一个时间
  • 商场活动经费预算
  • 计量差错引起的原材料盘亏
  • 净资产收益率与什么指标有关
  • 经纪代理包括什么
  • 其他债权投资发生减值会影响所有者权益总额吗
  • 餐饮服务属于什么职业
  • 《新会计准则》
  • 资产状况信息公示还是不公示
  • 摊余成本计入哪里
  • sql server复制功能
  • sql批量导出数据
  • foxmail反应慢的原因
  • bios如何设置关机键开机
  • 如何把itunes的音乐导入ipod
  • linux滚动更新是什么
  • linux怎么恢复数据
  • 微软发布Win10优化工具
  • windows7如何启动任务管理器
  • VS2012中C++,#include无法打开源文件
  • 铁嘴大师
  • activity间数据传递
  • ssh -keygen
  • 使用Raygun对Node.js应用进行错误处理的方法
  • js实现商品分类
  • js easyui
  • RadioGroup+Fragment实现底部菜单栏
  • jQuery中通过ajax调用webservice传递数组参数的问题实例详解
  • 个人的稿酬所得采用什么税率
  • 巾帼文明岗主题内容
  • 云南省国税发票查询真伪查询
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设