Spring

HttpMessageNotWritableException: "No converter found for return value of type"

1、概览 本文将带你了解 Spring 中出现 HttpMessageNotWritableException: "No converter found for return value of type" 异常的原因以及解决办法。 2、原因 通常,当 Spring 无法获取返回对象的属性时,就会出现这种异常。 导致这种异常的最典型原因通常是返回对象的属性没有任何 public getter 方法。 默认情况下,Spring Boot 依赖于 Jackson 库来完成序列化/反序列化请求和响应对象的所有工作。 因此,导致异常的另一个常见原因可能是 缺少或使用了错误的 Jackson 依赖。 简而言之,这种异常情况的一般准则是检查是否存在以下情况: 默认构造器 Getter 方法 Jackson 依赖 注意,异常类型 已从 java.lang.IllegalArgumentException 变为 org.springframework.http.converter.HttpMessageNotWritableException。 3、实例 现在,来看看一个会产生 org.springframework.http.converter.HttpMessageNotWritableException: "No converter found for return value of type" 异常的示例 使用 Spring Boot 构建一个基本的 REST API。 首先,创建 Student Model 类,并假装忘记生成 Getter 方法: public class Student { private int id; private String firstName; private String lastName; private String grade; public Student() { } public Student(int id, String firstName, String lastName, String grade) { this.

REST API:JAX-RS 与 Spring

1、概览 本文将带你了解 JAX-RS 和 Spring MVC 在 REST API 开发方面的区别。 2、Jakarta RESTful Web 服务 要成为 Jakarta EE 世界的一部分,一项功能必须具备规范、兼容的实现和 TCK(技术兼容套件)。JAX-RS 就是一套用于构建 REST 服务的规范。其最著名的参考实现是 RESTEasy 和 Jersey。 现在,通过实现一个简单的 Controller 来熟悉一下 Jersey: @Path("/hello") public class HelloController { @GET @Path("/{name}") @Produces(MediaType.TEXT_PLAIN) public Response hello(@PathParam("name") String name) { return Response.ok("Hello, " + name).build(); } } 上面的代码中,端点返回一个简单的 “text/plain” 响应,这是由 @Produces 注解指定的。具体来说,暴露了一个名为 hello 的 HTTP 资源,它接受一个名为 name 的参数,使用了两个 @Path 注解进行路径的定义。还使用 @GET 注解指定它是一个 GET 请求。 3、使用 Spring MVC 实现 REST Spring MVC 是 Spring Framework 的一个模块,用于创建 Web 应用程序。它为 Spring Framework 添加了 REST 功能。

Spring 中的 @EntityScan 和 @ComponentScan 注解

1、概览 在 Spring 应用中,我们通常使用 @EntityScan 来指定实体类所在的包,使用 @ComponentScan 来指定 Bean 组件所在的包。 组件是带有 @Controller、@Service、@Repository、@Component、@Bean 等注解的类。实体则是带有 @Entity 注解的类。 本文将带你了解 @EntityScan 和 @ComponentScan 注解在 Spring 中的用法和区别。 2、@EntityScan 注解 在 Spring 中,有 2 种方式放置 @Entity 实体类: 在 main 包或者其子包下 在完全不同的 root 包中 在第一种情况下,可以使用 @EnableAutoConfiguration 来启用 Spring 自动配置 Application Context。 在第二种情况下,需要用 @EntityScan 来告诉 Spring 实体所在的包,如下。 @Configuration @EntityScan("com.baeldung.demopackage") public class EntityScanDemo { // ... } 注意,使用 @EntityScan 会禁用 Spring Boot 对实体的自动扫描配置。 3、@ComponentScan 注解 与 @EntityScan 和实体类似,如果我们希望 Spring 只使用一组特定的 Bean 类,可以使用 @ComponentScan 注解。

获取 Spring Boot 中的所有端点

1、概览 本文将带你了解如何获取 Spring Boot 应用中的所有 REST 端点。 2、映射端点 在 Spring Boot 应用中,通过在 Controller 类中使用 @RequestMapping 注解来暴露 REST API 端点。要获取这些端点,有三种选择:事件监听器、Spring Boot Actuator 或 SpringDoc。 3、事件监听器 在 Controller 中使用 @RestController 和 @RequestMapping 创建 REST API 服务。这些类在 Spring Application Context 中注册为 Spring Bean。因此,当 Application Context 在启动时准备就绪,就可以使用事件监听器获取端点。定义监听器有两种方法。可以实现 ApplicationListener 接口,或者使用 @EventListener 注解。 3.1、ApplicationListener 接口 在实现 ApplicationListener 时,必须定义 onApplicationEvent() 方法: @Override public void onApplicationEvent(ContextRefreshedEvent event) { ApplicationContext applicationContext = event.getApplicationContext(); RequestMappingHandlerMapping requestMappingHandlerMapping = applicationContext .getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); Map<RequestMappingInfo, HandlerMethod> map = requestMappingHandlerMapping .

解决 Spring 中 “not eligible for auto-proxying” 警告

1、概览 本文将带你了解出现 “not eligible for auto-proxying” 警告的原因以及如何修复它。 2、“not eligible for auto proxying” 的原因 2.1、配置示例 首先,创建一个自定义 RandomInt 注解,使用它来注解应该插入指定范围内的随机整数的字段。 @Retention(RetentionPolicy.RUNTIME) public @interface RandomInt { int min(); int max(); } 其次,创建一个简单的 Spring 组件 DataCache 类。将一个可能被使用的随机 Group 分配给缓存,例如用于支持分片。为了实现这一点,使用自定义的注解来注解该字段: @Component public class DataCache { @RandomInt(min = 2, max = 10) private int group; private String name; } 现在,来看看 RandomIntGenerator 类。它是一个 Spring 组件,用于在 RandomInt 注解注解的字段中插入随机 int 值: @Component public class RandomIntGenerator { private Random random = new Random(); private DataCache dataCache; public RandomIntGenerator(DataCache dataCache) { this.

把 Spring Bean 设置为 Null

1、概览 本文将带你了解如何把 Spring Context 中的 Bean 设置为 null。在某些情况下,这可能很有用。例如,在测试时不想提供 Mock 对象。以及,在使用一些可选功能时,可能希望避免创建实现,并直接传递 null。 2、组件设置 有几种方法可以将 Bean 设置为 null,具体取决于 Context 的配置方式,本文主要考虑 XML、注解和 Java 配置的方式。 使用一个简单的设置,包含两个类: @Component public class MainComponent { private SubComponent subComponent; public MainComponent(final SubComponent subComponent) { this.subComponent = subComponent; } public SubComponent getSubComponent() { return subComponent; } public void setSubComponent(final SubComponent subComponent) { this.subComponent = subComponent; } } 本例将演示如何在 Spring Context 中将 SubComponent 设置为 null: @Component public class SubComponent {} 3、在 XML 配置中使用占位符 在 XML 配置中,可以使用一个特殊的占位符来标识 null 值:

Spring Bean 的命名

1、概览 当有多个相同类型的实现时,需要对 Spring Bean 进行不同的命名。这是因为如果 Bean 没有唯一的名称,Spring 在注入 Bean 时会出现歧义。 通过控制 Bean 的命名,可以告诉 Spring 我们想将哪个 Bean 注入到目标对象中。 本文将带你了解 Spring Bean 命名策略,以及如何为同一类型的 Bean 赋予多个名称。 2、默认 Bean 命名策略 Spring 为创建 Bean 提供了多种注解,可以在不同的级别使用。例如,可以在 Bean 类上放置一些注解,在创建 Bean 的方法上放置另一些注解。 首先,来看看 Spring 的默认命名策略。当只指定注解而不指定任何值时,Spring 是如何命名 Bean 的? 2.1、类级注解 首先从在类级别使用的注解的默认命名策略开始。Spring 会使用类名为 Bean 命名,并将第一个字母转换为小写。 举个例子: @Service public class LoggingService { } 如上,Spring 为 LoggingService 类创建了一个 Bean,并使用 loggingService 名称进行了注册。 这种默认的命名策略适用于所有用于创建 Spring Bean 的类级别注解,例如 @Component、@Service 和 @Controller。 2.2、方法级注解 Spring 提供了 @Bean 和 @Qualifier 等注解,可用于创建 Bean 的方法。

在 Spring 中使用 Thymeleaf 显示错误信息

1、概览 本文将带你了解如何在 Spring 应用中使用 Thymeleaf 模板来渲染错误信息。 我们会通过一个简单的 Spring Boot 项目来进行演示,该项目是一个 “用户注册” 应用,需要验证客户端传递的各个字段,还要处理全局错误。 2、Spring Boot 应用示例 创建一个简单的 Spring Boot 用户注册应用,需要一个 Controller、一个 Repository 和一个 Entity。 2.1、Maven 依赖 添加所有需要的 Spring Boot Starter:Web Mvc、Hibernate Validation、 Thymeleaf 和 JPA。 此外,还需要一个 H2 内存数据库依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> <version>1.4.200</version> </dependency> 2.2、实体 User 实体如下: @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.

在集成测试中覆盖 Spring Bean

1、概览 在 Spring 集成测试中,我们可能想要覆盖应用的一些 Bean。通常,可以使用专门为测试定义的 Spring Bean 来实现。然而,在 Spring Context 中提供多个具有相同名称的 Bean,可能会遇到 BeanDefinitionOverrideException 异常。 本文将带你了解如何在 Spring Boot 应用中 Mock 或 Stub 集成测试的 Bean,同时避免 BeanDefinitionOverrideException。 2、在测试中使用 Mock 或 Stub 在深入了解细节之前,应该了解如何在测试中使用 Mock 或 Stub。这是一种强大的技术,可以确保应用不会出现错误。 也可以在 Spring 中采用这种方法。不过,只有在使用 Spring Boot 时才能直接模拟集成测试 Bean。 或者,也可以使用测试配置来 Stub 或 Mock bean。 3、Spring Boot 应用示例 创建一个简单的 Spring Boot 应用,包含了一个 Controller、Service 和一个 Configuration 类。 @RestController public class Endpoint { private final Service service; public Endpoint(Service service) { this.service = service; } @GetMapping("/hello") public String helloWorldEndpoint() { return service.

Spring Framework 6.1 正式发布

Spring Framework 6.1 中的新变化 核心容器 总体上 与虚拟线程和 JDK 21 兼容。 虚拟线程的配置选项:专用的 VirtualThreadTaskExecutor 和 SimpleAsyncTaskExecutor 上的虚拟线程模式,以及具有新线程每个任务策略和虚拟线程模式的类似的 SimpleAsyncTaskScheduler。 与 Project CRaC(JVM 检查点恢复)的生命周期集成(请参阅 相关文档)),包括 -Dspring.context.checkpoint=onRefresh 选项。 为 ThreadPoolTaskExecutor 和 ThreadPoolTaskScheduler 以及 SimpleAsyncTaskScheduler 集成了生命周期 暂停/恢复功能 和 并行优雅停机 功能。 可使用 -Dspring.context.exit=onRefresh 选项进行 AppCDS 训练运行,这是主要的用例;请参阅 31595。 可达性元数据贡献改进,为即将到来的 GraalVM 变动做准备:缺失的可达性元数据将很快报告为运行时异常,以获得更好的开发人员体验。参见 31213。 异步/响应式销毁方法(如 R2DBC ConnectionFactory);参见 26691。 异步/响应式 Cacheable 方法,包括缓存接口和 CaffeineCacheManager 中的相应支持;参见 17559 和 17920。 响应式 @Scheduled 方法(包括 Kotlin 正则表达式);参见 22924。 为每个 @Scheduled 方法选择特定目标调度器;见 20818。 用于一次性任务(仅有初始延迟)的 @Scheduled 方法;见 31211。 @Scheduled 方法的可观测性;见 29883。 Spring 不会为 @Async 或 @EventListener 注解的方法生成开箱即用的观测结果,但会帮助你为这些方法的执行传播上下文(例如带有当前 trace id 的 MDC 日志)。请参见新的 ContextPropagatingTaskDecorator、相关参考文档部分 和 issue 31130。 Validator 工厂方法,用于编程式 validator 实现;请参阅 29890。 Validator.