$30 off During Our Annual Pro Sale. View Details »

Enterprise Web App. Development (6): JAX-RS Tra...

Enterprise Web App. Development (6): JAX-RS Training Ver. 4

This is the sixth course of a series of courses for Enterprise Web Application development based on several Open Source products. As we finished JPA + JTA with CDI course, we are going to move on to “JAX-RS” as the third course of Jakarta EE framework specification. Later we are taking care of “Jakarta Batch” as minimum skills to develop Enterprise Web Application. In those courses, we refer to some “Application Architecture Design Patterns”. Therefore this series requires the basic skills of Ubuntu Desktop/Server, Eclipse IDE, Java SE (OpenJDK), Payara Server and PostgreSQL. Regarding the Payara Server, we can use another Web Application Server conforming to Jakarta EE specification. As for PostgreSQL, we might be able to use another RDBMS product instead. We can also make use of another Linux distribution instead of Ubuntu Desktop/Server.

Version 4 was updated on Dec. 9th, 2025.

Avatar for Koichi NAKAGAWA

Koichi NAKAGAWA

November 26, 2020
Tweet

More Decks by Koichi NAKAGAWA

Other Decks in Programming

Transcript

  1. JAKARTA RESTFUL WEB SERVICES (JAX-RS) (VER. 4) A part of

    Jakarta EE™ specification RESTful Web Service Framework 1 By Koichi NAKAGAWA Enterprise Web Application Development Course (6) Updated on Dec. 9th, 2025
  2. Update Information ▪ Ver. 4: Use Ubuntu Server™ instead of

    Rockey Linux™ as a Server platform and Ubuntu Desktop™ instead of Windows 10 as Desktop platform, Payara Server 7™ certified as Jakarta EE 11 Platform Compatible Products instead of Payara Server 6™ and JDK 21 instead of JDK 11. • Ver. 3: Use Rocky Linux™ instead of CentOS™ as a Linux platform and Payara Server 6™ certified as Jakarta EE 9.1 Platform Compatible Products. • Ver. 2 : Use JDK 11 instead of JDK 8 and Jakarta EE 9 instead of Jakarta EE 8 in all exercises. 2
  3. EWA development course curriculum Object Oriented Development Methodology JSF with

    CDI JPA + JTA with CDI JAX-RS Application Architecture Design Patterns Eclipse IDE™ Version Control Tool with Git™ Build Tool with Apache Maven™ Payara Server™ Administration Linux (Ubuntu™) Total EWA Development Exercise Jakarta Batch Java SE (OpenJDK™) Required Skills to take courses Test Tool with JUnit5 PostgreSQL™ Administration 4
  4. Trademarks Notice • Jakarta™ EE and its logo( ) are

    trademarks of the Eclipse Foundation. • PostgreSQL™ and its logo( ) are registered trademarks of the PostgreSQL Community Association of Canada. • Apache Derby™ and its logo ( ) are trademarks of the Apache Software Foundation. • Payara™ Server and their logo( ) are trademarks of Payara Services® LTD. • EclipseLink™, EclipseLink™ logo ( ), Eclipse IDE for Enterprise Java Developer™, the Eclipse IDE for Enterprise Java Developer ™ logo( ), Eclipse M2Eclipse™, M2Eclipse™, Eclipse Git Team Provider™, Eclipse EGit™, EGit™, Eclipse Java development tools™, Java development tools™, Eclipse JDT™, JDT™ are trademarks of the Eclipse Foundation. • Apache Maven™, Maven™ are trademarks of the Apache Software Foundation (ASF). • Git™ and the Git™ logo( ) are either registered trademarks or trademarks of Software Freedom Conservancy, Inc., corporate home of the Git Project, in the United States and/or other countries. • Java™ is trademark of Oracle Corporation. 5
  5. Assumption for this course • The trainees who take this

    course are required the following skills in advance • PostgreSQL (Version: 17.5) – Basic Administration Operations • Payara Server (Version: 7.2025.1.Beta1) – Basic Administration Operations • OpenJDK (Version: 21) • Eclipse IDE for Enterprise Java Developers (Version: 2025-9 (4.37.0)) • Build Tool Training Course • Version Control Tool Training Course • Test Tool Training Course • JSF with CDI Training Course • JPA + JTA with CDI Training Course 6
  6. Objectives This course is aimed to obtain the following skills

    • Jakarta RESTful Web Services (JAX-RS) technology • Development of RESTful Web Services applications using JAX-RS • Integration with Transactional CDI components in business layer 7
  7. JAX-RS • Concept of Jakarta RESTful WebServices (JAX-RS) • How

    to use JAX-RS • Architecture Design with JAX-RS and CDI • First JAX-RS Application • Other JAX-RS Programming • Exercise 8
  8. Concept of JAX-RS • Communications between Applications 10 Requester (Server)

    Provider (Another Server) Service Request Message Response Message Application A Application B
  9. Concept of JAX-RS • Communication Technologies between Applications with Jakarta

    EE™ 11 Requestor (Server) Provider (Another Server) Service Request Message Response Message Technology Protocol Message Dist. Object Interface Over Internet Specification REST Service HTTP Text (URL Encode, XML, JSON) No Swagger base Possible JAX-RS EJB Remote Call RMI over IIOP Binary Yes Java Interface Impossible EJB SOAP Web Service SOAP over HTTP Text (XML) Yes WSDL Possible JAX-WS
  10. Concept of JAX-RS • HTTP Message 12 HTTP Requester HTTP

    Server HTTP Response HTTP Request • HTTP Structure Start Line (Request Line) Headers Body URI  http(s)://localhost/milkProducts  GET /milkProducts HTTP 1.1  Host: localhost  Null (Mainly used by POST/PUT Methods) Start Line (Status Line) Headers Body  HTTP/1.1 200 OK  Server: Apache  Cheese, Milk, Yogurt HTTP Request HTTP Response HTTP Provider
  11. Concept of JAX-RS • What is RESTful Web Services? 13

    HTTP Usage Uniform Interface HTTP Method URI HTTP Status No matter how many time a HTTP message is sent, resource should not be changed for GET and HEAD methods All HTTP Method should be utilized (GET, POST, PUT, DELETE, PATCH, HEAD) Point out a resource by URI ex. GET /employees/1234 All HTTP Status should be utilized (Not only 200(“OK”) and 500(“Internal Server Error”) but also 201(“Created”), 204(“No Content”), etc.) Safety Rule Idempotency Rule No matter how many time a HTTP message is sent, the result should be the same for GET, HEAD, PUT and DELETE methods Providers should provide their resource operation methods based on the uniformed rules. Providers should utilize the HTTP protocol fully following its original usages.
  12. Concept of JAX-RS • Architecture of JAX-RS 14 Requester Provider

    JAX-RS Engine Request Message (JSON, XML, …) Response Message (JSON, XML, …) Web Resource Class (POJO) Decode Call Resource Method Encode Resource Method Inputs (Java Objects) Outputs (Java Object) Jakarta EE Container
  13. How to configure JAX-RS Engine • JAX-RS Engine in the

    Architecture 16 Requester Provider JAX-RS Engine Request Message (JSON, XML, …) Response Message (JSON, XML, …) Web Resource Class (POJO) Decode Call Resource Method Encode Resource Method Inputs (Java Objects) Outputs (Java Object) Jakarta EE Container
  14. How to configure JAX-RS Engine • What is Application Path?

    17 REST Service URI with JAX-RS Engine http(s)://[Host Name or IP Address]:[port]/Context Path/Application Path/Request Path Configure the Application Path in one of the two ways. JAX-RS Engine Decode Call Resource Method Encode
  15. How to configure JAX-RS Engine • Configuration of Application Path

    (2 Ways) 18 Configuration in Custom Application • Using the @ApplicationPath for a subclass of javax.ws.rs.core.Application Configuration in web.xml • Using the servlet-mapping tag within the WAR’s web.xml JAX-RS Engine Decode Call Resource Method Encode
  16. How to configure JAX-RS Engine • Configuration of Application Path

    (By Custom Application) 19 Configuration in Custom Application • Using the @ApplicationPath for a subclass of javax.ws.rs.core.Application @ApplicationPath("/webapi") public class MyApplication extends Application { ... } @Override public Set<Class<?>> getClasses() { final Set<Class<?>> classes = new HashSet<>(); // register root resource classes.add(MyResource.class); return classes; } (Option) The Custom Application can define Web Resource Classes to be used as well. Application Path Web Resource Class Custom Application JAX-RS Engine Decode Call Resource Method Encode
  17. How to configure JAX-RS Engine • Configuration of Application Path

    (By web.xml) 20 Configuration in web.xml • Using the servlet-mapping tag within the WAR’s web.xml <servlet-mapping> <servlet-name>javax.ws.rs.core.Application</servlet-name> <url-pattern>/webapi/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>com.example.rest.MyApplication</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping> (Option) Application Path in your Custom Application can be changed. Application Path Changed Application Path Custom Application JAX-RS Engine Decode Call Resource Method Encode
  18. How to make Web Resource Class • Web Resource Class

    (POJO) in the Architecture 21 Requester Provider JAX-RS Engine Request Message (JSON, XML, …) Response Message (JSON, XML, …) Web Resource Class (POJO) Decode Call Resource Method Encode Resource Method Inputs (Java Objects) Outputs (Java Object) Jakarta EE Container
  19. How to make Web Resource Class • Programming for Web

    Resource Class and Resource Method 22 Web Resource Class (POJO) Resource Method @Path("/restService")  Request Line: GET /Context Path/Application Path/restService public class RestService { : @GET @Path("/hello")  Request Line: GET /Context Path/Application Path/restService/hello @Produces(MediaType.TEXT_PLAIN)  MIME Type of Response Message: “text/xml”, “application/json”, etc. public String hello() { return "Hello World! "; } : } Request Line: GET /Context Path/Application Path/restService/hello Response Message: Hello World! Check the value of the “accept” attribute of HTTP Request Header Request Path Path Parameter
  20. How to make Web Resource Class • Input Types obtained

    from HTTP Request 23 Web Resource Class (POJO) Input Types Path Query Form (URL Encoded) Objects (JSON, XML, …) Using Body (For POST, PUT Only) Start Line (Request Line) Headers Body HTTP Request Using Request Line JAX-RS Engine
  21. How to make Web Resource • How to obtain Path

    Parameters from HTTP Request 24 Web Resource Class (POJO) Resource Method @Path(“/restService”) public class RestService { : @GET @Path(“/visit1/{visitorName}”) @Produces(MediaType.TEXT_PLAIN) public String visit1(@PathParam(“visitorName”) String visitorName) {  Obtain a Path Parameter set return “Welcome to the REST World, ” + visitorName + “!”; } : } Request Line: GET /Context Path/Application Path/restService/visit1/Smith URI Template Response Message: Welcome to the REST World, Smith!
  22. How to make Web Resource • How to obtain Query

    Parameters from HTTP Request 25 Web Resource Class (POJO) Resource Method @Path(“/restService”) public class RestService { : @GET @Path(“/visit2”) @Produces(MediaType.TEXT_PLAIN) public String visit2(@QueryParam(“visitorName”) String visitorName) {  Obtain a Query Parameter set return “Welcome to the REST World, ” + visitorName + “!”; } : } Request Line: GET /Context Path/Application Path/restService/visit2?visitorName=Smith Response Message: Welcome to the REST World, Smith!
  23. How to make Web Resource • How to obtain Form

    Parameters from HTTP Request 26 Web Resource Class (POJO) Resource Method @Path(“/restService”) public class RestService { : @POST @Path(“/visit3”) @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.APPLICATION_FORM_URLENCODED)  MIME Type of the POST Request public String visit3(@FormParam(“visitorName”) String visitorName) {  Obtain a Form Parameter set return “Welcome to the REST World, ” + visitorName + “!”; } : } Request Line: POST /Context Path/Application Path/restService/visit3 Request Body: <form> … <input … name=“visitorName” value=“Smith” …/> … </form> Response Message: Welcome to the REST World, Smith! Check the value of the “content-type” attribute of HTTP Request Header
  24. How to make Web Resource • How to obtain JSON

    String as Java Object from HTTP Request 27 Web Resource Class (POJO) Resource Method @Path(“/restService”) public class RestService { : @POST @Path(“/visit4”) @Produces(MediaType.TEXT_PLAIN) @Consumes(MediaType.APPLICATION_JSON)  MIME Type of the POST Request public String visit4(Visitor visitor) {  Obtain a JSON Object as a Parameter return “Welcome to the REST World, ” + visitor.getName() + “!”; } : } Request Line: POST /Context Path/Application Path/restService/visit4 Request Body: {“name”:“Smith”}  JSON KVS(Key-Value-Store) String Response Message: Welcome to the REST World, Smith!
  25. How to make Web Resource • Output Types in HTTP

    Response 28 Output Types Status Code Objects (Plain Text, JSON, XML, …) Exceptions (Message, Root Cause) Using Status Line Using Body Web Resource Class (POJO) Start Line (Status Line) Headers Body HTTP Response JAX-RS Engine
  26. How to make Web Resource • How to return Object(s)

    in HTTP Response 29 Web Resource Class (POJO) Resource Method @GET @Produces(MediaType.APPLICATION_JSON) public List<MilkProduct> milkProducts() { List<MilkProduct> list = new ArrayList<>(); …. return list;  Return some JSON encoded Entities } Examples to set the Object(s) encoded with JSON in Response Message @GET @Produces(MediaType.APPLICATION_JSON)  Set MIME Type of Response Message public MilkProduct milkProduct(@QueryParam("id") Integer id) { MilkProduct product = new MilkProduct(); …. return product;  Return a JSON encoded Entity }
  27. How to make Web Resource • How to return Status

    Code and Object(s) in HTTP Response 30 Web Resource Class (POJO) Resource Method @GET @Produces(MediaType.APPLICATION_JSON) public Response milkProducts() { List<MilkProduct> list = new ArrayList<>(); …. return Response.status(200).entity(new GenericEntity<List<MilkProduct>>(list){}).build();  Return some JSON encoded Entities } Examples to set the HTTP Status Code Specifically and Object(s) encoded with JSON in Response Message @GET @Produces(MediaType.APPLICATION_JSON)  Set MIME Type of Response Message public Response milkProduct(@QueryParam("id") Integer id) { MilkProduct product = new MilkProduct(); …. return Response.status(Response.Status.OK).entity(product).build();  Return a JSON encoded Entity }
  28. How to make Web Resource • How to return Exception

    in HTTP Response 31 Web Resource Class (POJO) Resource Method Example to set the Exception Message, Root Cause of with HTTP Status Code in Response Message public String hello(…) throws WebApplicationException { try { : } catch (BusinessException cause) { String message = “Your request does not have enough information”; throw new WebApplicationException(message, cause, Response.Status.NOT_ACCEPTABLE);  Set a Message and a Root Cause of Exception and 406 as HTTP Status and throw WebApplicationException } }
  29. How to make Requester • Requester in the Architecture 32

    Requester Provider JAX-RS Engine Request Message (JSON, XML, …) Response Message (JSON, XML, …) Web Resource Class (POJO) Decode Call Resource Method Encode Resource Method Inputs (Java Objects) Outputs (Java Object) Jakarta EE Container
  30. How to make Requester • Program for Requester (1) 33

    String response = ClientBuilder.newClient()  Create a client object .target("http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/hello")  Set target URI .request(MediaType.TEXT_PLAIN)  Set MIME type of Returned Entity .get(String.class);  Send a GET request expecting String type as a Returned Entity Requester final String VISITOR_NAME = “Smith”; WebTarget myResource = ClientBuilder.newClient() .target("http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/visit1") .path("{visitorName}")  Set Path Parameter using template name .resolveTemplate("visitorName", VISITOR_NAME)  Set value for the above template name String response = myResource .request(MediaType.TEXT_PLAIN) .get(String.class); Request Line: GET /jaxrs_jsf_jpa/webapi/restService/visit1/Smith Request Line: GET /jaxrs_jsf_jpa/webapi/restService/hello
  31. How to make Requester • Program for Requester (2) 34

    final String VISITOR_NAME = “Smith”; WebTarget myResource = ClientBuilder.newClient() .target("http:// localhost:8080/jaxrs_jsf_jpa/webapi/restService/visit2") .queryParam(“visitorName", VISITOR_NAME);  Specify a Query Parameter set String response = myResource.request(MediaType.TEXT_PLAIN).get(String.class); Requester final String VISITOR_NAME = “Smith”; Form form = new Form(); form.param("visitorName", VISITOR_NAME); WebTarget myResource = ClientBuilder.newClient() .target("http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/visit3 "); String response = myResource.request(MediaType.TEXT_PLAIN) .post(Entity.entity(form,MediaType.APPLICATION_FORM_URLENCODED_TYPE), String.class);  set POST request including a FORM encoded order Entity expecting String Class as a Returned Entity. Request Line: POST /jaxrs_jsf_jpa/webapi/restService/visit3, Body: <form> … <input … name=“visitorName” value=“Smith” …/> … </form> Request Line: GET /jaxrs_jsf_jpa/webapi/restService/visit2?visitorName=Smith
  32. How to make Requester • Program for Requester (3) 35

    Requester final String VISITOR_NAME = “Smith”; Visitor visitor = new Visitor(VISITOR_NAME); WebTarget myResource = ClientBuilder.newClient() .target("http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/visit4 "); String response = myResource.request(MediaType.TEXT_PLAIN) .post(Entity.entity(visitor, MediaType.APPLICATION_JSON), String.class);  set POST request including a FORM encoded order Entity expecting String Class as a Returned Entity. Request Line: POST /jaxrs_jsf_jpa/webapi/restService/visit4, Body: {“name”:”Smith”}
  33. How to make Requester • Program for Requester (4) 36

    Requester final Integer ID = 1; WebTarget myResource = ClientBuilder.newClient() .target("http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/milkProduct") .queryParam(“id", ID); MilkProduct product = myResource.request(MediaType.APPLICATION_JSON) .get(MilkProduct.class);  send a GET request expecting a custom class of “MilkProduct.class” as a Single Returned Entity Request Line: GET /jaxrs_jsf_jpa/webapi/restService/milkProduct?id=1 List<MilkProduct> products = ClientBuilder.newClient() .target(" http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/milkProducts") .request(MediaType.APPLICATION_JSON) .get(new GenericType<List<MilkProduct>>() {});  Send a GET request expecting a Java Collection class of a custom class of “MilkProduct.class” as Multiple Returned Entities Request Line: GET /jaxrs_jsf_jpa/webapi/restService/milkProducts
  34. Architecture Design • Architecture Design with JAX-RS and JSF in

    Presentation Layer 38 Presentation REST Req. Handler Web Resource CDI Web Req. Handler Named CDI Action Method Business Domain Service Transactional CDI Service Method Data Access O-R Mapper Entity Entity RDB Entity Entity Name: Vendor: ABC XYZ Update Update Results: Name ABC Vendor XYZ DTO DTO Jakarta EE Container Requester JSON JSON Resource Method DTO DTO
  35. JAX-RS with CDI • Program for Web Resource Class with

    CDI 39 Web Resource Class (CDI) Resource Method @RequestScoped  Make this Web Resource Class work as a RequestScoped CDI Class @Path(“/restService“) public class RestService { : @Inject EnterpriseService service;  Inject a Transactional CDI : @GET @Path(“/getProduct”) @Produces(MediaType.APPLICATION_JSON) public Response showProducts(@QueryParam(“productId”) String productId) { Product productInfo = service.getProduct(productId); return Response.status(200).entity(productInfo).build(); } : }
  36. Requester Provider First JAX-RS Application Development Exercise • Use Case

     JUnit5 makes a GET request and obtains a message from a REST Service Provider. • GET Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/hello • Response Message: “Hello World!” in String (MIME Type: “text/plain”) 41 Jakarta EE Container Web Resource Class Resource Method REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/hello) REST Response Message (String: “Hello World!”) JUnit5 System Test (integration-test) Eclipse Exercise: Let’s make the First JAX-RS Application.
  37. This project of “jsf_jpa_jaxrs” is based on the “jsf_jpa” project

    and add necessary components newly created on the Eclipse IDE following the procedure described in the slides form the next page. • Right click on the “jsf_jpa” project and select “Copy” menu item and right click in “Project Explore” and select “Paste” menu item and name it “jsf_jpa_jaxrs” and click “Copy” button. • Confirm “JPA” in the “Project Facets” is unset by right-clicking on the project and select “Properties” “Project Facets” and checking “JPA” setting unset. 42 jsf_jpa Copy jsf_jpa_jaxrs • RestApplication : REST Custom App. • ResourceProvider : Web Resource Class • RestIT : System Test Class • … Add First JAX-RS Application Development Exercise
  38. • Procedure of the Development 43 First JAX-RS Application Development

    Exercise Edit pom.xml and Change package names Modify persistence.xml and Setup PostgreSQL Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester
  39. • Modify the Maven Object Model file (pom.xml) Change the

    artifactId to “jsf_jpa_jaxrs”. Add the 2 dependency artifacts for REST Client in the the REST Interface Test : <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>jsf_jpa_jaxrs</artifactId> <packaging>war</packaging> <version>0.0.1</version> : 44 Revised pom.xml : <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-client</artifactId> <version>4.0.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.glassfish.jersey.inject</groupId> <artifactId>jersey-hk2</artifactId> <version>4.0.0</version> <scope>test</scope> </dependency> : First JAX-RS Application Development Exercise
  40. • Change the package names Refactor all the packages to

    rename the packages from “jsf_jpa” to “jsf_jpa_jaxrs” creating new packages of “org.example.jsf_jpa_jaxrs.rest” under “src/main/java” and “src/test/java”. 45 New Package Names New New First JAX-RS Application Development Exercise Rename Rename Rename Rename Rename Rename
  41. • Procedure of the Development 46 First JAX-RS Application Development

    Exercise Edit pom.xml and Change package names Modify persistence.xml and Setup PostgreSQL Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester
  42. • Modify the JPA configuration file (persistence.xml) for CDI Unit

    Test Modify the class package names of the Persistence Unit in the copied persistence.xml under the folder of “src/test/resources/META-INF” for CDI Unit Test like the following. <persistence-unit name="persistenceUnit4Test" transaction-type="RESOURCE_LOCAL"> <!-- To make it work on JavaSE, we have to specify all used classes like the followings --> <class>org.example.jsf_jpa_jaxrs.domain.Department</class> <class>org.example.jsf_jpa_jaxrs.domain.Employee</class> <properties> <property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:postgresql://[host name]/jpa_db" /> <property name="javax.persistence.jdbc.user" value=“jpa_exercise" /> <property name="javax.persistence.jdbc.password" value=“jpa_exercise" /> <!-- EclipseLink should create the database schema automatically --> <property name="eclipselink.ddl-generation" value="create-tables" /> <property name="eclipselink.ddl-generation.output-mode" value="database" /> <property name="eclipselink.logging.level" value="SEVERE"/> <property name="eclipselink.target-database" value="PostgreSQL" /> </properties> </persistence-unit> 47 First JAX-RS Application Development Exercise
  43. • Procedure of the Development 48 Edit pom.xml and Change

    package names Modify persistence.xml and Setup PostgreSQL Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester First JAX-RS Application Development Exercise First JAX-RS Application Development Exercise
  44. • Change the Message folder Rename the Message folder to

    “org/example/jsf_jpa_jaxrs”. • Change the Message Utility Class Modify “BUNDLE_NAME” in Message Utility Class, Messages.java, under the package of “org.example. jsf_jpa_jaxrs.util” because of the changed folder name. 49 New Message Folder Name Revised Messages.java (src/main/java/org.example.jsf_jpa_jaxrs.util) Renamed Renamed First JAX-RS Application Development Exercise
  45. • Procedure of the Development 50 First JAX-RS Application Development

    Exercise First JAX-RS Application Development Exercise Edit pom.xml and Change package names Modify persistence.xml and Setup PostgreSQL Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester
  46. • Create required Classes 1. Create a new Web Resource

    Class, ResourceProvider.java, of the “org.example.jsf_jpa_jaxrs.rest” package under the “src/main/java” folder, which specifies the Web Resource Class Path of “/restService” and it returns a String message of “Hello World!” whose MIME type is “text/plain” as a response to the HTTP GET request for the Resource Method Path of “/hello” by creating a Resource Method of “hello()”. 2. Create a new Custom REST Application Class, RestApplication.java, of the “org.example.jsf_jpa_jaxrs.rest” package under the “src/main/java” folder to specify an Application Path of “webapi” and the ResouceProvider.java as a Web Resource Class. 3. A new System Test Class, RestIT.java, of the “org.example.jsf_jpa_jaxrs.rest” package under the “src/test/java” folder is provided to execute a System Test for the ResourceProvider.class. 51 First JAX-RS Application Development Exercise
  47. • RestIT.java (1) – Preparation for System Test  A

    new System Test Class, RestIT.java, of the “org.example.jsf_jpa_jaxrs.rest” package under the “src/test/java” folder is provided to execute a System Test for the ResourceProvider.class. 52 class RestIT { private static Client client; private static String baseUri = ""; @BeforeAll public static void loadTestConfig() { final String hostname = System.getProperty("servlet.host"); final String port = System.getProperty("servlet.port"); final String context = System.getProperty("servlet.context"); final String REST_APPLICATION_PATH = "webapi"; baseUri = "http://" + hostname + ":" + port + "/" + context + "/" + REST_APPLICATION_PATH; client = ClientBuilder.newClient(); } First JAX-RS Application Development Exercise
  48. • RestIT.java (2) – Execution of the System Test 53

    @Test public void testHello() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/hello"; String response = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH) .request(MediaType.TEXT_PLAIN) .get(String.class); assertTrue(response.contains("Hello World!")); } } First JAX-RS Application Development Exercise
  49. • Final Java Source Folder Structure 54 Provided New New

    First JAX-RS Application Development Exercise
  50. • Procedure of the Development 55 First JAX-RS Application Development

    Exercise Edit pom.xml and Change package names Modify persistence.xml and Setup PostgreSQL Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester
  51. • Execute JUnit through M2Eclipse™ for the provided REST System

    Test Class (1)  Right click on the project and select “Run As”  “4 Maven build”  Specify “jsf_jpa_jaxrs – integration-test (Remote)” for the “Name” field and “clean integration-test” for the “Goals” field. 56 First JAX-RS Application Development Exercise
  52. • Execute JUnit through M2Eclipse™ for the provided REST System

    Test Class (2)  Click “Run” button. Confirm that test completes successfully in “Console” 57 First JAX-RS Application Development Exercise First JAX-RS Application Development Exercise
  53. • Procedure of the Development 58 First JAX-RS Application Development

    Exercise First JAX-RS Application Development Exercise Edit pom.xml and Change package names Modify persistence.xml and Setup PostgreSQL Change the Message folder and the associated Class Create the Required Class Execute the REST System Test with Maven Test with Talend API Tester
  54. • Install “Talend API Tester – Free Edition”  With

    Chrome browser, access to https://chrome.google.com/webstore/detail/talend-api-tester-free -ed/aejoelaoggembcahagimdiliamlcdmfm?hl=en to install “Talend API Tester – Free Edition”.  Click “Add to Chrome” button 59 First JAX-RS Application Development Exercise
  55. • Execute “Talend API Tester – Free Edition” (1) –

    Request REST Service  Click the icon of on the Chrome browser.  Select “Get” Method and specify “http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/hello” as the URI and click the “Send” button. 60 First JAX-RS Application Development Exercise
  56. • Execute “Talend API Tester – Free Edition” – Response

    for the REST Service Request  Confirm that the expected HEADERS and BODY were responded. 61 First JAX-RS Application Development Exercise
  57. Requester Provider Other JAX-RS Programming Exercises • Use Case (1)

     JUnit5 makes a GET request with a PATH Parameter of a user name and obtains a message including the user name from a REST Service Provider. • GET Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit1/Smith • Response Message: “Welcome to the REST World, Smith” in String (MIME Type: “text/plain”) 63 Jakarta EE Container Web Resource Class Resource Method REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit1/Smith) REST Response Message (String: “Welcome to the REST World, Smith!”) JUnit5 System Test (integration-test) Eclipse
  58. Other JAX-RS Programming Exercises • Use Case (2)  JUnit5

    makes a GET request with a Query Parameter of a user name and obtains a message including the user name from a REST Service Provider. • GET Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit2? visitorName=“Smith” • Response Message: “Welcome to the REST World, Smith” in String (MIME Type: “text/plain”) 64 REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit2? visitorName=Smith) REST Response Message (String: “Welcome to the REST World, Smith!”) Requester JUnit5 System Test (integration-test) Eclipse Provider Jakarta EE Container Web Resource Class Resource Method
  59. Other JAX-RS Programming Exercises • Use Case (3)  JUnit5

    makes a POST request with a Form Parameter of a user name and obtains a message including the user name from a REST Service Provider. • POST Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit3 • POST Request Body: <form> … <input … name=“visitorName” value=“Smith” …/> … </form> • Response Message: “Welcome to the REST World, Smith” in String (MIME Type: “text/plain”) 65 REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit3, Body:<form> … <input … name=“visitorName” value=“Smith” …/> … </form>) REST Response Message (String: “Welcome to the REST World, Smith!”) Requester JUnit5 System Test (integration-test) Eclipse Provider Jakarta EE Container Web Resource Class Resource Method
  60. Other JAX-RS Programming Exercises • Use Case (4)  JUnit5

    makes a POST request with a JSON Object including a user name and obtains a message including the user name from a REST Service Provider. • POST Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit4 • POST Request Body: {“name”:“Smith”} • Response Message: “Welcome to the REST World, Smith” in String (MIME Type: “text/plain”) 66 REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit4, Body: {“name”:“Smith”}) REST Response Message (String: “Welcome to the REST World, Smith!”) Requester JUnit5 System Test (integration-test) Eclipse Provider Jakarta EE Container Web Resource Class Resource Method
  61. Other JAX-RS Programming Exercises • Use Case (5)  JUnit5

    makes a GET request with a Query Parameter of the ID and obtains a JSON message including the product name based on the ID from a REST Service Provider. • GET Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/milkProduct?id=1 • Response Message: “{"product": "Cheese"}” in JSON (MIME Type: “application/json”) 67 REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/milkProduct? id=1) REST Response Message (JSON: {"product": "Cheese"}) Requester JUnit5 System Test (integration-test) Eclipse Provider Jakarta EE Container Web Resource Class Resource Method id product 1 Cheese 2 Milk 3 Yogurt
  62. Provider Web Resource Class Other JAX-RS Programming Exercises • Use

    Case (6)  JUnit5 makes a GET request and obtains a JSON message including the list of product names from a REST Service Provider. • GET Request URI: http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/milkProducts • Response Message: “[{"product": "Cheese"}, {"product": “Milk"}, {"product": “Yogurt"}]” in JSON (MIME Type: “application/json”) 68 Jakarta EE Container Resource Method REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/milkProducts) REST Response Message (JSON: [{"product": "Cheese"},{"product": “Milk"},{"product": “Yogurt"}]) product Cheese Milk Yogurt Requester JUnit5 System Test (integration-test) Eclipse
  63. Other JAX-RS Programming Exercises • Modify the Maven Object Model

    file (pom.xml) Add the 1 dependency artifacts for REST Client in the the REST Interface Test to use JSON media conversion in Use Case (5) and (6). 69 Revised pom.xml : <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-json-jackson</artifactId> <version>4.0.0</version> <scope>test</scope> </dependency> :
  64. Other JAX-RS Programming Exercises • Development Procedure on Eclipse™ 1.

    Create a new “Visitor.java” of the “org.example.jsf_jpa_jaxrs.rest” package in the “src/main/java” folder for the additional Resource Methods for Use Case (4). This class has a String of “name” as its property which accommodates a user name. The class also has the default constructor, a constructor which accepts the name as a parameter, accessors like a getter and a setter for the property. 2. Create a new “MilkProduct.java” of the “org.example.jsf_jpa_jaxrs.rest” package in the “src/main/java” folder for the additional Resource Methods for Use Case (5) and (6). This class has a String of “product” as its property which accommodates a product name. The class also has the default constructor, a constructor which accepts the product as a parameter, accessors like a getter and a setter for the property. 3. Modify the Web Resource Class of “ResourceProvider.java” to implement Resource Methods for all the Use Cases. 4. Modified “RestIT.java” is provided to test the Web Resource Class you developed. 5. Execute the above System Test and confirm all the Tests are passed with M2Eclipse. 6. Send several requests to the new Provider with Talend API Tester and confirm every Use Case is OK. 70
  65. Other JAX-RS Programming Exercises • RestIT.java – System Test for

    Use Case (1) 71 @Test public void testVisit1() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/visit1"; final String VISITOR_NAME = "Smith"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH).path("{visitorName}") .resolveTemplate("visitorName", VISITOR_NAME); String response = myResource.request(MediaType.TEXT_PLAIN).get(String.class); assertTrue(response.contains(VISITOR_NAME)); }
  66. Other JAX-RS Programming Exercises • RestIT.java – System Test for

    Use Case (2) 72 @Test public void testVisit2() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/visit2"; final String VISITOR_NAME = "Smith"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH) .queryParam("visitorName", VISITOR_NAME); String response = myResource.request(MediaType.TEXT_PLAIN).get(String.class); assertTrue(response.contains(VISITOR_NAME)); }
  67. Other JAX-RS Programming Exercises • RestIT.java – System Test for

    Use Case (3) 73 @Test public void testVisit3() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/visit3"; final String VISITOR_NAME = "Smith"; Form form = new Form(); form.param("visitorName", VISITOR_NAME); WebTarget myResource = ClientBuilder.newClient().target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); String response = myResource.request(MediaType.TEXT_PLAIN) .post(Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE), String.class); assertTrue(response.contains(VISITOR_NAME)); }
  68. Other JAX-RS Programming Exercises • RestIT.java – System Test for

    Use Case (4) 74 @Test public void testVisit4() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/visit4"; final String VISITOR_NAME = "Smith"; Visitor visitor = new Visitor(VISITOR_NAME); WebTarget myResource = ClientBuilder.newClient().target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); String response = myResource.request(MediaType.TEXT_PLAIN) .post(Entity.entity(visitor, MediaType.APPLICATION_JSON), String.class); assertTrue(response.contains(VISITOR_NAME)); }
  69. Other JAX-RS Programming Exercises • RestIT.java – System Test for

    Use Case (5) 75 @Test public void testMilkProduct() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/milkProduct"; final String PRODUCT_NAME = "Cheese"; final Integer ID = 1; WebTarget myResource = ClientBuilder.newClient().target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH) .queryParam("id", ID); MilkProduct product = myResource.request(MediaType.APPLICATION_JSON) .get(MilkProduct.class); assertTrue(product.getProduct().contains(PRODUCT_NAME)); }
  70. Other JAX-RS Programming Exercises • RestIT.java – System Test for

    Use Case (6) 76 @Test public void testMilkProducts() { final String WEB_RESOURCE_PATH = "/restService"; final String RESOURCE_METHOD_PATH = "/milkProducts"; final Integer SIZE = 3; WebTarget myResource = ClientBuilder.newClient().target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); List<MilkProduct> products = myResource.request(MediaType.APPLICATION_JSON) .get(new GenericType<List<MilkProduct>>() {}); assertEquals(products.size(), SIZE); }
  71. Managing Departments with REST Exercise • Required features  Create

    a new Web Resource Class which provides the Personnel Service managing “Department” Entities with CRUD operations.  The Web Resource Class is implemented as a Request Scoped CDI component and its Web Resource Class path is “/personnelService”.  Create several Resource Methods to query Entities (path:/getAllDepartments) and create an Entity (path:/newDepartment), update (path:/updateDepartment) and remove (path:/deleteDepartment) an Entity. 79 Requester Presentation Jakarta EE Container Web Resource CDI (Request Scoped) Resource Methods REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/ webapi/personelService/newDepartment Body(JSON): {.., “name”:“Marketing”, …}) REST Response Message (JSON: {“id": “123“, “version”: “1”, …}) JUnit5 System Test (integration-test) Eclipse Business Data Access Transactional CDI O-R Mapper Provider Domain Service Business Methods RDB
  72. • PersonnelServiceIT.java – System Test for Managing Departments (Initialize DB)

    80 @Test public void testManageDepartment() { final String WEB_RESOURCE_PATH = "/personnelService"; // Initialize DB deleting all the data in DB String RESOURCE_METHOD_PATH = "/initializeDB"; WebTarget myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); Integer result = myResource.request(MediaType.TEXT_PLAIN).get(Integer.class); assertEquals(result, new Integer(Response.Status.OK.getStatusCode())); : Managing Departments with REST Exercise
  73. • PersonnelServiceIT.java – System Test for Managing Departments (Create a

    new Entity) 81 : // Create a New Department Entity whose “name” property is “Marketing” RESOURCE_METHOD_PATH = "/newDepartment"; Department department = new Department("Marketing"); myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); department = myResource.request(MediaType. APPLICATION_JSON) . post(Entity.entity(department, MediaType.APPLICATION_JSON), Department.class); assertNotNull(department); assertEquals(department.getName(), "Marketing"); : Managing Departments with REST Exercise
  74. • PersonnelServiceIT.java – System Test for Managing Departments (Update the

    Entity) 82 : // Update the Department Entity to have the new “name” property of “R&D” RESOURCE_METHOD_PATH = "/updateDepartment"; department .setName("R&D"); myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); department = myResource.request(MediaType. APPLICATION_JSON) . put(Entity.entity(department, MediaType.APPLICATION_JSON), Department.class); assertNotNull(department); assertEquals(department.getName(), "R&D"); : Managing Departments with REST Exercise
  75. • PersonnelServiceIT.java – System Test for Managing Departments (Obtain all

    the Entities) 83 : // Obtain all the Department Entities RESOURCE_METHOD_PATH = "/getAllDepartments"; myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); List<Department> departments = myResource.request(MediaType.APPLICATION_JSON) .get(new GenericType<List<Department>>() {}); assertNotNull(departments); assertEquals(departments.size(), 1); assertEquals(departments.get(0).getName(), "R&D"); : Managing Departments with REST Exercise
  76. • PersonnelServiceIT.java – System Test for Managing Departments (Delete the

    Entity) 84 : // Delete the Department Entity which was created and updated RESOURCE_METHOD_PATH = "/deleteDepartment"; myResource = client.target(baseUri + WEB_RESOURCE_PATH + RESOURCE_METHOD_PATH); result = myResource.queryParam("id", department.getId()).queryParam("version", department.getVersion()) .request(MediaType.TEXT_PLAIN) .delete(Integer.class); assertEquals(result, new Integer(Response.Status.OK.getStatusCode())); } Managing Departments with REST Exercise
  77. • Final Java Source Folder Structure 85 Provided Modify New

    Modify Managing Departments with REST Exercise