英文:
How to limit the usage of types converter to a specific controller in Spring MVC?
问题
在处理Spring MVC中的请求参数、路径变量或表单字段时,我必须处理typeMismatch错误。它们会在验证之前发生,有时可能会令人恼火。假设我有一个用标准验证约束注释的Integer参数,类似于:@Min(value = 0, message = "只能接受非负整数值")。那么,我可以创建一个简单的String到Integer转换器,以抑制NumberFormatException,同时将所有无法解析的String值设置为-1,以便它们可以进一步由上述的@Min约束无效化:
@Component
final class StringToInteger implements Converter<String, Integer> {
    public Integer convert(String source) {
		try{
			return Integer.valueOf(source);
		} catch (NumberFormatException ex) {
			return -1;
		}
    }
}
在使用Spring Boot时,@Component注解会自动在整个应用程序上下文中启动此转换器,但如果我想将其限制仅用于特定的Controller甚至目标请求,应该采用什么最简单的方法呢?
英文:
When dealing with request parameters, path variables or form fields in Spring MVC I have to handle typeMismatch errors. They occur just before the validation even begins, which can be irritating at times. Let's say I have an Integer parameter annotated with standard validation constraint, sort of: @Min(value = 0, message = "Only non-negative integer values can be accepted"). Then, I could create a simple String to Integer converter to suppresses NumberFormatException while setting all unparsable String values to -1, so that they could be further invalidated by aforementioned @Min constraint:
@Component
final class StringToInteger implements Converter<String, Integer> {
    public Integer convert(String source) {
		try{
			return Integer.valueOf(source);
		} catch (NumberFormatException ex) {
			return -1;
		}
    }
}
When using with Spring Boot, the @Component annotation automatically gets this converter up and running within the entire application context, but what if I want to limit its usage only to a specific Controller or even a target request? What is the simplest way to do that?
答案1
得分: 1
您可以使用DataBinder。您在控制器内部声明它。
@InitBinder
public void customizeBinding(DataBinder binder) {
    DefaultConversionService conversionService = new DefaultConversionService();
    conversionService.addConverter(new StringToInteger());
    binder.setConversionService(conversionService);
}
编辑: 您可以使用格式化器。
@InitBinder
public void customizeBinding(DataBinder binder) {
    binder.addCustomFormatter(new StringToInteger());
}
class StringToInteger implements Formatter<Integer> {
    @Override
    public Integer parse(String s, Locale locale) throws ParseException {
        try {
            return Integer.valueOf(s);
        } catch (NumberFormatException ex) {
            return -1;
        }
    }
    @Override
    public String print(Integer i, Locale locale) {
        return Objects.toString(i);
    }
}
英文:
You can use DataBinder. You declare it inside your controller.
	@InitBinder
	public void customizeBinding (DataBinder binder) {
    	DefaultConversionService conversionService = new DefaultConversionService();
	    conversionService.addConverter(new StringToInteger());
		binder.setConversionService(conversionService);
    }
EDIT: you can use a formatter instead.
@InitBinder
public void customizeBinding (DataBinder binder) {
	binder.addCustomFormatter(new StringToInteger());
}
class StringToInteger implements Formatter<Integer> {
	@Override
	public Integer parse(String s, Locale locale) throws ParseException {
		try {
			return Integer.valueOf(s);
		}
		catch (NumberFormatException ex) {
			return -1;
		}
	}
	@Override
	public String print(Integer i, Locale locale) {
		return Objects.toString(i);
    }
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论