How to Customize Hybris Bean a Step Further!
Rajat Singh
Lead Developer @Arrow Electronics. Developing and Enhancing SAP E-Commerce(Hybris) Applications. Passionate Coder/Thinker. Lets Connect!
Dear SAP Commerce Developers,
Before we dive into customizing bean which gets generated by registering it in the *beans.xml, let's first explore the scenarios that make this customization necessary.
Imagine we have a JSON payload that we want to map into a Plain Old Java Object (POJO). Here's a sample of the JSON payload:
{
"CountryOfOrigin": {
"code": "US",
"name": "United States"
},
"SomeOtherField": "Unexpected Value"
}
And here’s the respective bean definition:
<bean class="com.hybris.data.CountryOfOriginData">
<property name="code" value="US" />
<property name="name" value="United States" />
</bean>
and the generated Java POJO for this data object looks like this:
class CountryOfOriginData {
private String code;
private String name;
// Getters and setters...
}
Here’s the challenge: this POJO class doesn’t account for the extra field SomeOtherField in the JSON payload.
Problem Statements: Scenarios where this setup will fail
Unexpected Values in the Request Body:
Suppose we have an API that handles incoming RequestBody in CountryOfOriginData. Here’s a simple example:
@Controller
@RequestMapping("/api/countries")
public class CountryController {
@PostMapping
public ExampleDTO
createCountry(@RequestBody CountriesOfOriginData countriesOfOrigin) {
// Handle countriesOfOrigin
}
}
The API fails because it cannot process the extra field SomeOtherField that wasn’t expected in the JSON payload.
Handling JSON Response from External API:
When retrieving data from an external API, we could encounter similar issues:
CountryOfOriginData country = restTemplate.getForObject("https://api.example.com/countries", CountryOfOriginData.class);
This results in an exception as the JSON contains any unexpected field SomeOtherField.
In fact, there are numerous scenarios where the JSON-to-POJO mapping might fail, including saving JSON data to a database, reading JSON files, or passing JSON data through messaging systems like Kafka.
Standard Solution: Using Jackson Annotations
A common solution to this issue is to use Jackson annotations, specifically @JsonProperty and @JsonIgnoreProperties, to handle unknown fields gracefully. Fortunately, the Jackson library is included in SAP Hybris (currently using version 2211, as defined in external-dependencies.xml).
So Let’s consider how our CountryOfOriginData class should look after the build.
领英推荐
package com.hybris.data;
import com.fasterxml.jackson.annotation.JsonProperty;
@JsonIgnoreProperties(ignoreUnknown = true)
public class CountryOfOriginData {
@JsonProperty("code") // Optional
private String code;
@JsonProperty("name") // Optional
private String name;
// Getters and setters
}
This way, the CountryOfOriginData class can handle unknown fields without throwing an error.
How can we create this in Hybris with the following elements?
Customizing Bean Definitions in SAP Hybris
Now, how can we ensure that our bean definition includes these annotations in Hybris? For this, we’ll need to check the XSD (XML Schema Definition) file to confirm that our required elements and annotations are allowed.
Here’s a snippet of the relevant XSD schema:
<xs:complexType name="bean">
<xs:complexContent>
<xs:extension base="abstractPojo">
<xs:sequence>
<xs:element name="import" type="import" minOccurs="0" maxOccurs="unbounded" />
<xs:element name="annotations" type="annotations" minOccurs="0" maxOccurs="1"/>
<xs:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
</xs:sequence>
<xs:attribute name="type" type="xs:string" use="optional">
<xs:annotation>
<xs:documentation>Defines the type of bean.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:extension>
</xs:complexContent>
</xs:complexType>
Using this schema, we can define the necessary imports and annotations directly in the XML configuration:
<bean class="com.hybris.data.CountryOfOriginData">
<!-- Class Level import and annotation -->
<import type="com.fasterxml.jackson.annotation.JsonIgnoreProperties"/>
<annotations>@JsonIgnoreProperties(ignoreUnknown = true)</annotations>
<!-- Field Level annotation -->
<property name="code" value="US" >
<annotations>@JsonProperty("Status")</annotations>
</property>
<property name="name" value="United States" >
<annotations>@JsonProperty("Status")</annotations>
</property>
<!-- Add more properties as needed -->
</bean>
Bonus: Understanding the Role of XSD Files in SAP Hybris:
The XSD file is more than just a structure—it’s a blueprint that plays an essential role in SAP Hybris by defining what’s allowed in XML configurations.
1. Schema Validation
It ensures XML files follow a specific structure, avoiding runtime errors by catching issues early.
2. Defining Structure and Constraints
The XSD specifies allowed elements, constraints, data types, and more, keeping configurations consistent across the system.
3. Establishing Relationships and Hierarchies
Through extensions, XSD enables reuse and inheritance in XML-based configurations, maintaining modular configurations.
4. Documentation for Developers
Documentation in the XSD helps developers understand each element, making configuration easier.
Thank you for reading, and I wish you a Happy Diwali! ??