在控制器中映射之前转换特定字段
Convert specific fields before mapping in controller
我需要在映射到 Dto 之前转换两个特定字段 class。
我从表格中获得的数据:
userName: test
password: 123
active: N
enabled: N
external: N
id: -1
Dto class:
@Getter @Setter
public class UserDto {
protected Integer id;
protected String userName;
protected String password;
protected boolean active = false;
protected boolean enabled = true;
protected String external;
}
字段 active
和 enabled
是布尔类型,但从表单中我得到“Y”或“N”字符串值。原因是,我得到一个错误 Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'active'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [N]
我读过有关 Сonverter 和 PropertyEditors 的信息,但我不确定它们是否适合我,以及我如何才能将它仅应用于 2 个特定字段。
控制器:
@RequestMapping(value = "/user/save",method = RequestMethod.POST)
public ResponseEntity<String> saveUser(@ModelAttribute UserDto userDto, BindingResult bindingResultM, HttpServletRequest req) {
List<FieldError> errors = bindingResultM.getFieldErrors();
for (FieldError error : errors) {
log.error("bindingResultM: " + error.getObjectName() + " - " + error.getDefaultMessage());
}
try {
userService.saveUserDto(userDto);
return new ResponseEntity<>("OK", HttpStatus.OK);
} catch (Exception e){
throw new ResponseException(e.getMessage(), HttpStatus.METHOD_FAILURE);
}
}
在您的 DTO 上,您可以使用 :
注释您的布尔字段
@JsonDeserialize(
using = BooleanDeserializer.class
)
protected boolean enabled;
并创建解串器:
public class BooleanDeserializer extends JsonDeserializer<Boolean> {
public Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String booleanValue = StringUtils.trimToEmpty(jsonParser.getText().trim());
return BooleanUtils.toBoolean(booleanValue, "Y", "N");
}
}
因为你说你需要从表单中获取数据来填充UserDTO对象,这是一个将String类型转换为其他类型的过程.
因此,您需要使用“org.springframework.core.convert.converter.Converter”、“java.beans.PropertyEditor” ,或“org.springframework.format.Formatter”。这三个都可以完成将 String 类型转换为其他类型或将其他类型转换为 String 类型的工作。
但是PropertyEditor太复杂,所以一般我们都是用Converter或者Formatter,这两个可以在同一个方法里设置“default void addFormatters(FormatterRegistry registry) {}”的“WebMvcConfigurer”接口。
但这是针对整个应用程序的,您仅希望翻译发生在“active”和“enabled” " UserDTO 的字段。
然后你需要使用“org.springframework.web.bind.annotation.InitBinder”,它可以在控制器内部定义用于具体方法参数。 “@InitBinder”的“userDTO”表示数据绑定器仅用于“userDTO[=55=” ]" 此控制器内的 方法参数 。 (这个名字是case-sensitive,所以如果你在方法中使用“userDto”,你需要在@InitBinder注解中把它改成userDto。)
在此方法中,您可以 仅针对“active”和“enabled”字段指定 Formatter,通过使用此方法:
public void addCustomFormatter(Formatter<?> formatter, String... fields){}
当然你可以为这两个字段指定Converter,但是在“WebDataBinder”中没有直接方法 class。因此,eaiser 使用 Formatter。
@InitBinder("userDTO")
public void forUserDto(WebDataBinder binder) {
binder.addCustomFormatter(new BooleanFormatter(), "active", "enabled");
}
这是 BooleanFormatter class:
public class BooleanFormatter implements Formatter<Boolean>{
@Override
public String print(Boolean object, Locale locale) {
if (object) {
return "Y";
}
return "N";
}
@Override
public Boolean parse(String text, Locale locale) throws ParseException {
if (text.equals("Y")) {
return true;
}
return false;
}
}
我需要在映射到 Dto 之前转换两个特定字段 class。 我从表格中获得的数据:
userName: test
password: 123
active: N
enabled: N
external: N
id: -1
Dto class:
@Getter @Setter
public class UserDto {
protected Integer id;
protected String userName;
protected String password;
protected boolean active = false;
protected boolean enabled = true;
protected String external;
}
字段 active
和 enabled
是布尔类型,但从表单中我得到“Y”或“N”字符串值。原因是,我得到一个错误 Failed to convert property value of type 'java.lang.String' to required type 'boolean' for property 'active'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [N]
我读过有关 Сonverter
控制器:
@RequestMapping(value = "/user/save",method = RequestMethod.POST)
public ResponseEntity<String> saveUser(@ModelAttribute UserDto userDto, BindingResult bindingResultM, HttpServletRequest req) {
List<FieldError> errors = bindingResultM.getFieldErrors();
for (FieldError error : errors) {
log.error("bindingResultM: " + error.getObjectName() + " - " + error.getDefaultMessage());
}
try {
userService.saveUserDto(userDto);
return new ResponseEntity<>("OK", HttpStatus.OK);
} catch (Exception e){
throw new ResponseException(e.getMessage(), HttpStatus.METHOD_FAILURE);
}
}
在您的 DTO 上,您可以使用 :
注释您的布尔字段 @JsonDeserialize(
using = BooleanDeserializer.class
)
protected boolean enabled;
并创建解串器:
public class BooleanDeserializer extends JsonDeserializer<Boolean> {
public Boolean deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
String booleanValue = StringUtils.trimToEmpty(jsonParser.getText().trim());
return BooleanUtils.toBoolean(booleanValue, "Y", "N");
}
}
因为你说你需要从表单中获取数据来填充UserDTO对象,这是一个将String类型转换为其他类型的过程.
因此,您需要使用“org.springframework.core.convert.converter.Converter”、“java.beans.PropertyEditor” ,或“org.springframework.format.Formatter”。这三个都可以完成将 String 类型转换为其他类型或将其他类型转换为 String 类型的工作。
但是PropertyEditor太复杂,所以一般我们都是用Converter或者Formatter,这两个可以在同一个方法里设置“default void addFormatters(FormatterRegistry registry) {}”的“WebMvcConfigurer”接口。
但这是针对整个应用程序的,您仅希望翻译发生在“active”和“enabled” " UserDTO 的字段。
然后你需要使用“org.springframework.web.bind.annotation.InitBinder”,它可以在控制器内部定义用于具体方法参数。 “@InitBinder”的“userDTO”表示数据绑定器仅用于“userDTO[=55=” ]" 此控制器内的 方法参数 。 (这个名字是case-sensitive,所以如果你在方法中使用“userDto”,你需要在@InitBinder注解中把它改成userDto。) 在此方法中,您可以 仅针对“active”和“enabled”字段指定 Formatter,通过使用此方法:
public void addCustomFormatter(Formatter<?> formatter, String... fields){}
当然你可以为这两个字段指定Converter,但是在“WebDataBinder”中没有直接方法 class。因此,eaiser 使用 Formatter。
@InitBinder("userDTO")
public void forUserDto(WebDataBinder binder) {
binder.addCustomFormatter(new BooleanFormatter(), "active", "enabled");
}
这是 BooleanFormatter class:
public class BooleanFormatter implements Formatter<Boolean>{
@Override
public String print(Boolean object, Locale locale) {
if (object) {
return "Y";
}
return "N";
}
@Override
public Boolean parse(String text, Locale locale) throws ParseException {
if (text.equals("Y")) {
return true;
}
return false;
}
}