Сгенерированные перечисления с пользовательскими значениями не десериализуются должным образом.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Сгенерированные перечисления с пользовательскими значениями не десериализуются должным образом.

Сообщение Anonymous »

Похоже, что перечисления с пользовательским значением, созданные с помощью генератора openapi для сервера Spring, не работают должным образом.
Простой пример для воспроизведения проблемы.

Спецификация Openapi:

Код: Выделить всё

openapi: 3.0.3
info:
title: Simple Example
version: 1.0.0
paths:
/v1/hello:
get:
operationId: getGreetings
parameters:
- in: query
name: name
required: true
schema:
type: string
- in: query
name: greet
schema:
$ref: '#/components/schemas/GreetEnum'
responses:
'200':
description: "Success greeting"
content:
application/json:
schema:
type: string
components:
schemas:
GreetEnum:
type: string
enum:
- mr
- mrs
build.gradle:

Код: Выделить всё

plugins {
id 'java'
id 'org.springframework.boot' version '3.2.11'
id 'io.spring.dependency-management' version '1.1.6'
id 'org.openapi.generator' version '7.9.0'
}

group = 'dev.alubenets'
version = '0.0.1-SNAPSHOT'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

repositories {
mavenCentral()
}

openApiGenerate {
inputSpec.set("$projectDir/src/api-spec/api.yaml")
outputDir.set("$projectDir/build/generated")
generatorName.set("spring")
apiPackage.set("${group}.api")
modelPackage.set("${group}.api.model")
configOptions.set([
documentationProvider : "none",
useSpringBoot3        : "true",
useSwaggerUI          : "false",
interfaceOnly         : "true",
skipDefaultInterface  : "true",
serializableModel     : "true",
openApiNullable       : "false",
useEnumCaseInsensitive: "true"
])
globalProperties.set([
apis  : "",
models: "",
])
}

tasks.register('apiConfigure', DefaultTask) {
project.sourceSets {
main.java.srcDir "build/generated/src/main/java"
}
}

compileJava {
dependsOn('openApiGenerate', 'apiConfigure')
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-validation'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
useJUnitPlatform()
}
Класс @Controller:

Код: Выделить всё

@RestController
public class V1Controller implements V1Api {

@Override
public ResponseEntity getGreetings(String name, GreetEnum greet) {
return ResponseEntity.ok("Hello " + greet.toString() + " " + name + "!");
}
}
Класс TestController:

Код: Выделить всё

@WebMvcTest(controllers = V1Controller.class)
class V1ControllerTest {

@Autowired
MockMvc mockMvc;

@Test
void getGreetings() throws Exception {
mockMvc
.perform(
get("/v1/hello")
.queryParam("name", "Alex")
.queryParam("greet", "mrs")
)
.andExpect(status().isOk());
}
}
У меня есть следующее исключение:

Код: Выделить всё

Failed to convert value of type 'java.lang.String' to required type 'dev.alubenets.api.model.GreetEnum';  Failed to convert from type [java.lang.String] to type [@jakarta.validation.Valid @org.springframework.web.bind.annotation.RequestParam dev.alubenets.api.model.GreetEnum] for value [mrs]]
Сгенерированное перечисление:

Код: Выделить всё

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-11T14:25:24.928137300+03:00[Europe/Moscow]", comments = "Generator version: 7.9.0")
public enum GreetEnum {

MR("mr"),

MRS("mrs");

private String value;

GreetEnum(String value) {
this.value = value;
}

@JsonValue
public String getValue() {
return value;
}

@Override
public String toString() {
return String.valueOf(value);
}

@JsonCreator
public static GreetEnum fromValue(String value) {
for (GreetEnum b : GreetEnum.values()) {
if (b.value.equalsIgnoreCase(value)) {
return b;
}
}
throw new IllegalArgumentException("Unexpected value '" + value + "'");
}
}
Сгенерированный интерфейс:

Код: Выделить всё

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2024-11-11T14:25:24.928137300+03:00[Europe/Moscow]", comments = "Generator version: 7.9.0")
@Validated
public interface V1Api {

@RequestMapping(
method = RequestMethod.GET,
value = "/v1/hello",
produces = { "application/json" }
)

ResponseEntity getGreetings(
@NotNull  @Valid @RequestParam(value = "name", required = true) String name,
@Valid @RequestParam(value = "greet", required = false) GreetEnum greet
);

}
Итак, я предполагаю, что @JsonCreator следует использовать для создания экземпляра перечисления из String, но он даже не используется, пока я использую отладка с использованием точек останова.


Подробнее здесь: https://stackoverflow.com/questions/791 ... d-properly
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»