0

I have an Enum class and I would like to use the lowercase (i.e., case insensitive) in the URL call of the Get:

package org.crea.w4ag_mock.mocker;

import com.fasterxml.jackson.annotation.JsonProperty;

public enum TimeFramesEnum {

    /*
    baseline = BASELINE
    period2_2040 = PERIOD2_2040
    period3_2070 = PERIOD2_2070
    */

    BASELINE,
    PERIOD2_2040,
    PERIOD2_2070
}

I have tried various examples but none without useful result.

Each time I get the following error:

{
    "timestamp": "2023-02-27T15:22:06.493+00:00",
    "status": 400,
    "error": "Bad Request",
    "message": "Failed to convert value of type 'java.lang.String' to required type 'org.crea.w4ag_mock.mocker.TimeFramesEnum'; Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam org.crea.w4ag_mock.mocker.TimeFramesEnum] for value 'baseline'",
    "path": "/mock"
}

I followed the example of creating myself a custom converter and adding it to the registry via the configuration:

package org.crea.w4ag_mock.converter;
import org.apache.commons.lang3.EnumUtils;
import org.apache.commons.lang3.StringUtils;
import org.crea.w4ag_mock.mocker.TimeFramesEnum;
import org.springframework.core.convert.converter.Converter;

public class StringToTimeFramesConverter implements Converter<String, TimeFramesEnum> {
    @Override
    public TimeFramesEnum convert(String source){
        if (StringUtils.isBlank(source)) {
            return null;
        }
        return EnumUtils.getEnum(TimeFramesEnum.class, source.toUpperCase());
    }

}

configuration

package org.crea.w4ag_mock.config;
import org.crea.w4ag_mock.converter.StringToTimeFramesConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class EnumMappingConfig implements WebMvcConfigurer {
    @Override
    public void addFormatters(FormatterRegistry registry){
        registry.addConverter(new StringToTimeFramesConverter());
    }
}

My RestController is:

package org.crea.w4ag_mock;
import org.crea.w4ag_mock.mocker.*;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class Water4AgriFoodMockerApplication {

    public static void main(String[] args) {
        SpringApplication.run(Water4AgriFoodMockerApplication.class, args);

    }

    @GetMapping("mock")
    @ResponseBody
    public ResponseEntity<ModelMocker> getMock(
            @RequestParam(required = true) String idName,
            @RequestParam(required = true) String idConfiguration,
            @RequestParam(required = true) String location,
            @RequestParam(required = true) String startTime,
            @RequestParam(name="timeFrames", required = true) TimeFramesEnum timeFrames,
            @RequestParam(required = true) GcmsEnum gcms,
            @RequestParam(required = true) RcpsEnum rcps,
            @RequestParam(required = true) String idCrop,
            @RequestParam(required = true) String idVariety,
            @RequestParam(required = true) String idRotation
    ){
        ModelMocker modelMocker = ModelMocker.builder()
                .idName(idName)
                .idConfiguration(idConfiguration)
                .location(location)
                .startTime(startTime)
                .timeFrames(timeFrames)
                .gcms(gcms)
                .rcps(rcps)
                .idCrop(idCrop)
                .idVariety(idVariety)
                .idRotation(idRotation)
                .developmentStage(ModelMockerRandomValueGenerator.getDevelopmentStageValue())
                .potentialAboveGroundBiomass(ModelMockerRandomValueGenerator.getPotentialAboveGroundBiomassValue())
                .potentialYield(ModelMockerRandomValueGenerator.getPotentialYieldValue())
                .potentialLAI(ModelMockerRandomValueGenerator.getPotentialLAIValue())
                .waterLimitedAboveGroundBiomass(ModelMockerRandomValueGenerator.getWaterLimitedAboveGroundBiomassValue())
                .waterLimitedYield(ModelMockerRandomValueGenerator.getPotentialYieldValue())
                .waterLimitedLAI(ModelMockerRandomValueGenerator.getWaterLimitedLAIValue())
                .build();
        return ResponseEntity.ok(modelMocker);
    }

}

enter image description here

Gianni Spear
  • 7,033
  • 22
  • 82
  • 131
  • And your controller looks like? What is it you are sending to the controller? – M. Deinum Feb 27 '23 at 15:36
  • M. Deinum I added the controller – Gianni Spear Feb 27 '23 at 15:38
  • But you didn't add what you are sending to the controller. Also when you have such a large list of parameters use an object instead of separate parameters. – M. Deinum Feb 27 '23 at 15:40
  • I am sending vie URL all parameters. I create a class ModelMocker and I produce a mock value for testing. "use an object instead of separate parameters" do you have an example please? thanks in advance – Gianni Spear Feb 27 '23 at 15:43
  • source code from a baeldung example has an additional line in a configuration file `ApplicationConversionService.configure(registry);` [link](https://github.com/eugenp/tutorials/blob/57209b45d2f561d048553e53fa9c411b74c0e321/spring-boot-modules/spring-boot-request-params/src/main/java/com/baeldung/enummapping/config/EnumMappingConfig.java#L14) Maybe adding one could help. – siarhei987 Feb 27 '23 at 16:14
  • You could define a wrapper class containing your enum, converting your json to it and adding the `JsonAlias("baseline")` annotation to `BASELINE`. – dariosicily Feb 27 '23 at 17:48
  • You can just put the object in the method instead of the parameters, Spring will automatically do the binding to object parameters. So instead of the full list of parameters add `@ModelAttribute ModelMocker modelMocker`. – M. Deinum Feb 28 '23 at 07:34

0 Answers0