简体   繁体   中英

How register custom Converter in Spring Boot CLI application

I would like register in my spring boot command line app custom spring Converter but i can't solve it. Each solution what I found are for spring boot web app. I think it has to be somehow possible.

My application is configured via property file. For loading property file into app we use spring run argument --spring.config.location with value path to our property file.

For easier usage in app I would like use enums for some properties. If user use in property value which isn't supported by Enum class. App will throw exception

Caused by: java.lang.IllegalArgumentException: No enum constant com.actimize.amlperfreport.enums.OSFamily.window
    at org.springframework.boot.convert.LenientObjectToEnumConverterFactory$LenientToEnumConverter.findEnum(LenientObjectToEnumConverterFactory.java:93)
    at org.springframework.boot.convert.LenientObjectToEnumConverterFactory$LenientToEnumConverter.convert(LenientObjectToEnumConverterFactory.java:80)
    at org.springframework.boot.convert.LenientObjectToEnumConverterFactory$LenientToEnumConverter.convert(LenientObjectToEnumConverterFactory.java:61)
    at org.springframework.core.convert.support.GenericConversionService$ConverterFactoryAdapter.convert(GenericConversionService.java:436)
    at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
    ... 107 common frames omitted

It isn't user friendly. I would like use custom Converter for validate input values from property file before convert to enum, log my custom log message and set default value for errors.

Part of my property file for example:

ais.system.environment=windows
db.system.environment=windows
rcm.system.environment=unix
db.server.type=mssql
...

Class for store values from property file in app:

@Slf4j
@Getter
@Setter
@Configuration
public class ExecutionTemplate {

    @Value("#{'${ais.system.environment}'.toLowerCase()}")
    private OSFamily environmentAIS;
...

Custom Converter:

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.converter.Converter;

@Slf4j
public class OSFamilyConverter implements Converter<String,OSFamily> {
    @Override
    public OSFamily convert(String source) {
        if(OSFamily.WINDOWS.getType().equals(source)){
            return OSFamily.WINDOWS;
        } else if(OSFamily.UNIX.getType().equals(source)){
            return OSFamily.UNIX;
        }
        log.error("[{}] isn't between supported operation system. App will use as operation system [{}]. Supporter operation systems are [{},{}].",
                source,OSFamily.UNIX.getType(),OSFamily.UNIX.getType(),OSFamily.WINDOWS.getType());
        return OSFamily.UNIX;
    }
}

Main class:

@Slf4j
@RequiredArgsConstructor
@SpringBootApplication
public class AmlPerfReportApplication implements CommandLineRunner {

    private final ApplicationContext context;
    private final OrchestratorService orchestratorService;
    private final Messenger messenger;
    private JCommander jCommander;


    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(AmlPerfReportApplication.class);

        app.setBannerMode(Banner.Mode.LOG);
        app.run(args);
    }

    @Override
    public void run(String... args) throws Exception {
        Args arguments = new Args();
...

If i am right custom converter has to be register in main method before call run method. But i don't know how.

My app doesn't have web interface i can't use method addFormatter from WebMvcConfigurer How to register custom converters in spring boot?

Could you please help me?

Converter seems to only work on properties bound to a ConfigurationProperties , but not @Value .

This works for me:

public enum OSFamily { }

@Component
@ConfigurationPropertiesBinding
public class OSFamilyConverter implements Converter<String, OSFamily> { }

@Component
@ConfigurationProperties(prefix = "system")
@Getter @Setter
class SystemProperties{
    private OSFamily ais;
    private OSFamily db;
    private OSFamily rcm;
}

...
// Then inject normally
@Autowired
MyConfigProperties systemProperties;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM