0

I'm using Springdoc 1.4 with Spring-Boot 2.3 and in the OperationCustomizer class, I need to read value from the application properties file. But everytime the field is always initialized to null. The specifications are as follows

application.properties

application.security.authorization=true

OperationCustomizer class

@Component
public class GlobalHeaderAdder implements OperationCustomizer {
    @Value("${application.security.authorization:true}")
    Boolean authFilterEnabled;       // <---- Initialized to NULL

    @Override
    public Operation customize(Operation operation, HandlerMethod handlerMethod) {
        System.out.println("____________________________\n" + authFilterEnabled + "\n+++++++++++++++++++++++++");
        if (authFilterEnabled) {
            operation.addParametersItem(new Parameter().$ref("#/components/parameters/ClientID"));
        }
        operation.addSecurityItem(new SecurityRequirement().addList("Authorization"));
        List<Parameter> parameterList = operation.getParameters();
        if (parameterList != null && !parameterList.isEmpty()) {
            Collections.rotate(parameterList, 1);
        }
        return operation;
    }
}

The class is being called by the below code

@Bean
public GroupedOpenApi hideApis() {
    return GroupedOpenApi.builder().group("default")
            .pathsToExclude("/api/v2/**", "/v2/**")
            .pathsToMatch("/api/v1/**", "/v1/**")
            .addOperationCustomizer(new GlobalHeaderAdder())
            .build();
}

The approach provided here works but I would like to have an approach where I don't have to make the field static.

Vasyl Sarzhynskyi
  • 3,689
  • 2
  • 22
  • 55
Debargha Roy
  • 2,320
  • 1
  • 15
  • 34

2 Answers2

4

issue with your code is that you initiate GlobalHeaderAdder by your own via invoking constructor, but in that case it's not a spring bean, and, as a result, @Value("${application.security.authorization:true}") and all other spring annotations will not work.

so, to fix the issue, you should either inject GlobalHeaderAdder bean for creating hideApis:

@Bean
public GroupedOpenApi hideApis(GlobalHeaderAdder globalHeaderAdder) {
    return GroupedOpenApi.builder().group("default")
        .pathsToExclude("/api/v2/**", "/v2/**")
        .pathsToMatch("/api/v1/**", "/v1/**")
        .addOperationCustomizer(globalHeaderAdder)
        .build();
}

or create a bean in the following way, that you will be able to inject into hideApis in the way mentioned above (for this option you don't need to have @Component under class GlobalHeaderAdder):

@Bean
public GlobalHeaderAdder globalHeaderAdder() {
    return new GlobalHeaderAdder();
}
Vasyl Sarzhynskyi
  • 3,689
  • 2
  • 22
  • 55
  • Thanks a lot @Vasyl! Can you help with some resource(s) that will cover such basics of the Spring framework? – Debargha Roy Jul 11 '20 at 08:38
  • 1
    maybe try to read articles about spring, or if you want to get more complex knowledge, then try to read a book like 'Beginning Spring 5: From Novice to Professional' – Vasyl Sarzhynskyi Jul 11 '20 at 11:33
1

You just need to fix the value in @Value.
Your class should be like this:

@Component
public class GlobalHeaderAdder implements OperationCustomizer {
    @Value("${application.security.authorization}")    //<< only the name of the property, 
    Boolean authFilterEnabled;
Victor Pietro
  • 21
  • 1
  • 6
  • 1
    nope, it's not correct. expression `@Value("${application.security.authorization:true}")` means that if such property not specified, then we should take `true` – Vasyl Sarzhynskyi Jul 11 '20 at 05:50