Consume Odata Service in Hybris

Nikhil Bhavsar
5 min readMar 26, 2019

--

This Article is for the technical description of consuming Odata Service provided by REFX(Flexible Real Estate Management).

We have created one module function like if the customer wants more detail information about the product then a customer can register inquiry about that product, then sales executive can contact that customer according to register inquiry.

But here we discuss only how to Consume Odata and showing response data on SAP Hybris side.

In later blogs, I will discuss how customer inquiry data submit on SAP C4C side 👍

What is Odata?

OData is a REST-based open web protocol for sharing data in a standardized format for easy consumption by other systems. It uses well known web technologies like HTTP, AtomPub, and JSON.

Scenario: We have created one node from odata service is called which gives the response as a list of rental objects(List of properties).We have to display this rental object list on hybris . then customer clicks on one rental object on which other Odata service is called which gives response for that particular object. This we need to display it on the hybris description page.

Architecture:

UI :

1) On Product Listing page(list of rental objects)

2) After Click on the rental object

3)After Click on Submit button, data submitted to SAP C4C and we get the unique lead id from C4C side for customer future reference that we discuss in another blog…

Data Modeling

Beans.xml

Create Data Classes(Simple POJO Classes) : ServiceRequestData class value depends on REFX data example CITY1,COUNTRY.

<bean class=”com.hybris.training.core.data.ODataSingleResponseData”><property name=”d” type=”ServiceRequestData”/>
</bean>
<bean class=”com.hybris.training.core.data.ODataListResponseData”><property name=”d” type=”ODataListResultsData” />
</bean>
<bean class=”com.hybris.training.core.data.ODataListResultsData”><property name=”results” type=”java.util.List&lt;ServiceRequestData&gt;”/>
</bean>
<bean class=”com.hybris.training.core.data.OdataMetaData”>
<property name=”id” type=”String”/>
<property name=”uri” type=”String”/>
<property name=”type” type=”String”/>
</bean>
<bean class=”com.hybris.training.core.data.ServiceRequestData”><property name=”__metadata” type=”com.hybris.training.core.data.OdataMetaData”/>
<property name=”IMKEY” type=”String”/>
<property name=”INTRENO” type=”String”/>
<property name=”ROTYPE” type=”String”/>
<property name=”BUKRS” type=”String”/>
<property name=”SWENR” type=”String”/>
<property name=”SMENR” type=”String”/>
<property name=”SNUNR” type=”String”/>
<property name=”SGENR” type=”String”/>
<property name=”FLOOR” type=”String”/>
<property name=”FLOORLOC” type=”String”/>
<property name=”NUMROOMS” type=”String”/>
<property name=”LIVINGAREA” type=”String”/>
<property name=”ADROBJNR” type=”String”/>
<property name=”ADRNR” type=”String”/>
<property name=”CITY1" type=”String”/>
<property name=”POST_CODE1" type=”String”/>
<property name=”STREET” type=”String”/>
<property name=”HOUSE_NUM1" type=”String”/>
<property name=”COUNTRY” type=”String”/>
<property name=”MC_CITY1" type=”String”/>
<property name=”MC_STREET” type=”String”/>
<property name=”TIME_ZONE” type=”String”/>
</bean>

Project.properties

odata.url=http://sapours1.sapours.com:8010/sap/opu/odata/sap/ZREFX_SRV
odata.suffix=/ZRental_ObjSet
odata.format.accept=?$format=json
odata.format.s=(‘
odata.format.e=’)
odata.attach=/ZAttachmentSet
odata.auth=Authorization
odata.auth.type=Basic
odata.auth.username=GIREESH
odata.auth.password=s4h@2018

ServiceLayer

1)REFXOdata Interface

public List<ServiceRequestData> getRentalObjects();public ServiceRequestData getRentalObject(String imkey);public byte[] getRentalObjectImg(ServiceRequestData serviceRequestData);
  1. getRentalObject: Method gives a list of rental object from REFX.
  2. getRentalObject: Method gives Single rental object using the specific key from REFX.
  3. getRentalObjectImg: Method gives image for specific rental object from REFX.

2) REFXOdataImpl Class:

