springdoc-openapi icon indicating copy to clipboard operation
springdoc-openapi copied to clipboard

UpperSnakeCaseStrategy is not working with spring boot and ParameterObject

Open AlehGalo opened this issue 1 year ago • 3 comments

UpperSnakeCaseStrategy + ParameterObject + Spring Boot is not working properly.

Hi there.

I'm using Request DTO object.

@JsonNaming(PropertyNamingStrategies.UpperSnakeCaseStrategy.class)
@Data
public class RequestDto {
    private String personalNumber;
...
}

With Rest Controller

@GetMapping
    public Response getData(@ParameterObject @NonNull RequestDto requestDto) {
        return service.getdata(requestDto);
    }

There was a bug fixed #2484 Seems like case was missed and stayed untouched. It's not a frequent case but our company needs it.

Versions are as follows

<springdoc-openapi.version>2.6.0</springdoc-openapi.version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.7</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

Thanks in advance.

AlehGalo avatar Jul 09 '24 14:07 AlehGalo

Maybe a DelegatingMethodParameterCustomizer can help.

import java.lang.reflect.Field;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.springdoc.core.customizers.DelegatingMethodParameterCustomizer;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils;

import com.fasterxml.jackson.databind.PropertyNamingStrategies;
import com.fasterxml.jackson.databind.annotation.JsonNaming;

public class MyMethodParameterCustomizer implements DelegatingMethodParameterCustomizer {

    @Override
    public void customize(MethodParameter originalParameter, MethodParameter methodParameter) {
        if (AnnotatedElementUtils.isAnnotated(methodParameter.getContainingClass(), JsonNaming.class)) {
            JsonNaming jsonNaming = methodParameter.getContainingClass().getAnnotation(JsonNaming.class);
            if (jsonNaming.value().equals(PropertyNamingStrategies.UpperSnakeCaseStrategy.class)) {
                try {
                    Field parameterNameField = FieldUtils.getDeclaredField(methodParameter.getClass(), "parameterName",
                            true);
                    parameterNameField.set(methodParameter,
                            PropertyNamingStrategies.UpperSnakeCaseStrategy.INSTANCE.translate(
                                    methodParameter.getParameterName()));
                } catch (IllegalAccessException e) {
                    // log errors
                }
            }
        }
    }
}

Then inject it as a bean:

@Bean
DelegatingMethodParameterCustomizer delegatingMethodParameterCustomizer() {
    return new MyMethodParameterCustomizer();
}

This will translate personNumber to PERSON_NUMBER in Swagger. snake

buzzerrookie avatar Jul 24 '24 08:07 buzzerrookie

Hi @buzzerrookie.

Thank you for the code sample. It seems to be working.

But in general it looks like an issue of springdoc and workaround exists.

AlehGalo avatar Aug 22 '24 07:08 AlehGalo

Checked the code. It brakes springdoc swagger.

Requests parameters sent are not correctly mapped back.

Sending request from swagger results in Bad Request.

AlehGalo avatar Aug 22 '24 08:08 AlehGalo