1、概览 本文将带你了解如何使用 ResponseEntity 设置 HTTP 响应的 Body、Status 和 Header。
2、ResponseEntity ResponseEntity 表示整个 HTTP 响应:状态码、Header 和 Body。因此,可以用它来完全配置 HTTP 响应。只需从端点返回它,Spring 就会处理接下来的所有事情。
ResponseEntity 是一个泛型类。因此,可以使用任何类型作为响应体:
@GetMapping("/hello") ResponseEntity<String> hello() { return new ResponseEntity<>("Hello World!", HttpStatus.OK); } 通过编程式,可以针对不同情况返回不同的 HTTP 状态码:
@GetMapping("/age") ResponseEntity<String> age( @RequestParam("yearOfBirth") int yearOfBirth) { if (isInFuture(yearOfBirth)) { return new ResponseEntity<>( "Year of birth cannot be in the future", HttpStatus.BAD_REQUEST); // 400 } return new ResponseEntity<>( "Your age is " + calculateAge(yearOfBirth), HttpStatus.OK); // 200s } 还可以设置 HTTP 响应头:
1、概览 本文将带你了解 Spring Boot 应用中的日志配置。
2、初始设置 通过 Spring Initializr 初始化一个 Spring Boot 应用:
创建唯一的类 LoggingController:
@RestController public class LoggingController { Logger logger = LoggerFactory.getLogger(LoggingController.class); @RequestMapping("/") public String index() { logger.trace("A TRACE Message"); logger.debug("A DEBUG Message"); logger.info("An INFO Message"); logger.warn("A WARN Message"); logger.error("An ERROR Message"); return "Howdy! Check out the Logs to see the output..."; } } 启动应用后,只需访问 http://localhost:8080/,就能触发这些日志输出。
3、日志零配置 就日志记录而言,Spring Boot 唯一必须的依赖是 Apache Commons Logging。它是由 Spring 的 spring-jcl 模块提供的。
如果使用的是 Spring Boot Starter(几乎总是使用 Spring Boot Starter),就根本不用担心导入 spring-jcl 的问题。这是因为每个 Starter,比如 spring-boot-starter-web,都依赖于 spring-boot-starter-logging,它已经导入了 spring-jcl。
1、概览 本文将带你了解 Spring 中 @RequestParam 注解的用法。
简单地说,可以使用 @RequestParam 从请求中提取查询参数、表单参数甚至是多个参数。
2、示例端点 假设我们有一个端点 /api/foos,它接受一个名为 id 的查询参数:
@GetMapping("/api/foos") @ResponseBody public String getFoos(@RequestParam String id) { return "ID: " + id; } 在本例中,使用 @RequestParam 来提取 id 查询参数。
通过 GET 请求来调用 getFoos:
http://localhost:8080/spring-mvc-basics/api/foos?id=abc ---- ID: abc 接下来,看看注解的属性:name、value、required 和 defaultValue。
3、指定请求参数名称 在上一个示例中,变量名和参数名都是相同的。
如果变量名称和参数名称不同,可以使用 name 属性配置 @RequestParam 名称:
@PostMapping("/api/foos") @ResponseBody public String addFoo(@RequestParam(name = "id") String fooId, @RequestParam String name) { return "ID: " + fooId + " Name: " + name; } 也可以使用 @RequestParam(value = "id") 或直接使用 @RequestParam("id")。
1、概览 Spring Boot 通过 Hibernate Validator(Bean Validation 的实现)对数据验证提供了强大的支持。
本文将通过一个实际的 REST 应用带你了解如何在 Spring Boot 中校验数据。
2、Maven 依赖 在 pomx.ml 中添加 spring-boot-starter-web、spring-boot-starter-jpa 和 H2 database 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>2.1.214</version> <scope>runtime</scope> </dependency> 从 Boot 2.3 开始,还需要明确添加 spring-boot-starter-validation 依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> 3、示例 Domain 类 定义一个 JPA 实体类,User:
@Entity public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @NotBlank(message = "Name is mandatory") private String name; @NotBlank(message = "Email is mandatory") private String email; // 构造函数、Set、Set 方发省略 } User 实体类很简单,它展示了如何使用 Bean Validation 的约束来限制 name 和 email 字段。
1、概览 本文将带你了解使用 Spring Data JPA 获取最后一条记录的多种方式。
2、初始设置 首先,创建并初始化要查询的表。
创建一个 Post 实体类:
@Entity public class Post { @Id private Long id; private String title; private LocalDate publicationDate; // get、set 方法 } @Entity 表示注解的类代表数据库中的一个表。@Id 注解定义了主键。
为了简单起见,这里使用的是 H2 内存数据库。
添加一个基本的 SQL 脚本,创建 Post 类对应的 post 表:
DROP TABLE IF EXISTS post; CREATE TABLE post( id INT PRIMARY KEY, title VARCHAR(200), publication_date DATE ) 接着,添加一些数据:
INSERT INTO post (id, title, publication_date) VALUES(1, 'Facebook post', '2020-11-10'); INSERT INTO post (id, title, publication_date) VALUES(2, 'Instagram post', '2020-12-24'); INSERT INTO post (id, title, publication_date) VALUES(3, 'Twitter post', '2023-01-10'); INSERT INTO post (id, title, publication_date) VALUES(4, 'tiktok post', '2023-03-18'); INSERT INTO post (id, title, publication_date) VALUES(5, 'Pinterest post', '2023-09-09'); 如你所见,最后一条记录的 ID 是 5。
1、概览 本文将带你了解 Spring Boot 应用中的声明式 REST 客户端 - Spring Cloud OpenFeign。
Feign 通过可插拔的注解支持(包括 Feign 注解和 JAX-RS 注解)使编写 Web 客户端更加容易。
此外,Spring Cloud 还增加了对 Spring MVC 注解和使用与 Spring Web 中相同的 HttpMessageConverter 的支持。
使用 Feign 的一个好处是,除了接口定义外,无需编写任何调用服务的代码。
2、依赖 首先,创建 Spring Boot Web 项目,并在 pom.xml 文件中添加 spring-cloud-starter-openfeign 依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> 此外,还需要添加 spring-cloud-dependencies 依赖:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 你可以在 Maven Central 上找到 spring-cloud-starter-openfeign 和 spring-cloud-dependencies 的最新版本。
3、Feign 客户端 接着,需要将 @EnableFeignClients 添加到 main 类中:
1、概览 本文将带你了解如何在 Spring 中重新加载 Properties 配置属性。
2、Spring 读取 Properties Spring 有几种不同的方式来访问 Properties:
Environment - 可以注入 Environment,然后使用 Environment#getProperty 来读取给定的属性。Environment 包含不同的属性源,如系统属性(System Properties)、-D 参数和 application.properties(或者 .yml) 等。还可以使用 @PropertySource 将额外的属性源添加到 Environment 中。 Properties - 可以将 properties 文件加载到 Properties 实例中,然后在 Bean 中通过调用 properties.get("property") 使用它。 @Value - 可以使用 @Value(${'property'}) 注解在 Bean 中注入特定属性。 @ConfigurationProperties - 可以使用 @ConfigurationProperties 在 Bean 中加载层次化的属性。。 3、重新加载外部属性文件 要在运行时更改文件中的属性(Properties),应该将该文件放在 Jar 之外的某个地方。然后使用命令行参数 -spring.config.location=file://{文件路径} 告诉 Spring 文件的位置。或者,也可以将其放在 application.properties 中。
对于基于磁盘文件的 Properties,可以开发一个端点或定时任务来读取文件并更新 Properties。
Apache 的 commons-configuration 是一个用于重新加载属性文件的库。可以使用 PropertiesConfiguration 和不同的 ReloadingStrategy 。
1、概览 上一篇文章《Spring Cloud Gateway 教程》中介绍了 Spring Cloud Gateway 网关框架。本文将带你了解如何在 Spring Cloud Gateway 中自定义 Filter。以及如何在 Filter 中修改请求和响应数据。
2、项目设置 创建一个基本应用,并将其用作 API 网关。
2.1、Maven 配置 在使用 Spring Cloud 时,往往通过 <dependencyManagement> 来管理组件的版本:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Hoxton.SR4</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 添加 Spring Cloud Gateway,无需指定使用的实际版本:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> 最新的 Spring Cloud 版本可通过 Maven Central 中找到。当然,需要注意使用的 Spring Cloud 版本需要与 Spring Boot 版本兼容。
2.2、API 网关配置 假设 API 服务在本地 8081 端口运行,在 /resource 端点暴露了一个简单的字符串资源。
接下来,配置网关,把请求代理到该服务。简而言之,当请求网关的 URI 路径中带有 /service 前缀的请求时,网关将把请求转发给该服务。
1、概览 本文将带你了解 Java 19 的 虚拟线程 和 Reactor Webflux 的基本工作原理以及它们的优缺点。
2、代码示例 假如我们开发的是一个电商后台,有如下 “负责计算和发布添加到购物车中的商品价格” 的函数。
class ProductService { private final String PRODUCT_ADDED_TO_CART_TOPIC = "product-added-to-cart"; private final ProductRepository repository; private final DiscountService discountService; private final KafkaTemplate<String, ProductAddedToCartEvent> kafkaTemplate; // 构造函数 public void addProductToCart(String productId, String cartId) { Product product = repository.findById(productId) .orElseThrow(() -> new IllegalArgumentException("not found!")); Price price = product.basePrice(); if (product.category().isEligibleForDiscount()) { BigDecimal discount = discountService.discountForProduct(productId); price.setValue(price.getValue().subtract(discount)); } var event = new ProductAddedToCartEvent(productId, price.
1、概览 本文将带你了解如何在 UI (前端)应用中使用 Zuul 作为代理与 Spring REST 服务通信,使用 Zuul 代理的目的是为了统一处理 CORS 和 Same Origin Policy 问题。
Zuul 是 Netflix 基于 JVM 的路由和服务器端负载均衡器。Spring Cloud 与嵌入式 Zuul 代理进行了很好的集成。
2、Maven 配置 首先,在 UI 应用的 pom.xml 中添加 Spring Cloud Zuul 依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> <version>2.2.0.RELEASE</version> </dependency> 最新版本可在 此处 找到。
3、Zuul Properties 接着,在 application.yml 中对 Zuul 进行配置:
zuul: routes: foos: path: /foos/** url: http://localhost:8081/spring-zuul-foos-resource/foos 如上:
代理了资源服务器 Foos UI 应用上所有以 /foos/ 开头的请求都将转发到 Foos 资源服务器 http://loclahost:8081/spring-zuul-foos-resource/foos/ 4、API API 是一个简单的 Spring Boot 应用,监听 8081 端口。