Quantcast
Channel: SCN : All Content - SAP HANA Cloud Platform Developer Center
Viewing all articles
Browse latest Browse all 3285

JAX-RS the missing link between UI5 and HCP Java apps - adding EJB

$
0
0

This is part 2 of this blog and it assumes you have read Part 1.

 

In part 1 of this blog we have achieved a basic "ping" service that responds to a get request with just some static answer - "pong".

 

Normally you want to access a database and do some nice stuff. The best way to achieve a nice service layer is (in my opinion) to use EJB. You can control access rights, transactions etc. right by annotating your EJB in a nice and simple way. And you get your EntityManager or Datasource for JPA or JDBC directly injected without so much "boiler plate" code. So I want to show how to incopreate EJB in our setup. So the task I want to solve is adding an EJB with an entity manager injected and returning the result as a JSON object.

 

So first turn your project to a JPA project by adding this project facet in Eclipse.

 

Then we need a simple EJB:

/**

* EJB

*/

package com.sap.myapp;

 

import javax.ejb.LocalBean;

import javax.ejb.Stateless;

import javax.persistence.EntityManager;

import javax.persistence.PersistenceContext;

 

/**

* Simple EJB

*/

@LocalBean

@Stateless

public class MyEJB {

 

  @PersistenceContext EntityManager em;

 

  public MyJSONResult doSomething() {

    MyJSONResult result = new MyJSONResult();

    result.setState(em != null ? "em is injected :-)" : " em not inject :-(");

    return result;

  }

}

It does nothing else as to give me the state of the injected entity manager. For the sake of completeness I have to add the MyJSONResult class, which is just a simple POJO:

/**

* JSON bean

*/

package com.sap.myapp;

 

/**

* Simple Bean as result of EJB call

*/

public class MyJSONResult {

  private String state;

 

  /**

   * @return the state

   */

  public String getState() {

    return state;

  }

 

  /**

   * @param state the state to set

   */

  public void setState(String state) {

    this.state = state;

  }

}

If we would have the Java Web Profile level 7 not 6 on HCP this would be very easy (and I could not write this blog) all you would have to do is add your EJB to your new service. So my service would look like:

 

/**

* REST

*/

package com.sap.myapp;

 

import javax.ejb.EJB;

import javax.servlet.ServletException;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Response;

 

/**

* Simple REST Service

*/

@Path("/service")

public class MyService {

 

  @EJB MyEJB myEjb;

 

  @GET

  @Path("/")

  @Produces(MediaType.APPLICATION_JSON)

  public Response myService() throws ServletException {

    return Response.ok().entity(myEjb.doSomething()).build();

  }

}

 

This would result in a Nullpointer Exception as the EJB is not injected. So there is some more magic needed as long as we stay with Jave Web Profile 6. We have to do a JNDI lookup of the bean before we can use it. By doing JNDI we get a fully working container managed EJB and we have to do that in every service method that wants to use EJB.

 

So the extended service will look like the following:

/**

* REST

*/

package com.sap.myapp;

 

import javax.ejb.EJB;

import javax.naming.InitialContext;

import javax.naming.NamingException;

import javax.servlet.ServletException;

import javax.ws.rs.GET;

import javax.ws.rs.Path;

import javax.ws.rs.Produces;

import javax.ws.rs.core.MediaType;

import javax.ws.rs.core.Response;

 

/**

* Simple REST Service

*/

@Path("/service")

public class MyService {

 

  @EJB MyEJB myEjb;

 

  @GET

  @Path("/")

  @Produces(MediaType.APPLICATION_JSON)

  public Response ping() throws ServletException {

    lookupEJBs();

 

    return Response.ok().entity(myEjb.doSomething()).build();

  }

 

  private void lookupEJBs() throws ServletException {

    if (myEjb == null) {

      try {

        InitialContext ic = new InitialContext();

        myEjb = (MyEJB) ic.lookup("java:comp/env/ejb/MyEJB");

      }

      catch (NamingException e) {

        throw new ServletException(e);

      }

      catch (Exception e) {

        throw new ServletException(e);

      }

    }

  }

}

For the JNDI lookup to work you have to add your EJB to the web.xml:

  <ejb-local-ref>

    <ejb-ref-name>ejb/MyEJB</ejb-ref-name>

    <local>com.sap.myapp.MyEJB</local>

  </ejb-local-ref>

So you tried it all out and your ping-pong service works but your new service gives a 404? Then you forgot to add your new service class to "MyApplication" as we did with the PingService in Part 1

 

Thats it, if you call now your application with the relative path "/rest/service" you get a JSON response.

 

{"state":"em is injected :-)"}

 

Explore the power of Jersey, even stuff as file upload can be done with a few simple annotations. If someone is interested in that I may add a third part to this small blog series


Viewing all articles
Browse latest Browse all 3285

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>