spring mvc中不同服务调用类型(声明式(Feign)、基于模板(RestTemplate)、基于 SDK、消息队列、gRPC)对比详解

@RestControllerAdvice 和 @ControllerAdvice 对比详解


1. 基本概念
注解等效组合核心作用
@ControllerAdvice@Component + @RequestMapping(隐式)定义全局控制器增强类,处理跨控制器的异常、数据绑定或全局响应逻辑。
@RestControllerAdvice@ControllerAdvice + @ResponseBody继承 @ControllerAdvice,并默认将返回值序列化为 HTTP 响应体(如 JSON)。

2. 核心区别
对比维度@ControllerAdvice@RestControllerAdvice
返回值处理默认返回视图名称(需配合 @ResponseBody 才能序列化)直接返回数据对象,自动序列化为响应体(如 JSON)
适用场景传统 MVC 应用(如返回 HTML 视图或混合响应)RESTful API(需返回 JSON/XML 格式数据)
注解组合需手动添加 @ResponseBody 才能返回 JSON内置 @ResponseBody,无需额外声明
返回类型示例String(视图名称)、ModelAndViewResponseEntity, Map, 自定义 POJO

3. 代码示例对比
场景:全局异常处理

@ControllerAdvice 示例(返回视图名称)

@ControllerAdvice
public class GlobalViewExceptionHandler {@ExceptionHandler(IOException.class)public String handleIOException() {return "error/500"; // 返回视图名称(如 Thymeleaf 模板)}
}

@RestControllerAdvice 示例(返回 JSON)

@RestControllerAdvice
public class GlobalApiExceptionHandler {@ExceptionHandler(IOException.class)public ResponseEntity<ErrorDetails> handleIOException() {ErrorDetails error = new ErrorDetails(500, "Internal Server Error", null);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);}
}

4. 关键功能对比
功能@ControllerAdvice@RestControllerAdvice
异常处理支持,需手动定义返回类型(视图或 JSON)支持,直接返回 JSON 格式错误对象
数据绑定可通过 @InitBinder 统一配置绑定规则同样支持 @InitBinder,但返回值默认序列化
全局方法增强可通过 @ModelAttribute 注入公共数据同样支持,但返回数据自动序列化
响应体控制需显式使用 @ResponseBodyResponseEntity内置 @ResponseBody,无需额外声明

5. 配置与扩展
共同特性
  • 包级作用域:通过 basePackages 指定需要增强的控制器包:

    @ControllerAdvice(basePackages = "com.example.controllers")
    
  • 方法级过滤:通过 annotations 指定仅处理特定注解的控制器:

    @ControllerAdvice(annotations = RestController.class)
    
差异点
  • 响应体格式
    • @ControllerAdvice 需显式配置 @ResponseBodyResponseEntity 才能返回 JSON:

      @ControllerAdvice
      public class MixHandler {@ResponseBody // 显式声明返回 JSON@ExceptionHandler(IOException.class)public ErrorDetails handleIOException() { ... }
      }
      
    • @RestControllerAdvice 默认支持序列化:

      @RestControllerAdvice
      public class ApiHandler {@ExceptionHandler(IOException.class)public ErrorDetails handleIOException() { ... } // 自动序列化为 JSON
      }
      

6. 典型使用场景
场景推荐注解原因
传统 Web 应用(返回 HTML)@ControllerAdvice需返回视图名称(如 Thymeleaf 模板路径)。
RESTful API 异常处理@RestControllerAdvice直接返回结构化的 JSON 错误信息,无需额外配置 @ResponseBody
混合场景(需同时处理视图和 JSON)@ControllerAdvice需通过 @ResponseBody 区分返回类型,或使用 ResponseEntity 控制响应格式。

7. 总结表格
维度@ControllerAdvice@RestControllerAdvice
核心作用全局异常处理、数据绑定、视图增强专为 REST API 设计,返回 JSON 格式响应
返回值默认行为返回视图名称或需 @ResponseBody 显式声明直接返回数据对象,自动序列化为响应体
适用场景传统 MVC 应用、混合响应场景纯 REST API 开发(如 Spring Boot 微服务)
注解组合关系独立注解,需手动配置响应格式等效于 @ControllerAdvice + @ResponseBody

关键总结### 声明式服务调用与其他服务调用类型对比详解


1. 什么是声明式服务调用?

定义:通过注解或配置声明服务调用接口,无需手动编写底层网络请求代码,由框架自动生成代理实现。
核心特点

  • 声明式:通过注解(如 @FeignClient)或配置定义服务接口。
  • 自动代理:框架(如 Spring Cloud Feign)自动处理 HTTP 请求、序列化、负载均衡等。
  • 解耦:开发者只需关注业务逻辑,无需关心网络细节。

