Automatic spring type conversion -- @ InitBinder and Converter, spring @ initbinder
Spring has two types of converters, one is propertyEditor and the other is Converter. Although all are type conversion, there are still slight differences.
So here is an example to analyze the use cases and differences of the two types of conversions.
In common applications, there should be many such cases. One Field in a po is status, and the table is successful when status = 0, and the table fails when status = 1... although this status can be defined as an Integer type, sometimes a TypeStatus class is defined to indicate this status field for ease of management and more object-oriented. the implementation of this TypeStatus may be as follows. Of course, this is only a demo and should not be taken seriously:
Public class TypeStatus {private Integer value; private String msg; public TypeStatus (Integer value, String msg) {this. value = value; this. msg = msg;} public static TypeStatus toBean (Integer value) {if (value = 0) {return new TypeStatus (0, "successful ");} else if (value = 1) {return new TypeStatus (1, "failed") ;}else {return null ;}public Integer getValue () {return value ;} public String getMsg () {return msg ;}}
Then the problem arises, although the status field becomes more vivid after this encapsulation .. but how does spring convert 0 from the front-end page to a TypeStatus type in controller? Assume that the po containing this status field is as follows:
public class PoDemo { TypeStatus status;}
The controller is as follows:
public class DemoController { public String testEditor(PoDemo po){ return "ok"; }}
From one type to another, type conversion is required. First, let's look at the implementation of the first propertyEditor. Add the following method to controller:
@InitBinder public void initBinder(WebDataBinder binder) { binder.registerCustomEditor(TypeStatus.class, "status", new TypeStatusEditor()); }
The second parameter of the registerCustomEditor method is the field name, which identifies the field name as status. The type conversion will be applied to the attribute of the TypeStatus type. If another field statusToo in our PoDemo is also of the TypeStatus type, this type of conversion will not be applied. if you want to apply this type conversion to all TypeStatus fields, you can set the second parameter to null.
The implementation of TypeStatusEditor is as follows:
public class TypeStatusEditor extends PropertyEditorSupport { @Override public String getAsText() { TypeStatus ts = (TypeStatus) getValue(); return String.valueOf(ts.getValue()); } @Override public void setAsText(String text) throws IllegalArgumentException { TypeStatus ts = TypeStatus.toBean(Integer.parseInt(text)); setValue(ts); } }
The use of PropertyEditor is not discussed here. it can be seen from the code that it is actually a String-to-type process, which is exactly the difference between propertyEditor and Converter. the main application scenarios of PropertyEditor are String-to-type conversion. the get and set methods provided by the Editor can also be seen that they must go through the String. generally, most of the values transmitted on the front-end page are of the String type. In this case, PropertyEditor is not suitable for conversion.
The ProertyEditor is a String-to-type conversion, which is only a special case. When it comes to the most common type-to-type conversion, It is the Converter application.
Or PoDemo and Controller:
public class PoDemo { byte[] img;}
public class DemoController { public String testEditor(PoDemo po){ return "ok"; }}
For example, if we store an image in the database, the database stores the image as blob, And the java class actually stores the image as byte [], then the problem arises again, I uploaded an image at the front end to the Controller as MultipartFile. How does spring convert the MultipartFile to byte [] and automatically encapsulate it into a PoDemo class? In this case, PropertyEditor obviously does not work. This is type-to-type conversion, and only Converter can be used.
The implementation is as follows:
public class MultipartFileToByteArrayEditor implements Converter<CommonsMultipartFile,byte[]> { @Override public byte[] convert(CommonsMultipartFile source) { return source.getBytes(); } }
Then we need to register it in the spring configuration file:
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven><bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <list> <bean class="xx.xx.MultipartFileToByteArrayEditor"/> </list> </property> </bean>
The FormattingConversionServiceFactoryBean provided by the system is used to register our type converter class MultipartFileToByteArrayEditor. You can also use ConversionServiceFactoryBean to register it.
After the configuration is complete, spring can automatically convert the MultipartFile to byte [] and encapsulate it into a PoDemo.
Some people may think that Converter actually contains PropertyEditor. If both types of converters are applicable, what kind of Converter will be used? By default, Spring searches for PropertyEditor and Converter.
Conclusion: PropertyEditor applies to the String type, while Converter applies to the type. PropertyEditor has a higher priority.