Beautils tool class implementation principle, beautils tool class implementation
For more information about the introspection and reflection mechanisms, see this blog [not finished yet, in the draft ].
Let's talk about bean attributes. bean attributes refer to the names after the get/set method, rather than the attributes of the class:
For example:
Private String username; // The bean attribute does not refer to the public String getUsername () {//, but the return username following get ;} public void setUsername (String username) {// The Username after set is the bean attribute this. username = username ;}
Beanutils uses the introspector mechanism at the underlying layer, while its implementation relies on java reflection. 1. directly use reflection to implement Beanutils functions:
Package online. msym. test; import java. lang. reflect. invocationTargetException; import java. lang. reflect. method; import java. util. hashMap; import java. util. map; import java. util. set; import org. junit. test; import online. msym. bean. user; public class Demo {// use reflection to encapsulate @ Test public void fun1 () throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {// 1. creates a Map set that imitates the request. getParame Map <String, String []> map = new HashMap <String, String []> (); map. put ("username", new String [] {"tom"}); // Note: Here I put a lower-case username, although the latter is using signorecase (), but it is still inappropriate, map. put ("password", new String [] {"123"}); // This error is caused by Boyou [quit (zh)] [This word cannot be read... .
// 2. Create a User object (the get/set method and the toString method are provided in the User class)
User user = new User ();
// 3. encapsulate the value corresponding to the key in the map set with the same name as the bean attribute in the user into the bean attribute.
// 3.1 obtain the set of all keys in the map
Set <String> keys = map. keySet ();
// 3.2 obtain all methods in the User class
Method [] MS = user. getClass (). getDeclaredMethods ();
// 3. 3. Determine whether all method names are equal to the value of "set" + key (Case Insensitive)
For (String key: keys ){
String setMethodName = "set" + key; // at this time, the first setMethodName = setusername to be traversed, so the following equals () must be case insensitive.
// 3.4 traverse all ms and get the method name
For (Method m: ms ){
String methodName = m. getName ();
If (setMethodName. inclusignorecase (methodName) {// here, define signorecase ()
//. Call the invoke method using the method object to assign values to the value corresponding to the key
M. invoke (user, map. get (key) [0]); // user. setXxx (map. get (xxx ))
}
}
}
// 4. Output
System. out. println (user );
}
}
2. Using introspector:
Package online. msym. test; import java. beans. beanInfo; import java. beans. introspectionException; import java. beans. introspector; import java. beans. propertyDescriptor; import java. lang. reflect. invocationTargetException; import java. lang. reflect. method; import java. util. hashMap; import java. util. map; import java. util. set; import org. junit. test; import online. msym. bean. user; public class Demo {// use introspection to encapsulate Request Parameters @ T Est public void fun2 () throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {// 1. creates a Map set that imitates the request. map <String, String []> map = new HashMap <String, String []> (); map. put ("username", new String [] {"tom"}); map. put ("password", new String [] {"123"}); // 2. create a User Object User user = new User (); // 3. get a BeanInfo object BeanInfo. Bif = Introspector. getBeanInfo (User. class); // 4. get all the property descriptors PropertyDescriptor [] PPS = bif. getPropertyDescriptors (); // 5. get the read/write Method for (PropertyDescriptor pd: pds) {Method writeMethod = pd. getWriteMethod (); // 6. obtain the method name if (writeMethod! = Null) {// System. out. println (pd. getName (); // get the bean property name // System. out. println (writeMethod. getName (); // get all the set method names String name = pd. getName (); writeMethod. invoke (user, map. get (name) [0]) ;}} System. out. println (user );}}
This Beanutils tool class can encapsulate most bean data, but it cannot be encapsulated, such as the Date object. When there is a Date bean, a custom type converter is required.
Form:
The following is a custom type converter: (convert the birthday text in the form to the Date type and encapsulate it in javabean)
Package online. msym. utils; import java. text. parseException; import java. text. simpleDateFormat; import java. util. date; import org. apache. commons. beanutils. converter; public class MyDateConverter implements Converter {// This method is the real type conversion method public Object convert (Class type, Object value) {// System. out. println (type); // class java. util. date // System. out. println (value); // 2018/11/11 String s = (String) value; SimpleDateFormat sdf = new SimpleDateFormat ("yyyy/MM/dd"); Date date = null; try {date = sdf. parse (s);} catch (ParseException e) {e. printStackTrace ();} return date ;}}
Write the following in the dopost () method of the Servlet that encapsulates the javabean:
Public void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {User user = new User (); try {// register ConvertUtils for a custom type converter. register (new MyDateConverter (), java. util. date. class); BeanUtils. populate (user, request. getParameterMap ();} catch (IllegalAccessException e) {e. printStackTrace ();} catch (InvocationTargetException e) {e. printStackTrace ();} System. out. println (user); // the data entered in the form is printed here, and the input Date string is converted to the Date type}
Print Output: (The toString () method is rewritten in the User class)