位置: 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工作过程

  • 小爱同学怎么唤醒(小爱同学怎么唤醒手机)

    小爱同学怎么唤醒(小爱同学怎么唤醒手机)

  • 腾讯PacewearS8手环怎么绑定手机(腾讯手机pro)

    腾讯PacewearS8手环怎么绑定手机(腾讯手机pro)

  • iphone怎么截屏(iphone6怎么截屏)

    iphone怎么截屏(iphone6怎么截屏)

  • qq音乐怎么取消dj模式(QQ音乐怎么取消到期续费)

    qq音乐怎么取消dj模式(QQ音乐怎么取消到期续费)

  • 华为畅玩9a什么时候上市的(华为畅玩9a什么处理器)

    华为畅玩9a什么时候上市的(华为畅玩9a什么处理器)

  • 拼多多直播怎么放录好的视频(拼多多直播怎么上链接)

    拼多多直播怎么放录好的视频(拼多多直播怎么上链接)

  • 微信黑名单是什么意思(微信黑名单是什么样子的)

    微信黑名单是什么意思(微信黑名单是什么样子的)

  • 拼多多闪电退货钱先退吗(拼多多闪电退货有运费险吗)

    拼多多闪电退货钱先退吗(拼多多闪电退货有运费险吗)

  • amd3600配什么主板(amd3600配什么主板和内存)

    amd3600配什么主板(amd3600配什么主板和内存)

  • 定位服务是什么意思(手机定位服务是什么)

    定位服务是什么意思(手机定位服务是什么)

  • 苹果6苹果11系列充电器一样吗(苹果6和苹果11区别)

    苹果6苹果11系列充电器一样吗(苹果6和苹果11区别)

  • 屏幕漏液是因为什么(屏幕漏液为什么)

    屏幕漏液是因为什么(屏幕漏液为什么)

  • 摄像头三根线怎么接(摄像头三根线怎么用)

    摄像头三根线怎么接(摄像头三根线怎么用)

  • 手机为什么充的都是虚电(手机为什么充的慢了)

    手机为什么充的都是虚电(手机为什么充的慢了)

  • 怎么把手机恢复到刚买的时候(怎么把手机恢复到一天前)

    怎么把手机恢复到刚买的时候(怎么把手机恢复到一天前)

  • opporeno z怎么关机(opporenoz怎么关闭语音播报)

    opporeno z怎么关机(opporenoz怎么关闭语音播报)

  • 手动目录不够用怎么添加(手动目录可以增加)

    手动目录不够用怎么添加(手动目录可以增加)

  • 菜鸟裹裹关联是双方能看到吗(菜鸟裹裹关联是相互的吗)

    菜鸟裹裹关联是双方能看到吗(菜鸟裹裹关联是相互的吗)

  • cad十字中心线快捷键(2014cad十字中心线快捷键)

    cad十字中心线快捷键(2014cad十字中心线快捷键)

  • 苹果灰色的图标删不掉(苹果灰色app图标打不开)

    苹果灰色的图标删不掉(苹果灰色app图标打不开)

  • 怎么验证airpods真假(怎么验证airpodspro2是不是正品)

    怎么验证airpods真假(怎么验证airpodspro2是不是正品)

  • iaantmon.exe是什么进程 作用是什么 iaantmon进程查询(lnmgr.exe是什么)

    iaantmon.exe是什么进程 作用是什么 iaantmon进程查询(lnmgr.exe是什么)

  • 私人定制AI绘画——快速finetune stable diffusion教程(私人定制ai绘画下载)

    私人定制AI绘画——快速finetune stable diffusion教程(私人定制ai绘画下载)

  • 【C语言进阶】文本与二进制操作文件,优化通讯录。(c语音进阶)

    【C语言进阶】文本与二进制操作文件,优化通讯录。(c语音进阶)

  • 商贸企业出口进项税会计分录汇总
  • 实收资本变动额怎么算
  • 抵扣联 发票联
  • 营改增后纳税人可以使用的发票种类有
  • 印花税已经申报在哪里点交费
  • 去年开的专票今年可以作废吗
  • 预收账款转营业外收入账务处理
  • 稽查查补税款能缓缴
  • 工程结算与工程施工如何结转
  • 境外企业向境内提供国际运输服务核定征收的企业所得税
  • 建筑业确认主营业务收入
  • 金融企业发放贷款时发生的交易费用
  • 安装服务异地施工增值税在哪交
  • 注册资本金印花税减半征收
  • 企业汇算清缴前的票可以入账吗
  • 购进原材料影响营业利润吗
  • 捐款属于什么会计科目类别
  • 关联公司代付款
  • 应付职工薪酬的贷方表示什么
  • 应付利息和应计利息怎么区分
  • 取得进账发票没发票
  • 公司收到个人入股股金,然后又投资其他公司怎么做账
  • 购置资产是什么财务活动
  • php+mysql+apache
  • 代理记账费用计入什么会计科目
  • 结转销售原材料会计分录
  • 工资薪金所得申报流程
  • vue.config.js 中 devServer.proxy 配置说明,以及配置正确不生效问题
  • 奥尔梅克
  • token登录器
  • mac完全安装windows
  • react框架结构
  • ajax调用php接口
  • python雪花算法生成id
  • 销售费用凭证
  • 2021前端热门技术解读
  • Web 1.0、Web 2.0 和 Web 3.0 之间的比较
  • 社会团体收取的会费是否缴纳企业所得税
  • 未开票收入是否含税
  • 结转生产成本是负数怎么办
  • 销售鸡蛋免增值税吗
  • 普通发票两联都盖章吗
  • 公司缴纳社保应该怎么做账
  • 其他综合收益涉及到的业务
  • mysql四种常见日志
  • 第一季度利润表年初余额
  • 商品编码原则是指什么
  • 个体工商户能享受4050政策吗
  • 开增值税专用发票的好处
  • 人工成本的分类是
  • 企业主营业务利润是由什么构成的
  • 处置固定资产亏损,增值税所得税申报不一至情况说明
  • 房地产企业出售商铺交什么税
  • 合同约定合同期限自动顺延
  • 如何在科目余额表中查询给另一家公司付了多少钱
  • 零申报报表怎么填写
  • 稀释股权违法吗
  • 小规模纳税企业在应交增值税明细科目
  • 连锁店会计处理流程
  • 公司的日常费用支出能税前全部扣除吗?
  • 会计工作移交的时候需要有谁在场
  • mysql 临时表
  • win9系统
  • windows2003 64位注册码 序列号 激活码
  • win7如何创建新桌面
  • xp的开始菜单
  • centos文件权限详解
  • win10预览版和正式版区别
  • osx安装win10
  • 史上最详细的mrtg(Multi Router Traffic Grapher)设置说明
  • win10回收站设置
  • cocos2dx4.0教程
  • js获取url的html
  • jQuery插件封装时如要实现链式编程,需要
  • 代码整洁之道 高清pdf
  • 仿客齐集首页导航条DIV+CSS+JS [代码实例]
  • qq自动登出
  • js如何将输入的数存到数组中
  • javascript+
  • 港口的码头用地
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设