Steps:

  1. In UriComponentsBuilder pass the URL that you have to consume, suffix, and format(like ?$format= JSON because here data coming in JSON format)
  2. Create New instance of HttpHeaders then add authentication to access that URL
  3. Create an object of HttpEntity pass parameter object of http header
  4. Inject the bean of REST Template in class
  5. Use getter method of rest template pass parameter object of UriComponentsBuilder
  6. Finally, we get a response in ResponseEntity but data is JSON format
  7. So inject bean for Jackson object mapper to convert JSON data to a java object(POJO class)

Find out more information on Jackson object mapper 👇

Now Let’s do some coding 💪

public static final String URL = Config.getParameter(“odata.url”);
public static final String SUFFIX = Config.getParameter(“odata.suffix”);
public static final String FORMAT = Config.getParameter(“odata.format.accept”);
public static final String S = Config.getParameter(“odata.format.s”);
public static final String E = Config.getParameter(“odata.format.e”);
@Override
public List<ServiceRequestData> getRentalObjects()
{
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(URL + SUFFIX + FORMAT);
final HttpHeaders headers = new HttpHeaders();
headers.add(“Authorization”, “Basic “ + addAuthentication());
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<String> result = getRestTemplate().exchange(builder.build().encode().toUri(), HttpMethod.GET, entity,String.class);
getJacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);getJacksonObjectMapper().configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
try
{
final ODataListResultsData oDataListResultsData = getJacksonObjectMapper().readValue(result.getBody(), ODataListResponseData.class).getD();
final List<ServiceRequestData> list = oDataListResultsData.getResults();
return list;
}
catch (final JsonParseException e)
{
e.printStackTrace();
}
catch (final JsonMappingException e)
{
e.printStackTrace();
}
catch (final IOException e)
{
// XXX Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
public ServiceRequestData getRentalObject(final String imkey)
{
final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(URL + SUFFIX + S + imkey + E + FORMAT);
final HttpHeaders headers = new HttpHeaders();
headers.add(“Authorization”, “Basic “ + addAuthentication());
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<String> result = getRestTemplate().exchange(builder.build().encode().toUri(), HttpMethod.GET, entity,String.class);
getJacksonObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);getJacksonObjectMapper().configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
try
{
Final ODataSingleResponseData oDataSingleResponseData = getJacksonObjectMapper().readValue(result.getBody(),ODataSingleResponseData.class);
final ServiceRequestData ServiceRequestData = oDataSingleResponseData.getD();
return ServiceRequestData;
}
catch (final JsonParseException e)
{
e.printStackTrace();
}
catch (final JsonMappingException e)
{
e.printStackTrace();
}
catch (final IOException e)
{
e.printStackTrace();
}
return null;}@Overridepublic byte[] getRentalObjectImg(final ServiceRequestData serviceRequestData){final UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(“http://sapours1.sapours.com:8010/sap/opu/odata/sap/ZREFX_SRV/ZAttachmentSet(CompCode='"+ serviceRequestData.getBUKRS() + “‘,RentalObjects=’” + serviceRequestData.getSMENR() + “‘,BusEnt=’”+ serviceRequestData.getSWENR() + “‘)/$value”);final HttpHeaders headers = new HttpHeaders();
headers.add(“Authorization”, “Basic “ + addAuthentication());
final HttpEntity<String> entity = new HttpEntity<String>(headers);
final ResponseEntity<byte[]> result = getRestTemplate().exchange(builder.build().encode().toUri(), HttpMethod.GET, entity,byte[].class);
final byte[] image = result.getBody();
return image;
}
##To access REFX data in hybris site##public String addAuthentication(){
final String plainCreds = “USERNAME:PASSWORD”;
final byte[] plainCredsBytes = plainCreds.getBytes();
final byte[] base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
final String base64Creds = new String(base64CredsBytes);
return base64Creds;
}

If the customer wants more detail about that property then on click of Submit button C4C service calls to submit that customer data and create a unique lead from the C4C side for that particular rental object that we have to show to the customer.

SAP Hybris And SAP C4C integration using SOAP Webservice will be coming soon 🏃

If you enjoyed this story give a clap for it and share to help others find it! Feel free to leave a comment below.

You can also find me on LinkedIn, Github.

Happy Learning😄……

--

--

Nikhil Bhavsar

Software Engineer at Amagi | — a life-long learner, explorer | ~ Traveller ~ Trekker~