Slide 1

Slide 1 text

JAKARTA RESTFUL WEB SERVICES (JAX-RS) (VER. 3.1) A part of Jakarta EE™ specification RESTful Web Service Framework 1 By Koichi NAKAGAWA Enterprise Web Application Development Course (6)

Slide 2

Slide 2 text

Update Information • 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

Slide 3

Slide 3 text

JAX-RS Jakarta RESTful Web Services (JAX-RS) 3

Slide 4

Slide 4 text

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 Windows 10™ + Linux (Rocky Linux™) Total EWA Development Exercise Jakarta Batch Java SE (Oracle JDK™/OpenJDK™) Required Skills to take courses Test Tool with JUnit5 PostgreSQL™ Administration 4

Slide 5

Slide 5 text

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 GitTeam 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

Slide 6

Slide 6 text

Assumption for this course • The trainees who take this course are required the following skills in advance • PostgreSQL (Version: 13.5) – Basic Administration Operations • Payara Server (Version: 6.2021.1.Alpha1) – Basic Administration Operations • Oracle JDK/OpenJDK (Version: 11) • Eclipse IDE for Enterprise Java Developers (Version: 2021-12 (4.22.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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

Concept of Jakarta RESTful WebServices (JAX-RS) 9

Slide 10

Slide 10 text

Concept of JAX-RS • Communications between Applications 10 Requester (Server) Provider (Another Server) Service Request Message Response Message Application A Application B

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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.

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

How to use JAX-RS 15

Slide 16

Slide 16 text

How to configure JAX-RS Engine • Architecture of JAX-RS 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

Slide 17

Slide 17 text

How to configure JAX-RS Engine • What is Application Path? 17 JAX-RS Engine Decode Call Resource Method Encode 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.

Slide 18

Slide 18 text

How to configure JAX-RS Engine • Configuration of Application Path (2 Ways) 18 JAX-RS Engine Decode Call Resource Method Encode 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

Slide 19

Slide 19 text

How to configure JAX-RS Engine • Configuration of Application Path (By Custom Application) 19 JAX-RS Engine Decode Call Resource Method Encode 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> getClasses() { final Set> 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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

How to make Web Resource Class • Architecture of JAX-RS 21 Requestor 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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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!

Slide 25

Slide 25 text

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!

Slide 26

Slide 26 text

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: … … Response Message: Welcome to the REST World, Smith! Check the value of the “content-type” attribute of HTTP Request Header

Slide 27

Slide 27 text

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!

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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 milkProducts() { List 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 }

Slide 30

Slide 30 text

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 list = new ArrayList<>(); …. return Response.status(200).entity(new GenericEntity>(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 }

Slide 31

Slide 31 text

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 } }

Slide 32

Slide 32 text

How to make Requestor • Architecture of JAX-RS 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

Slide 33

Slide 33 text

How to make Requestor • Program for Requestor (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 Requestor 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

Slide 34

Slide 34 text

How to make Requestor • Program for Requestor (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); Requestor 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: … … Request Line: GET /jaxrs_jsf_jpa/webapi/restService/visit2?visitorName=Smith

Slide 35

Slide 35 text

How to make Requestor • Program for Requestor (3) 35 Requestor 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”}

Slide 36

Slide 36 text

How to make Requestor • Program for Requestor (4) 36 Requestor 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 products = ClientBuilder.newClient() .target(" http://localhost:8080/jaxrs_jsf_jpa/webapi/restService/milkProducts") .request(MediaType.APPLICATION_JSON) .get(new GenericType>() {});  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

Slide 37

Slide 37 text

Architecture Design with JAX-RS and CDI 37

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

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(); } : }

Slide 40

Slide 40 text

First JAX-RS Application 40

Slide 41

Slide 41 text

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.

Slide 42

Slide 42 text

First JAX-RS Application Development Exercise • This project of “jsf_jpa_jaxrs” is based on the “jsf_jpa” project and add necessary components newly created on the Eclipse IDE. 42 jsf_jpa Copy jsf_jpa_jaxrs • RestApplication : REST Custom App. • ResourceProvider : Web Resource Class • RestIT : System Test Class • … Add

Slide 43

Slide 43 text

First JAX-RS Application Development Exercise • Procedure of the Development 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 43

Slide 44

Slide 44 text

First JAX-RS Application Development Exercise • 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 : 4.0.0 org.example jsf_jpa_jaxrs war 0.0.1 : 44 Revised pom.xml : org.glassfish.jersey.core jersey-client 3.0.3 test org.glassfish.jersey.inject jersey-hk2 3.0.3 test :

Slide 45

Slide 45 text

First JAX-RS Application Development Exercise • 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

Slide 46

Slide 46 text

First JAX-RS Application Development Exercise • Procedure of the Development 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

Slide 47

