Skip to content

Commit 15723c9

Browse files
committed
Fixes for Spring Boot 3.5.0 API
Spring Boot renamed the property methods to determine if HAL is enabled or not. Use reflection to determine which method to call so we can support both versions Fixes #3005
1 parent 8439195 commit 15723c9

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/configuration/SpringDocHateoasConfiguration.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
package org.springdoc.core.configuration;
2828

29+
import java.util.List;
2930
import java.util.Optional;
3031

3132
import com.fasterxml.jackson.core.JsonGenerator;
@@ -50,6 +51,8 @@
5051
import org.springframework.context.annotation.Lazy;
5152
import org.springframework.hateoas.Links;
5253
import org.springframework.hateoas.server.LinkRelationProvider;
54+
import org.springframework.lang.NonNull;
55+
import org.springframework.util.ReflectionUtils;
5356

5457
/**
5558
* The type Spring doc hateoas configuration.
@@ -89,7 +92,7 @@ HateoasHalProvider hateoasHalProvider(Optional<HateoasProperties> hateoasPropert
8992
@ConditionalOnMissingBean
9093
@Lazy(false)
9194
CollectionModelContentConverter collectionModelContentConverter(HateoasHalProvider halProvider, LinkRelationProvider linkRelationProvider) {
92-
return halProvider.isHalEnabled() ? new CollectionModelContentConverter(linkRelationProvider) : null;
95+
return isHalEnabled(halProvider) ? new CollectionModelContentConverter(linkRelationProvider) : null;
9396
}
9497

9598
/**
@@ -105,7 +108,7 @@ CollectionModelContentConverter collectionModelContentConverter(HateoasHalProvid
105108
@ConditionalOnMissingBean(name = Constants.LINKS_SCHEMA_CUSTOMIZER)
106109
@Lazy(false)
107110
GlobalOpenApiCustomizer linksSchemaCustomizer(HateoasHalProvider halProvider, SpringDocConfigProperties springDocConfigProperties) {
108-
if (!halProvider.isHalEnabled()) {
111+
if (isHalEnabled(halProvider)) {
109112
return openApi -> {
110113
};
111114
}
@@ -124,6 +127,24 @@ GlobalOpenApiCustomizer linksSchemaCustomizer(HateoasHalProvider halProvider, Sp
124127
HateoasLinksConverter hateoasLinksConverter(ObjectMapperProvider springDocObjectMapper) {
125128
return new HateoasLinksConverter(springDocObjectMapper) ;
126129
}
127-
128-
129-
}
130+
131+
private boolean isHalEnabled(@NonNull HateoasHalProvider halProvider) {
132+
// in SB 3.5.0 isHalEnabled was renamed to isUseHalAsDefaultJsonMediaType
133+
// We have to use reflection to support both versions
134+
var possibleMethodNames = List.of("isUseHalAsDefaultJsonMediaType", "isHalEnabled");
135+
136+
for (var methodName : possibleMethodNames) {
137+
var method = ReflectionUtils.findMethod(halProvider.getClass(), methodName);
138+
if (method != null) {
139+
var retval = ReflectionUtils.invokeMethod(method, halProvider);
140+
if (retval == null) {
141+
throw new IllegalStateException("Unable to determine if HAL is enabled");
142+
}
143+
144+
return (Boolean) retval;
145+
}
146+
}
147+
148+
throw new IllegalStateException("Unable to determine if HAL is enabled, no method found");
149+
}
150+
}

springdoc-openapi-starter-common/src/main/java/org/springdoc/core/providers/HateoasHalProvider.java

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,16 @@
2626

2727
package org.springdoc.core.providers;
2828

29+
import java.util.List;
2930
import java.util.Optional;
3031

3132
import jakarta.annotation.PostConstruct;
3233

34+
import org.jetbrains.annotations.NotNull;
3335
import org.springframework.boot.autoconfigure.hateoas.HateoasProperties;
3436
import org.springframework.hateoas.mediatype.hal.Jackson2HalModule;
37+
import org.springframework.lang.NonNull;
38+
import org.springframework.util.ReflectionUtils;
3539

3640
/**
3741
* The type Hateoas hal provider.
@@ -79,8 +83,28 @@ protected void init() {
7983
*/
8084
public boolean isHalEnabled() {
8185
return hateoasPropertiesOptional
82-
.map(HateoasProperties::getUseHalAsDefaultJsonMediaType)
86+
.map(this::isUseHalAsDefaultJsonMediaType)
8387
.orElse(true);
8488
}
8589

90+
private Boolean isUseHalAsDefaultJsonMediaType(@NonNull HateoasProperties hateoasProperties) {
91+
// in SB 3.5.0 getUseHalAsDefaultJsonMediaType was renamed to isUseHalAsDefaultJsonMediaType
92+
// We have to use reflection to support both versions
93+
var possibleMethodNames = List.of("isUseHalAsDefaultJsonMediaType", "getUseHalAsDefaultJsonMediaType");
94+
95+
for (var methodName : possibleMethodNames) {
96+
var method = ReflectionUtils.findMethod(hateoasProperties.getClass(), methodName);
97+
if (method != null) {
98+
var retval = ReflectionUtils.invokeMethod(method, hateoasProperties);
99+
if (retval == null) {
100+
return null;
101+
}
102+
103+
return (Boolean) retval;
104+
}
105+
}
106+
107+
// We should have found a method, if not, throw an exception
108+
throw new IllegalStateException("Unable to determine if HAL is enabled, no method found");
109+
}
86110
}

0 commit comments

Comments
 (0)