Preface
Why type converter in struts2?
:struts2 can only provide automatic conversion for 8 original types in Java and common types such as String and Date.
But this definitely cannot meet our needs if we want to integrate the page data into a javabean. When you go to Action, what Action gets is an object, so this requirement requires us to use a type converter.
Most of the time, using the built-in type converter and OGNL-based type converter provided by the Struts2 framework can meet most type conversion needs; however, there are some special cases where a string of a specified format may need to be converted into a composite object, and a custom type converter is required. For example, if the client sends a string like "jelly|123456" to the server, we need to convert this string into a User type instance, with "jelly" as the user name and "123456" as the user password.
Custom type conversion class
There is a front desk page like this:
<form action="login" method="post"> User: <input type="text" name="userinfo"><br> <input type="submit" value="convert"></form>
The corresponding Action code is:
private User user; // This is a compound type private String tip;public void setUsers(User user){ this.user = user;}public User getUser(){ return user;}We hope that the user enters a string in the foreground page with the format "username|password" and converts the string in the format of "username|password" to the User type through a custom type converter. Let’s talk about how to implement a custom type converter.
Struts2's type converter is actually still based on the OGNL framework. There is a TypeConverter interface in the OGNL project, which is the interface that must be implemented by a custom type converter. The definition code of this interface is as follows:
// OGNL provides public interface TypeConverter{ public Object convertValue(Map context, Object target, Member member, String propertyName, Object value, Class toType);}To implement a type converter, you must implement the TypeConverter above, but the methods in the above interface are too complex, so the OGNL project also provides an implementation class for this interface: DefaultTypeConverter, which usually uses extended this class to implement custom type converters. Implementing a custom type converter requires overriding the convertValue method of the DefaultTypeConverter class.
The following is the conversion class converted to a User class instance:
public class UserConverter extends DefaultTypeConverter{ public Object convertValue(Map context, Object value, Class toType) { if (toType == User.class) { // When you need to convert a string to the User type// The system's request parameter is a string array String[] params = (String[])value; // Create a User instance User user = new User(); // Only process the first array element of the request parameter array, and divide the string into two strings with the '|' symbol String[] userValues = params[0].split("//|"); // Assign a value to the User instance user.setName(userValues[0]); user.setPassword(userValues[1]); return user; } else if (toType == String.class) { // When it is necessary to convert the User type to a string User user = (User)value; return "<" + user.getName() + "|" + user.getPassword() + ">"; } return null; }}The function of the convertValue method is very simple. This method is responsible for completing the type conversion, but this conversion is bidirectional. The target type is judged based on the parameter toType, and then we can implement the conversion logic in two directions.
Register a type converter
Having a type converter is not enough, because the Struts2 framework does not know when to use these type converters, so the type converter must be registered in the web application, so the Struts2 framework can use this type converter normally.
Struts2 mainly supports the following two ways to register type converters:
Let’s talk about the above two methods of registering type converters.
Local type converter
Struts2 allows developers to specify configuration information for type conversion through local type conversion files. A type conversion file is an ordinary Properties (*.properties) file. The file name of the local type conversion file should be in the form ActionName-conversion.properties, where ActionName is the Action name that needs to be converted to the file with this type, and the subsequent -conversion.properties string is a fixed part. The type conversion file should be placed in the same location as the Action class file.
After talking about the local type conversion file, let’s continue to talk about the registered local type converter. To register a local type converter, you only need to add the following line of configuration to the local type converter file:
<propName>=<ConverterClass>
Replace the above <propName> with the property that needs to be type-converted, and replace <ConverterClass> with the implementation class of the type converter. For the UserConverter class implemented above, it is necessary to configure it in the local type conversion file as follows:
# To specify the user attribute, you need to use the UserConverter class to complete the type conversion user=com.jellythink.practise.UserConverter
Global Type Converter
The limitations of local type converters are too obvious, and they can only work on specified Actions and specified properties. However, if multiple Actions in the application contain attributes of User type, or one Action contains attributes of multiple User type, it would be more appropriate to use a global type converter.
The global type converter does not work on the specified properties of the specified Action, but on the specified type. For example, it works for all properties of type com.jellythink.practise.User.
Registering a global type converter should provide an xwork-conversion.properties file, which is the global type converter file. You need to directly place the file under the WEB-INF/classes path of the web application.
The global type conversion file content consists of multiple <propType>=<ConvertClass> items. Replace propType with the type that needs to be type converted, and replace ConvertClass with the implementation class of the type converter. For the UserConverter class implemented above, it is necessary to configure it in the global type conversion file as follows:
com.jellythink.practise.User=com.jellythink.practise.UserConverter
"Local" vs "Global"
Local type conversion can only convert the specified attribute of the specified Action. Regardless of whether the attribute of the Action is an array or a collection type, the converter's conversion method only converts the attribute once. If an Action has a List<User> property user, the local type converter will call the convertValue() method only once, which converts the users request parameter to a List<User> collection object at one time.
The global type converter will convert all Action specific types. If an Action's attribute is an array or collection type, and the array or collection element is the method that requires the converter to convert, then the global type converter will not convert the entire set attribute, but will convert each element of the set attribute. That is, when the attribute is an array or collection, the array or collection contains several elements of the type, then the convertValue() method will be called several times.
After getting familiar with the difference between the two, I will pay more attention to it in my future work; especially the difference between array and set elements when converting them.
Custom type converter based on Struts2
The above introduces the conversion direction by inheriting the DefaultTypeConverter class, in a convertValue method, the conversion direction is judged by judging the toType parameter, and then the conversion logic for different conversion directions is implemented separately. In the Struts2 framework, in order to simplify the implementation of type converters, a StrutsTypeConverter abstract class is specially provided, which is a subclass of the DefaultTypeConverter class. It has implemented the convertValue method of the DefaultTypeConverter class; when implementing this method, it turns the conversion in two different directions by judging the toType parameter in the convertValue method into calling the following two different methods:
What we need to do is to inherit the StrutsTypeConverter abstract class and implement the two abstract methods: convertFromString and convertToString.
The modified code is as follows:
public class UserConverter extends StrutsTypeConverter{ public Object convertFromString(Map context, String[] values, Class toClass) { User user = new User(); String[] userValues = values[0].split("//|"); user.setName(userValues[0]); user.setPassword(userValues[1]); return user; } public String convertToString(Map context, Object o) { // When it is necessary to convert the User type to a string User user = (User)o; return "<" + user.getName() + "|" + user.getPassword() + ">"; }}Summarize
This article summarizes the custom type converter in Struts2 in detail, and the overall idea is as follows:
Just a few steps to get the custom type converter done.
Okay, the above is the entire content of this article. I hope that the content of this article has certain reference value for everyone's study or work. If you have any questions, you can leave a message to communicate. Thank you for your support to Wulin.com.