How do I create a custom type converter for a boolean parameter in a GET request?
For example, I want the allowed values in the GET request to be "oui" and "non" instead of "true" and "false". I followed the Spring documentation on how to do this, and tried the following:
@RestController
public class ExampleController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor("oui", "non", true));
}
@GetMapping("/e")
ResponseEntity<String> showRequestParam(@RequestParam boolean flag) {
return new ResponseEntity<>(String.valueOf(flag), HttpStatus.OK);
}
}
I also tried this:
@RestController
public class DemoController {
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addCustomFormatter(new Formatter<Boolean>() {
@Override
public Boolean parse(String text, Locale locale) throws ParseException {
if ("oui".equalsIgnoreCase(text)) return true;
if ("non".equalsIgnoreCase(text)) return false;
throw new ParseException("Invalid boolean parameter value '" text "'; please specify oui or non", 0);
}
@Override
public String print(Boolean object, Locale locale) {
return String.valueOf(object);
}
}, Boolean.class);
}
@GetMapping("/r")
ResponseEntity<String> showRequestParam(@RequestParam(value = "param") boolean param) {
return new ResponseEntity<>(String.valueOf(param), HttpStatus.OK);
}
}
Neither of these worked. When supplying the value "oui", I got an HTTP 400 response with the following message:
Failed to convert value of type 'java.lang.String' to required type 'boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [oui]"
Update:
I've also now tried using a Converter:
@Component
public class BooleanConverter implements Converter<String, Boolean> {
@Override
public Boolean convert(String text) {
if ("oui".equalsIgnoreCase(text)) return true;
if ("non".equalsIgnoreCase(text)) return false;
throw new IllegalArgumentException("Invalid boolean parameter value '" text "'; please specify oui or non");
}
}
This "kind of" works, in that it now accepts "oui" and "non", but it does so in addition to "true" and "false". How can I get it to accept "oui" and "non" instead of "true" and "false"?
CodePudding user response:
In your first case, your requestParam is a boolean but you bind a Boolean.
I've tried with this code
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor("oui", "non", true));
}
@GetMapping("/e")
ResponseEntity<String> showRequestParam(@RequestParam(value="flag") Boolean flag) {
return new ResponseEntity<>(String.valueOf(flag), HttpStatus.OK);
}
And it's print
true
when I call localhost:8080/e?flag=oui
CodePudding user response:
can't you map it to an enum?
enum BooleanInput {
oui(true),
non(false);
private boolean value;
BooleanInput(boolean value) {
this.value = value;
}
Boolean value() {
return this.value;
}
}
and in the controller,
@GetMapping("/e")
ResponseEntity<String> showRequestParam(@RequestParam BooleanInput flag) {
return new ResponseEntity<>(flag.value(), HttpStatus.OK);
}