In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-20 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
In this issue, the editor will bring you about how to automatically assemble objects and forms in Java. The article is rich in content and analyzes and describes for you from a professional point of view. I hope you can get something after reading this article.
Nowadays, many Web frameworks have realized the function of automatic assembly of Form form fields and Java object attributes, which is indeed very useful. If there is no such function, there will be calls of request.getParameter () series methods and type conversion methods everywhere. The amount of repeated code is large, easy to make mistakes, and at the same time is not beautiful, affecting the appearance of the city.
The question now is, how do these frameworks automatically assemble? How can we implement it ourselves if we don't use these frameworks? Especially for those pure JSP/Servlet applications, it would be nice to have automatic assembly function! Fully aware of your expectations, we have decided to explain the principle and implementation of automatic assembly.
In fact, the implementation principle is relatively simple, which is mainly composed of the following three steps:
Get the name-value mapping of all form fields of the submitted Form through request.getParameterMap (), where the name and value are of string type.
Use the java.beans.PropertyDescriptor object to get the names and types of all properties of Java Bean.
Match the name of the form field with the name of the Bean property one by one, and when a matching property is found, call the setter method of Bean to set the value of the form field to the Bean property. Of course, because the value of the form field is always of string type, which is likely to be inconsistent with the type of the Bean property, the necessary type conversions are required before setting the Bean property.
I don't know if you fully understand the three principles expressed above. It doesn't matter. Let's take a look at the actual effect through a specific example of form submission. First, take a look at the form page to be submitted and its code:
First Name:
Last Name:
Birthday:
Gender: male
Working age:-Please choose-three years, five years, ten years, twenty years.
Interest: swimming, playing ball, playing chess, playing mahjong, reading
As can be seen from the figure above, there are a total of six form fields with names-values as follows: {"firstName"-"ugly", "lastName"-"monster", "birthday"-"1978-11-03", "gender"-"female", "working-Age"-"5", "its"-"1L 2Q 5"}. This form needs to be submitted to checkbean.action for processing (please note: do not think it is struts2 as soon as you see .aciton. Not all those who ride a white horse are Tang monks! Let's take a look at the processing code of CheckBean Action and the definition of Bean
Import java.util.HashMap; import java.util.Map; import vo.Persion; import com.bruce.mvc.ActionSupport; public class CheckBean extends ActionSupport {@ Override public String execute () {/ / if the name of the form element is inconsistent with the Form Bean attribute name, use keyMap to map / / key: form element name, value: Form Bean attribute name Map keyMap = new HashMap () KeyMap.put ("working-Age", "workingAge"); keyMap.put ("its", "interest") / * automatic assembly method 1. Create FormBean using form elements / / if the name of the form element is exactly the same as the FormBean attribute name, you do not need to use keyMap to map Persion p = createFormBean (Persion.class, keyMap) / * automatic assembly method 2 * / / first create a FormBean object, and then populate its properties Persion p2 = new Persion (); fillFormBeanProperties (p2, keyMap); / / you can get all the attribute values of FormBean / / Map result = BeanHelper.getProperties (p) / / set p to the request property, and finally display setRequestAttribute ("persion", p); return SUCCESS;}} import java.util.Date; import java.util.List; public class Persion {private String firstName; private String lastName; private Date birthday; private boolean gender; private int workingAge; private int [] interest on the result page Private List photos; / / getter and setter methods / / (abbreviated). }
As you can see from the code of CheckBean, it automatically assembles Persion through the createFormBean () or fillFormBeanProperties () methods. The difference between them is that the former directly creates a new Persion object, while the latter populates the properties of the original Persion object. Note that if the name of the form field is inconsistent with the attribute name corresponding to Persion, it is mapped with keyMap. For example, the form field "working-Age" corresponds to the workingAge attribute of Persion, but their names are different, so map. In addition, Persion has a photos attribute that our form field does not have, which is ignored when auto-assembling. Finally, take a look at the output page and its code:
Persion Attributs Name Brithday Gender Working Age Interest Photos
As you can see from the above example, we have gained great convenience by automatically assembling Bean. Now let's start with createFormBean () and fillFormBeanProperties () and gradually unravel the mystery of auto-assembly. Let's take a look at the definitions of the following two classes and their methods:
Package com.bruce.mvc; import com.bruce.util.http.HttpHelper; / * {@ link Action} object public base class * / public class ActionSupport implements Action {private ServletContext servletContext; private HttpServletRequest request; private HttpServletResponse response; private HttpSession session; / * default {@ link Action} entry method (returns {@ link Action#SUCCESS}) * / public String execute () {return SUCCESS } / * * create a FormBean using form elements (the name of the form element is exactly the same as the FormBean attribute name) * / public final T createFormBean (Class clazz) {return HttpHelper.createFormBean (request, clazz) } / * * create FormBean using form elements (use keyMap to map FormBean attributes that do not correspond to the name of the form element) * / public final T createFormBean (Class clazz, Map keyMap) {return HttpHelper.createFormBean (request, clazz, keyMap) } / * * populate FormBean with form elements (the name of the form element is exactly the same as the FormBean attribute name) * / public final void fillFormBeanProperties (T bean) {HttpHelper.fillFormBeanProperties (request, bean) } / * * populate FormBean with form elements (use keyMap to map FormBean attributes that do not correspond to form element names) * / public final void fillFormBeanProperties (T bean, Map keyMap) {HttpHelper.fillFormBeanProperties (request, bean, keyMap);} / other methods / / (omitted). No, no, no. } package com.bruce.util.http; import com.bruce.util.BeanHelper; / * * HTTP help class * / public class HttpHelper {/ * * create a FormBean using form elements (the name of the form element is exactly the same as the FormBean attribute name) * / public final static T createFormBean (HttpServletRequest request, Class clazz) {return createFormBean (request, clazz, null) } / * * create FormBean using form elements (use keyMap to map FormBean attributes that do not correspond to form element names) * / public final static T createFormBean (HttpServletRequest request, Class clazz, Map keyMap) {Map properties = getParamMap (request); return BeanHelper.createBean (clazz, properties, keyMap) } / * * populate FormBean with form elements (the name of the form element is exactly the same as the FormBean attribute name) * / public final static void fillFormBeanProperties (HttpServletRequest request, T bean) {fillFormBeanProperties (request, bean, null) } / * * populate FormBean with form elements (use keyMap to map FormBean attributes that do not correspond to form element names) * / public final static void fillFormBeanProperties (HttpServletRequest request, T bean, Map keyMap) {Map properties = getParamMap (request); BeanHelper.setProperties (bean, properties, keyMap) } / * * get all parameter names and values of {@ link HttpServletRequest} * / public final static Map getParamMap (HttpServletRequest request) {return request.getParameterMap ();} / other methods / / (abbreviated). }
Haha, as you can see, we detour for such a long time, but the ActionSupport class and the HttpHelper class do not do much. They just get the request parameter Map and pass it to the createBean () and setProperties () methods of the BeanHelper class for assembly. The actual assembly work is BeanHelper. Here is an analysis of why it is so circuitous. In fact, the code is extracted from the "Portal Web Development Framework" written by us. In a word, it is written so circuitously because of the needs of the framework, not intentionally. By the way advertisement: "Portal Web Development Framework" is a set of fully functional Web server development framework, built-in MVC Web infrastructure, support for extensible data access interface (has built-in Hibernate, MyBaits and JDBC support), integrated interceptor, internationalization, file upload and download and caching and other basic Web services, based on pure Jsp/Servlet API implementation, very easy to learn and use. It is especially suitable for those who want to use pure Jsp/Servlet API for development or feel tedious and helpless about the complexity of mainstream frameworks such as SSH. The framework has been tested by many commercial projects and is not written for fun. If you are interested, we will find another opportunity to open a special post to introduce this framework in detail.
Without going too far, let's get back to the point, let's take a look at how BeanHelper's assembly tooling is implemented:
/ * * Java Bean help class, perform get / set related operations of the Java Bean attribute * / public class BeanHelper {/ * * create a specified type of Java Bean, and set the related attribute * * @ param clazz: Bean type * @ param properties: attribute name / value mapping
* where the name is {@ link String} type, which may or may not be consistent with the attribute name all the time
* attribute values may be of the following 3 types:
* 1) actual type of attribute: assign a value to the attribute directly
* 2) {@ link String} type: perform automatic type conversion before assigning values to the attribute
* 3) {@ link String} [] Type: perform automatic type conversion before assigning values to the attribute
* @ param keyMap: properties.key / Bean attribute name mapping. When the key of properties does not correspond to the attribute name, * associate them with keyMap * @ return generated Bean instance * / public static final B createBean (Class clazz, Map properties, Map keyMap) {B bean = null Try {/ / create Bean instance bean = clazz.newInstance (); / / set Bean property setProperties (bean, properties, keyMap);} catch (Exception e) {throw new RuntimeException (e);} return bean } public static final B createBean (Class clazz, Map properties) {return createBean (clazz, properties, null);} / * * set the property of Java Bean * * @ param bean: Bean instance * @ param properties: attribute name / value mapping
* where the name is {@ link String} type, which may or may not be consistent with the attribute name all the time
* attribute values may be of the following 3 types:
* 1) actual type of attribute: assign a value to the attribute directly
* 2) {@ link String} type: perform automatic type conversion before assigning values to the attribute
* 3) {@ link String} [] Type: perform automatic type conversion before assigning values to the attribute
* @ param keyMap: properties.key / Bean attribute name mapping. When the key of properties does not correspond to the attribute name, * associate them with keyMap * / public static final void setProperties (Object bean, Map properties, Map keyMap) {/ / get all Bean attributes Map pps = getPropDescMap (bean.getClass ()) Set set = properties.entrySet (); / / set each attribute value for (Map.Entry o: set) of Bean based on the attribute name {String name = null; / / attribute name String key = o.getKey () If (keyMap! = null) name = keyMap.get (key); if (name = = null) name = key; T value = o.getValue (); PropertyDescriptor pd = pps.get (name) / / PropertyDescriptor if (pd! = null & & value! = null) / / set the specified attribute value setProperty (bean, pd, value);}} public static final void setProperties (Object bean, Map properties) {setProperties (bean, properties, null) } / / set the specified property value private static final boolean setProperty (Object bean, PropertyDescriptor pd, T value) {/ / get the setter method Method method = pd.getWriteMethod (); / / only handle the instance setter method if of public (method! = null & & isPublicInstanceMethod (method)) {method.setAccessible (true) Class clazz = pd.getPropertyType (); / / set specific attribute values setProperty (bean, value, method, clazz); return true;} return false } / / set specific attribute values private static void setProperty (Object bean, T value, Method method, Class clazz) {Object param = null; Class valueType = value.getClass (); Class valueComType = valueType.getComponentType (); Class clazzComType = clazz.getComponentType () / / check whether type conversion is required for if (! clazz.isAssignableFrom (valueType) & & (valueType.equals (String.class)) | (valueType.isArray () & & valueComType.equals (String.class) ) & ((GeneralHelper.isSimpleType (clazz) | | (clazz.isArray () & & GeneralHelper.isSimpleType (clazzComType)) / / converted to the genus of the target type Property value param = parseParameter (clazz Value) Else param = value; / / Survey setter method sets the attribute value invokeMethod (bean, method, param);} / / performs type conversion (no explanation, see the officials refer to ^ _ ^) private static final Object parseParameter (Class clazz, T obj) {Object param = null Class valueType = obj.getClass (); if (clazz.isArray ()) {String [] value = null; if (valueType.isArray ()) value = (String []) obj; else {String str = (String) obj StringTokenizer st = new StringTokenizer (str, ",;\ t\ n\ r\ f"); value = new String [st.countTokens ()]; for (int I = 0; st.hasMoreTokens (); iTunes +) value [I] = st.nextToken () } int length = value.length; Class type = clazz.getComponentType (); param = Array.newInstance (type, length); for (int I = 0; I
< length; i++) { String v = value[i]; Object p = GeneralHelper.str2Object(type, v); Array.set(param, i, p); } } else { String value = null; if(valueType.isArray()) { String[] array = (String[])obj; if(array.length >0) value = array [0];} else value = (String) obj; param = GeneralHelper.str2Object (clazz, value);} return param;} / / other methods / /. } public class GeneralHelper {/ * * Collection of simple data types * / public static final Set > (18); static {SMIPLE_CLASS_SET.add (int.class); SMIPLE_CLASS_SET.add (long.class); SMIPLE_CLASS_SET.add (float.class); SMIPLE_CLASS_SET.add (double.class); SMIPLE_CLASS_SET.add (byte.class) SMIPLE_CLASS_SET.add (char.class); SMIPLE_CLASS_SET.add (short.class); SMIPLE_CLASS_SET.add (boolean.class); SMIPLE_CLASS_SET.add (Integer.class); SMIPLE_CLASS_SET.add (Long.class); SMIPLE_CLASS_SET.add (Float.class); SMIPLE_CLASS_SET.add (Double.class) SMIPLE_CLASS_SET.add (Byte.class); SMIPLE_CLASS_SET.add (Character.class); SMIPLE_CLASS_SET.add (Short.class); SMIPLE_CLASS_SET.add (Boolean.class); SMIPLE_CLASS_SET.add (String.class); SMIPLE_CLASS_SET.add (Date.class) } / * * check whether clazz is a simple data type * / public final static boolean isSimpleType (Class clazz) {return SMIPLE_CLASS_SET.contains (clazz) } / * * String-> Any, if handler is null, convert the string to 8 basic data types, their wrapper classes, {@ link Date} or {@ link String} * if handler is not null, handler performs conversion * * @ param type: {@ link Class} object of target type * @ param v: string to be converted * @ param handler: type conversion processor * @ return: conversion result Return null * @ throws if the conversion is not successful: if the target type does not support throwing {@ link IllegalArgumentException} * * / @ SuppressWarnings ("unchecked") public static final T str2Object (Class type, String v, TypeHandler handler) {Object param = null If (handler! = null) return handler.handle (v); if (type = = String.class) param = safeTrimString (v); else if (type = = int.class) param = str2Int_0 (v); else if (type = = long.class) param = str2Long_0 (v) Else if (type = = byte.class) param = str2Byte_0 (v); else if (type = = char.class) param = str2Char_0 (v); else if (type = = float.class) param = str2Float_0 (v); else if (type = = double.class) param = str2Double_0 (v) Else if (type = = short.class) param = str2Short_0 (v); else if (type = = boolean.class) param = str2Boolean_False (v); else if (type = = Integer.class) param = str2Int (v); else if (type = = Long.class) param = str2Long (v) Else if (type = = Byte.class) param = str2Byte (v); else if (type = = Character.class) param = str2Char (v); else if (type = = Float.class) param = str2Float (v); else if (type = = Double.class) param = str2Double (v) Else if (type = = Short.class) param = str2Short (v); else if (type = = Boolean.class) param = str2Boolean (v); else if (Date.class.isAssignableFrom (type)) param = str2Date (v); else throw new IllegalArgumentException (String.format ("object type'% s' not valid", type)) Return (T) param;} public static final T str2Object (Class type, String v) {return str2Object (type, v, null);} / other methods / / (omitted). }
As can be seen from the above code, BeanHelper supports the automatic assembly of eight simple data types and their wrapper classes, String and Date types, and their array types. Finally, it is emphasized that BeanHelper and GeneralHelper are actually two very versatile classes, and their purpose is not only to assist Form form fields to automatically assemble Bean. Here are some examples to help you learn more about how to use BeanHelper:
Package test; import java.beans.IntrospectionException; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; import com.bruce.util.BeanHelper; import com.bruce.util.GeneralHelper; @ SuppressWarnings ("unused") public class TestBeanHelper extends Object {public static void main (String [] args) throws Exception {test (); testStr2Object () Test_setProperty (); test_setProperties_1 (); test_setProperties_2 ();} private static void test () {/ / System.out.println (GeneralHelper.str2Date ("1978-11-03")); / / System.out.println (GeneralHelper.str2Date ("1978-11-03")); / / GeneralHelper.str2Byte (null) / / GeneralHelper.str2Char_0 (null); / / GeneralHelper.str2Boolean (null); / / GeneralHelper.str2Boolean_False (null);} private static void testStr2Object () throws IntrospectionException {int I = GeneralHelper.str2Object (int.class, "123"); Date dt = GeneralHelper.str2Object (Date.class, "1978-11-03") String [] arr = GeneralHelper.str2Object (String [] .class, "12, 34, 56, 78", new GeneralHelper.TypeHandler () {@ Override public String [] handle (String v) {StringTokenizer st = new StringTokenizer (v, ",;\ t\ r\ n\ f") String [] result = new String [st.countTokens ()]; for (int I = 0; st.hasMoreTokens (); result +) result [I] = st.nextToken (); return result;}}) / /!! Error! / / String [] arr2 = GeneralHelper.str2Object (String [] .class, "12, 34, 56, 78");} private static void test_setProperty () {C = new C (); BeanHelper.setProperty (c, "dt", "2010-10-10"); BeanHelper.setProperty (c, "I", 456) BeanHelper.setProperty (c, "l", "999"); int I = BeanHelper.getProperty (c, "I"); double l = BeanHelper.getProperty (c, "l"); boolean b = BeanHelper.getProperty (c, "b"); Date dt = BeanHelper.getProperty (c, "dt"); System.out.println (c) } private static void test_setProperties_1 () throws Exception {Map objs = new HashMap (); objs.put ("si", new String [] {"888"}); objs.put ("fi", new String [] {"999"}); objs.put ("b", new String [] {"true"}) Objs.put ("I", new String [] {"1"}); objs.put ("l", new String [] {"2.3"}); objs.put ("dt", new String [] {"2011-09-17"}); objs.put ("_ _ str", new String [] {"I am a monster"}) Objs.put ("_ _ ia", new String [] {"12", "34", "56"}); objs.put ("_ _ sa", new String [] {"ab", "cd", "ef"}); Map keyMap = new HashMap (); keyMap.put ("_ str", "str") KeyMap.put ("_ _ ia", "ia"); keyMap.put ("_ _ sa", "sa"); C c = BeanHelper.createBean (C.class, objs, keyMap); Map result = BeanHelper.getProperties (c); System.out.println (result) } private static void test_setProperties_2 () throws Exception {java.sql.Date dt = new java.sql.Date (new java.util.Date (). GetTime ()); Map objs = new HashMap (); objs.put ("si", 888); objs.put ("fi", 999); objs.put ("b", "True") Objs.put ("I", 123); objs.put ("l", "2.3"); / / objs.put ("dt", new String [] {"2011-09-17"}); objs.put ("dt", dt); objs.put ("str", "I am a monster") Objs.put ("ia", new int [] {12, 34, 56}); objs.put ("sa", "ab, cd, ef"); C c = new C (); BeanHelper.setProperties (c, objs); Map result = BeanHelper.getProperties (c); System.out.println (result);}} package test Import java.util.Date; class A {private boolean b; public boolean isB () {return b;} public void setB (boolean b) {this.b = b;}} public class C extends A {static int si; final int fi = 100; private int i Private Double l; private Date dt; private String str; private int [] ia; private String [] sa; public String [] getSa () {return sa;} public void setSa (String [] sa) {this.sa = sa;} public static int getSi () {return si } public static void setSi (int si) {C.si = si;} public int getFi () {return fi;} public String getStr () {return str;} public void setStr (String str) {this.str = str } public int [] getIa () {return ia;} public void setIa (int [] ia) {this.ia = ia;} public int getI () {return I;} public void setI (int I) {this.i = I } public Double getL () {return l;} public void setL (Double l) {this.l = l;} public Date getDt () {return dt;} public void setDt (Date dt) {this.dt = dt }} the above is the editor for you to share how to automatically assemble objects and forms in Java. If you happen to have similar doubts, please refer to the above analysis to understand. If you want to know more about it, you are welcome to follow the industry information channel.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.