Slide 47 text

First JAX-RS Application Development Exercise • 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. org.example.jsf_jpa_jaxrs.domain.Department org.example.jsf_jpa_jaxrs.domain.Employee 47

Slide 48

Slide 48 text

First JAX-RS Application Development Exercise • Procedure of the Development 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 48

Slide 49

Slide 49 text

First JAX-RS Application Development Exercise • 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

Slide 50

Slide 50 text

First JAX-RS Application Development Exercise • Procedure of the Development 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 50

Slide 51

Slide 51 text

First JAX-RS Application Development Exercise • 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

Slide 52

Slide 52 text

First JAX-RS Application Development Exercise • 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(); }

Slide 53

Slide 53 text

First JAX-RS Application Development Exercise • 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!")); } }

Slide 54

Slide 54 text

First JAX-RS Application Development Exercise • Final Java Source Folder Structure 54 Provided New New

Slide 55

Slide 55 text

First JAX-RS Application Development Exercise • Procedure of the Development 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 55

Slide 56

Slide 56 text

First JAX-RS Application Development Exercise • 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

Slide 57

Slide 57 text

First JAX-RS Application Development Exercise • Execute JUnit through M2Eclipse™ for the provided REST System Test Class (2)  Click “Run” button. Confirm that test completes successfully in “Console” 57

Slide 58

Slide 58 text

First JAX-RS Application Development Exercise • Procedure of the Development 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 58

Slide 59

Slide 59 text

First JAX-RS Application Development Exercise • 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

Slide 60

Slide 60 text

First JAX-RS Application Development Exercise • 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

Slide 61

Slide 61 text

First JAX-RS Application Development Exercise • Execute “Talend API Tester – Free Edition” – Response for the REST Service Request  Confirm that the expected HEADERS and BODY were responded. 61

Slide 62

Slide 62 text

Other JAX-RS Programming 62

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

Requester Provider 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 Jakarta EE Container Web Resource Class Resource Method 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!”) JUnit5 System Test (integration-test) Eclipse

Slide 65

Slide 65 text

Requester Provider 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: … … • Response Message: “Welcome to the REST World, Smith” in String (MIME Type: “text/plain”) 65 Jakarta EE Container Web Resource Class Resource Method REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/visit3, Body: … … REST Response Message (String: “Welcome to the REST World, Smith!”) JUnit5 System Test (integration-test) Eclipse

Slide 66

Slide 66 text

Requester Provider 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 Jakarta EE Container Web Resource Class Resource Method 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!”) JUnit5 System Test (integration-test) Eclipse

Slide 67

Slide 67 text

Requester Provider 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 Jakarta EE Container Web Resource Class Resource Method REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/webapi/restService/milkProduct? id=1) REST Response Message (JSON: {"product": "Cheese"}) JUnit5 System Test (integration-test) Eclipse id product 1 Cheese 2 Milk 3 Yogurt

Slide 68

Slide 68 text

Requester Provider 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 Web Resource Class 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"}]) JUnit5 System Test (integration-test) Eclipse product Cheese Milk Yogurt

Slide 69

Slide 69 text

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 : org.glassfish.jersey.media jersey-media-json-jackson 3.0.3 test :

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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)); }

Slide 72

Slide 72 text

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)); }

Slide 73

Slide 73 text

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)); }

Slide 74

Slide 74 text

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)); }

Slide 75

Slide 75 text

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)); }

Slide 76

Slide 76 text

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 products = myResource.request(MediaType.APPLICATION_JSON) .get(new GenericType>() {}); assertEquals(products.size(), SIZE); }

Slide 77

Slide 77 text

Other JAX-RS Programming Exercises • Final Java Source Folder Structure 77 Provided Modify New New

Slide 78

Slide 78 text

Exercise 78

Slide 79

Slide 79 text

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 Requestor Presentation Jakarta EE Container Web Resource CDI (Request Scoped) Resource Methods REST Request Message (URI:http://localhost:8080/jsf_jpa_jaxrs/w ebapi/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

Slide 80

Slide 80 text

Managing Departments with REST Exercise • 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())); :

Slide 81

Slide 81 text

Managing Departments with REST Exercise • 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"); :

Slide 82

Slide 82 text

Managing Departments with REST Exercise • 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"); :

Slide 83

Slide 83 text

Managing Departments with REST Exercise • 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 departments = myResource.request(MediaType.APPLICATION_JSON) .get(new GenericType>() {}); assertNotNull(departments); assertEquals(departments.size(), 1); assertEquals(departments.get(0).getName(), "R&D"); :

Slide 84

Slide 84 text

Managing Departments with REST Exercise • 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())); }

Slide 85

Slide 85 text

Managing Departments with REST Exercise • Final Java Source Folder Structure 85 Provided Modify New Modify