示例(Spring Cloud Feign):

@FeignClient(name = "service-provider") // 声明调用的服务名称
public interface ProductClient {@GetMapping("/products/{id}")Product getProduct(@PathVariable("id") String id);
}

2. 其他服务调用类型及对比

类型 1:基于模板的调用(如 RestTemplate/HttpClient)

定义:手动构造 HTTP 请求,通过模板工具(如 RestTemplateOkHttp)发送请求并处理响应。
特点

  • 灵活控制:可完全控制请求参数、超时、重试等。
  • 无侵入性:无需框架支持,纯 Java 实现。
  • 代码冗长:需手动处理异常、序列化等。

使用方法

// 使用 RestTemplate 调用服务
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<Product> response = restTemplate.getForEntity("http://service-provider/products/123",Product.class
);
Product product = response.getBody();

类型 2:基于 SDK 的调用

定义:通过第三方或自定义 SDK 封装服务调用逻辑,提供统一接口。
特点

  • 封装复杂逻辑:如 AWS SDK 封装了 S3、DynamoDB 的调用细节。
  • 依赖性强:需引入 SDK 依赖,版本需与服务端兼容。
  • 易用性高:开发者无需关心底层协议。

使用示例(AWS S3 SDK)

AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion("us-west-2").build();
S3Object object = s3Client.getObject("my-bucket", "key-name");

类型 3:基于消息队列的异步调用

定义:通过消息中间件(如 RabbitMQ、Kafka)发送异步消息,由消费者处理。
特点

  • 解耦:生产者与消费者无直接依赖。
  • 异步:支持高并发和最终一致性。
  • 需消息中间件:需维护消息队列基础设施。

使用示例(Spring Cloud Stream)

// 生产者发送消息
@Service
public class OrderService {@Autowiredprivate MessageChannel orderChannel;public void sendOrder(Order order) {orderChannel.send(MessageBuilder.withPayload(order).build());}
}// 消费者处理消息
@Service
public class OrderConsumer {@StreamListener("order-inbound")public void processOrder(Order order) {// 处理订单逻辑}
}

类型 4:基于 gRPC 的调用

定义:使用 gRPC 框架进行高性能的 RPC 调用,基于 Protocol Buffers 定义接口。
特点

  • 高性能:二进制协议,支持流式传输。
  • 强类型定义:通过 .proto 文件定义接口和数据结构。
  • 学习成本高:需掌握 gRPC 和 Protocol Buffers。

使用示例

// 定义 proto 文件
service ProductService {rpc GetProduct (ProductRequest) returns (ProductResponse) {}
}// 生成客户端代码
ProductServiceBlockingStub stub = ProductGrpc.newBlockingStub(channel);
ProductResponse response = stub.getProduct(request);

类型 5:基于 HTTP 客户端(如 OkHttp)的直接调用

定义:直接使用低层 HTTP 客户端(如 OkHttp、URLConnection)发送请求。
特点

  • 完全控制:可配置超时、连接池等。
  • 无需框架依赖:纯 Java 实现。
  • 代码复杂度高:需手动处理序列化、异常等。

示例(OkHttp)

OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://service-provider/products/123").build();
Response response = client.newCall(request).execute();
String responseBody = response.body().string();

3. 对比总结表格
类型声明式基于模板基于 SDK消息队列gRPC
核心特点注解声明,框架代理手动构造请求封装第三方接口异步解耦高性能 RPC
代码复杂度简单(无需手动请求)中等(需处理细节)简单(依赖 SDK)中等(需消息配置)高(需 proto 定义)
适用场景微服务内同步调用需灵活控制的场景第三方服务调用解耦异步场景高性能同步 RPC
框架依赖Spring Cloud无(需 RestTemplate)SDK 依赖RabbitMQ/KafkagRPC 库
是否同步/异步同步(可配置异步)同步/异步同步/异步异步同步/异步流
典型工具FeignRestTemplate,OkHttpAWS SDKSpring Cloud StreamgRPC

4. 选择依据
需求场景推荐类型原因
快速集成微服务同步调用声明式(Feign)零代码实现负载均衡、熔断,开发效率高。
需灵活控制 HTTP 请求细节基于模板(RestTemplate)直接控制超时、重试等参数。
调用第三方服务(如 AWS)基于 SDK使用官方 SDK 确保兼容性和易用性。
解耦服务间依赖消息队列异步通信,高并发场景下避免阻塞。
高性能低延迟的 RPC 调用gRPC二进制协议和流式传输适合高频、低延迟场景。

5. 关键总结
  1. 声明式服务调用(如 Feign):开发效率最高,适合微服务内同步调用。
  2. 基于模板/SDK灵活性与易用性平衡,适合复杂或第三方服务调用。
  3. 消息队列解耦与异步的首选方案。
  4. gRPC高性能场景的最优选择,需权衡学习成本。

根据项目需求(如性能、耦合度、开发效率),选择合适的调用方式,或混合使用多种类型以满足不同场景。

