(Developer)Customize the configuration-based controller command and data bean mapping framework
WebSphere Commerce uses REST calls for some data beans by default. They are configured with mapping profiles that map REST input parameters to data bean or controller command setter-methods, and data bean or controller command getter-methods to REST output parameters. To customize this behavior, we must either create new mappings, or extend the default mappings. The following scenarios might be typical when customizing the framework:
- Use the same REST data beans or controller commands as WebSphere Commerce, but getting a different set of input or response data.
- Subclassing a preexisting data bean to extend function, and creating a REST mapping configuration that references the preexisting mapping profile so that we can add the delta changes.
- Configure a new REST service for a preexisting data bean or controller command that has no default REST configuration.
- Creating or updating our own customized data beans and controller commands to be accessed through REST.
Note: Customizing the framework refers to creating new REST handlers and mapping profiles, or extending built-in mapping profiles.
Procedure
- Use the data bean or controller command extension directory to add new configuration mapping profiles. Use the following sample configurations as a base:
- Default configuration location: Rest.war/WebContent/WEB-INF/config/beanMapping/com.ibm.commerce.BeanBaseClass.xml
<bean> <profiles> <profile name="IBM_Summary"> <inputs> <input inputName="int1" methodName="setInt1"/> <input inputName="string1" methodName="setString1"/> </inputs> <outputs> <output methodName="getInt1" outputName="int1"/> <output methodName="getString1" outputName="string1"/> </outputs> </profile> <profile name="IBM_Details"> <inputs> <input inputName="int1" methodName="setInt1"/> <input inputName="int2" methodName="setInt2"/> <input inputName="string1" methodName="setString1"/> <input inputName="string2" methodName="setString2"/> </inputs> <outputs> <output methodName="getInt1" outputName="int1"/> <output methodName="getInt2" outputName="int2"/> <output methodName="getString1" outputName="string1"/> <output methodName="getString2" outputName="string2"/> <output methodName="getObject1" outputName="object1"> <output methodName="getLong1" outputName="long1"/> </output> </outputs> </profile> </profiles> </bean>Where:
- The default configuration file is in the default bean mapping directory.
- It contains two profiles.
- Each profile has input and output mappings between REST and the data bean.
- Extension configuration location: Rest.war/WebContent/WEB-INF/config/beanMapping-ext/com.mycompany.BeanExtendedClass.xml
<bean> <profiles> <profile name="MyCompany_Details"> <extends> <extend profileName="IBM_Details" profileClass="com.ibm.commerce.BeanBaseClass"/> </extends> <inputs> <input inputName="int1" methodName="setInt1" required="true"/> <input inputName="int3" methodName="setInt3"/> </inputs> <outputs> <output methodName="getString3" outputName="string3"/> <output methodName="getString2a" outputName="string2"/> <output methodName="getObject1" outputName="object1"> <output methodName="getLong2" outputName="long2"/> </output> </outputs> </profile> </profiles> </bean>Where:
- The extension configuration file is in the extension bean mapping directory.
- The file name is different because it is a custom subclass of the original bean.
- It contains a new profile called MyCompany_Details:
- The profile contains an extends element, stating where to get the input and output values to start with. In this sample, it is from the IBM_Details profile of the com.ibm.commerce.BeanBaseClass default configuration file.
- It overrides the input int1 to be required.
- It adds new input int3 and output string3.
- It overrides the output string2 to call method getString2a instead of getString2.
- For the output tree or hierarchy that starts with object1, add a leaf output called long2.
Extension configuration location: Rest.war/WebContent/WEB-INF/config/beanMapping-ext/com.ibm.commerce.BeanBaseClass.xml <bean> <profiles> <profile name="IBM_Summary"> <extends> <extend profileName="IBM_Summary"/> </extends> <outputs> <output methodName="getString2" outputName="string2"/> </outputs> </profile> </profiles> </bean>Where:
- The extension configuration file is in the extension bean mapping directory.
- The file name is the same as the default file because it is meant to override the built-in profiles or add more profiles for the original bean.
- The IBM_Summary profile is repeated in this file, so that whenever it is referenced by a REST call, the profile in this extension file takes precedence:
- The profile contains extends elements, stating where to get the input and output values to start with. In this sample, it is from the original IBM_Summary profile.
- Adds new output string2.
Ensure that we are aware of the following rules for extensions:
- A mapping file in the extension directory takes precedence over the default configuration. When a profile is found in both files, the one in the extension file takes precedence.
- Use the extends/extend capability:
- The extends/extend elements are only allowed in an extension configuration file.
- We can extend only one default profile per extension profile.
- The original profile is used as a default. All inputs and outputs and listName attributes are added to the extended profile.
- Any input in the extended profile that has the same methodName replaces the one found in the default profile, regardless of inputName.
- Any input in the extended profile that has the same inputName overrides the default profile.
- Any other input in the extended profile is added as a new input.
- The listName attribute value is dictated by its use in the extension profile. If it is not mentioned in the extension profile, it is not used.
- If the output element is a branch (contains output elements within) in the extended profile:
- If the outputName is different, a new branch is added.
- If the outputName is the same as the default, but the output methodName is different, the branch in the default is replaced with this one.
- If the outputName and methodName are the same as a branch in the default, it processes the items within according to these same rules.
- Any output that is not a branch in the extended profile that has the same outputName overrides the default profile.
- If any input or output is duplicated (same name) within the same profile, the result is undefined.
Supported input parameter types. Whether a REST call is made using path parameters (for example, strings), a JSON body (for example, JSON data types), the AbstractConfigBasedClassicHandler needs to convert them to the data type expected by the data bean or controller command setter method. For date-time types, the formats are focused on ISO 8601 standards. The following table shows a list of target data types (data bean and controller command setter method parameter types) and the REST input data types supported:
Data bean or controller command target data type (for example, setter method argument) Input/source data type Input/source format (if applicable) java.lang.String String java.lang.Boolean (or bool) String true | false JSON Boolean java.lang.Number (for example, Integer, Long, BigDecimal) or primitive numbers String
JSON Number Attempt to convert to target requiredjava.util.Date String 2014-08-01T13:41:07Z 2014-08-01T13:41:07-04:00 2014-08-01T13:41:07-0400 2014-08-12T13:41:07.123Z 2014-08-12T13:41:07.000-04:00 2014-08-12T13:41:07.789-0400 java.sql.Timestamp String 2014-08-01T13:41:07Z 2014-08-01T13:41:07-04:00 2014-08-01T13:41:07-0400 yyyy-mm-dd hh:mm:ss.[fff...] (as described in Java documentation for Timestamp) java.sql.Date String YYYY-MM-DD java.sql.Time String T16:57:30Z T16:57:30-05:00 T16:57:30+0400 16:57:30Z 16:57:30-05:00 16:57:30+0400 T16:57:30 16:57:30 Java Array (for example, [123, 456, 789])
Java Collection of elements of any supported target type, so long as all elements are of the same data type JSON Array of elements of any supported target type
JSON output formats. The following table describes the JSON output formats that we can expect for different data types that are returned by getter-type methods of data beans and controller commands:
Data bean or controller command return data type JSON data type JSON format (if applicable) java.lang.String JSON String java.lang.Number (for example, Integer, Long, BigDecimal) or primitive numbers JSON Number java.lang.Boolean (or bool) JSON Boolean java.util.Date JSON String 1975-08-04T12:35:00.123Z java.sql.Timestamp JSON String 2014-08-01T13:41:07.000000000Z java.sql.Date JSON String YYYY-MM-DD java.sql.Time JSON String 13:41:07Z Java Array (for example, [123, 456, 789]) or Java Collection (it is expected that all elements are of the same data type) JSON Array Java Map JSON Object (keys are Strings, values are of any supported return type)