  1. 选择原则
    • REST API:优先使用 @RestControllerAdvice,简化 JSON 响应处理。
    • 传统 MVC:使用 @ControllerAdvice,灵活控制视图或 JSON 响应(需配合 @ResponseBody)。
  2. 注意事项
    • @ControllerAdvice 若需返回 JSON,必须显式添加 @ResponseBody 或使用 ResponseEntity
    • @RestControllerAdvice 内置 @ResponseBody,无需额外声明,适合统一 API 响应格式。
  3. 最佳实践
    • 对于纯 API 项目,用 @RestControllerAdvice 集中处理异常和响应。
    • 在混合项目中,通过 basePackages 区分不同场景的增强类。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/900887.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CVE-2025-29927 Next.js 中间件鉴权绕过漏洞

Next.js Next.js 是一个基于 React 的现代 Web 开发框架&#xff0c;用来构建高性能、可扩展的 Web 应用和网站。 CVE-2025-29927 Next.js 中间件鉴权绕过漏洞 CVE-2025-29927是Next.js框架中的一个授权绕过漏洞&#xff0c;允许攻击者通过特制的HTTP请求绕过在中间件中执行…

WP最主题专业的wordpress主题开发

WP最主题&#xff08;wpzui.com&#xff09; WP最主题是一个提供高品质WordPress主题的平台。它注重主题的设计和功能&#xff0c;旨在为用户提供美观且实用的主题选择。其主题通常具有良好的用户体验、丰富的自定义选项以及优化的性能&#xff0c;能够满足不同类型的网站搭建…

玩转代理 IP :实战爬虫案例

在现代互联网环境下&#xff0c;爬虫不仅是数据获取的利器&#xff0c;也成为应对网站反爬机制的技术博弈。而在这场博弈中&#xff0c;"代理 IP" 是核心武器之一。本文将以高匿名的代理ip为核心&#xff0c;结合 Python 实战、代理策略设计、高匿技巧与反封锁优化&a…

Vue 3 中 ref 与 reactive 的对比

Vue 3 中 ref 与 reactive 的对比 Vue 3 中 ref 与 reactive 的对比一、定义和基本使用refreactive 二、响应式原理refreactive 三、适用场景refreactive 四、注意事项refreactive Vue 3 中 ref 与 reactive 的对比 在 Vue 3 中&#xff0c;ref 和 reactive 都是用于创建响应式…

《Vue.js组件化开发实战:从安全纵深到性能跃迁》

开篇&#xff1a;组件化开发的工业革命 当全球500强企业的核心业务系统在12.12大促中经受每秒38万次请求冲击时&#xff0c;我们突然意识到&#xff1a;现代前端组件已不再是简单的UI积木&#xff0c;而是承载业务逻辑、安全防护、性能优化的纳米级作战单元。本文将从军工级系统…

从0到1的Python接口自动化学习路线

Python 是一门非常适合初学者且功能强大的编程语言,它在接口自动化测试领域具有广泛应用。 以下是一份针对 Python 与接口自动化测试的详细学习路线,帮助你从零开始学习并逐步掌握相关知识。 第一阶段:Python基础 目标:掌握 Python 基本语法和编程能力。 一、学习内容 1.…

HDCP(五)

HDCP 2.2 测试用例设计详解 基于HDCP 2.2 CTS v1.1规范及协议核心机制&#xff0c;以下从正常流程与异常场景两大方向拆解测试用例设计要点&#xff0c;覆盖认证、密钥管理、拓扑验证等关键环节&#xff1a; 1. 正常流程测试 1.1 单设备认证 • 测试目标&#xff1a;验证源设…

国标GB28181协议EasyCVR视频融合平台:5G时代远程监控赋能通信基站安全管理

一、背景介绍 随着移动通信行业的迅速发展&#xff0c;无人值守的通信基站建设规模不断扩大。这些基站大多建于偏远地区&#xff0c;周边人迹罕至、交通不便&#xff0c;给日常的维护带来了极大挑战。其中&#xff0c;位于空旷地带的基站设备&#xff0c;如空调、蓄电池等&…

A2L文件解析

目录 1 摘要2 A2L文件介绍2.1 A2L文件作用2.2 A2L文件格式详解2.2.1 A2L文件基本结构2.2.2 关键元素与声明2.2.3 完整A2L文件示例 3 总结 1 摘要 A2L文件&#xff08;也称为ASAP2文件&#xff09;是ECU开发的核心接口文件&#xff0c;用于标定、测量和诊断的关键配置文件&…

光学工程考研调剂推荐

一、调剂院校推荐 1. 华南农业大学 • 调剂分数参考&#xff1a;光学工程调剂生分数通常在300分左右&#xff0c;过国家线即可尝试。例如&#xff0c;2023年有297分考生成功调剂至此。 • 优势&#xff1a;对分数要求相对宽松&#xff0c;适合分数接近国家线的考生。 2. 安…

SQLite 注入:深入理解与防范策略

SQLite 注入:深入理解与防范策略 引言 SQLite,作为一款轻量级的数据库,被广泛应用于嵌入式系统、移动应用以及个人电脑中。尽管SQLite以其简单易用而受到青睐,但其安全机制若不恰当配置,则可能面临注入攻击的风险。本文旨在深入探讨SQLite注入的原理、类型及防范策略。 …

汽车与航空航天领域软件维护:深度剖析与未来展望

一、引言 在当今科技飞速发展的时代&#xff0c;汽车和航空航天领域的软件应用愈发广泛和深入&#xff0c;软件已成为这些行业系统的核心组成部分。从汽车的智能驾驶辅助系统到航空航天飞行器的飞行控制软件&#xff0c;软件的可靠性、安全性直接关系到整个系统的正常运行和人…

Jupyter notebook使用技巧

一、打开指定文件夹 在快捷方式目标中&#xff0c;使用如下代码 anaconda3\python.exe anaconda3\cwp.py anaconda3 anaconda3\python.exe anaconda3\Scripts\jupyter-notebook-script.py --notebook-dirD:\code\python

车辆视频检测器linux版对于密码中包含敏感字符的处理方法

由于密码中含有敏感字符&#xff0c;导致前端页面异常&#xff0c;图标变灰&#xff0c;坐标拾取打不开图像等&#xff0c;主要原因是&#xff1a;密码比较前后不一致&#xff0c;左边是Abc_110&#xff0c;右边是&#xff1a;Abc_110%2B&#xff0c;对于此问题&#xff0c;特别…

移动端六大语言速记:第12部分 - 测试与优化

移动端六大语言速记:第12部分 - 测试与优化 本文将对比Java、Kotlin、Flutter(Dart)、Python、ArkTS和Swift这六种移动端开发语言在测试与优化方面的特性,帮助开发者理解和掌握各语言的测试框架和性能优化技巧。 12. 测试与优化 12.1 单元测试框架对比 各语言单元测试框架…

Java—HTML:3D形变

今天我要介绍的是在Java HTML中CSS的相关知识点内容之一&#xff1a;3D形变&#xff08;3D变换&#xff09;。该内容包含透视&#xff08;属性&#xff1a;perspective&#xff09;&#xff0c;3D变换&#xff0c;3D变换函数以及案例演示&#xff0c; 接下来我将逐一介绍&…

模拟-与-现实协同训练:基于视觉机器人操控的简单方法

25年3月来自 UT Austin、Nvidia、UC Berkeley 和纽约大学的论文“Sim-and-Real Co-Training: A Simple Recipe for Vision-Based Robotic Manipulation”。 大型现实世界机器人数据集在训练通才机器人模型方面拥有巨大潜力&#xff0c;但扩展现实世界人类数据收集既耗时又耗资…

电子电气架构 --- 为配备区域计算的下一代电子/电气(E/E)架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…

【UE】渐变框材质

效果 步骤 新建一个材质&#xff0c;这里命名为“M_GlowingBorder”&#xff0c;打开“M_GlowingBorder”后&#xff0c;设置材质域为“用户界面”&#xff0c;混合模式为“半透明” 添加如下节点&#xff1a; 代码&#xff1a; Begin Object Class/Script/UnrealEd.Materia…

CTF web入门之爆破

爆破 web21: 打开burp进行抓包 通过对密码进行解析。得知密码是由拼接而来 admin:1 选择要攻击的参数 攻击方式。 选择payload方式 。。添加参数 1,2,3。账号 分隔符 密码 选择加密方式。添加buse64.去掉url字符。不然buse64后,会在url加密过一次,从而导致攻击不成…