blob: 4625dda34685d4e7314e3962cb73b6169436609c [file] [log] [blame]
<?php
/**
* Copyright (c) 2020 Eclipse Foundation.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Martin Lowe (Eclipse Foundation) - Initial implementation
*
* SPDX-License-Identifier: EPL-2.0
*/
// This file must be included
if (basename(__FILE__) == basename($_SERVER['PHP_SELF'])) {
exit();
}
?>
<h1 class="article-title"><?php echo $pageTitle; ?></h1>
<p>In this article, I&rsquo;ll walk you through the steps required to create a simple web service with <a href="https://jakarta.ee/">Jakarta EE 8</a>. The example web service creates a Web Application Resource (WAR) file that can be deployed to any Jakarta EE 8-compliant application server container, including micro-containers such as Payara Micro and WildFly.</p>
<p>The headings below outline the main steps to create the web service and most steps include example code.</p>
<h2>Create a Maven-Based WAR File Project</h2>
<p>You can create the file in your favorite IDE. The most prevalent IDEs for developing Jakarta EE 8 applications include the <a href="https://www.eclipse.org/eclipseide/">Eclipse IDE</a>, IntelliJ, and Apache NetBeans. Another option is to download the Jakarta EE starter project.</p>
<p>I start with the Jakarta EE starter project, then I open it and develop within the Apache NetBeans 12 IDE. I deploy the web service to the Payara Micro platform.</p>
<p>To get started, download and unzip the Jakarta EE starter project <a href="https://eclipse-ee4j.github.io/starter/samples/simple-hello.zip">simple-hello.zip</a> and copy it into a working directory on your computer. Open the project in your IDE and rename it to PoolService-1.0-SNAPSHOT, as shown in Figure 1.</p>
<p><span style="font-size:12px">Figure 1: Renaming the Project</span></p>
<p><img class="img-responsive" src="images/2-1.png"></p>
<h2>Add a Root Path for Jakarta RESTful Web Services Resources</h2>
<p>Adding a path to the class named <code>org.demo.simple.ApplicationConfig</code> creates a root path for your Jakarta RESTful web services at the path &quot;resources.&rdquo; To access Jakarta RESTful Web Services (JAX-RS) resources, preface the service name with this path.</p>
<p>When you&rsquo;re finished, the code should look like the example below.</p>
<pre>
<code>
package com.demo.simple;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
/**
* Configures the Jakarta REST application.
*
* @author Ivar Grimstad (ivar.grimstad@eclipse-foundation.org)
*/
@ApplicationPath("resources")
public class ApplicationConfig extends Application {
}
</code>
</pre>
<h2>Create the Temperature Controller Class</h2>
<p>The <code>TemperatureController</code> class is used to read the temperature file when it&rsquo;s invoked.</p>
<p>To create the class, create a new Java class named <code>org.demo.simple.TemperatureController</code>, which is responsible for reading the file and setting values within variables. The temperature will be in the format (23.5, 74.3) with the first reading being in Celsius, and the second reading being in Fahrenheit.</p>
<p>Here&rsquo;s an example <code>TemperatureController</code> class for reference.</p>
<pre>
<code>
package com.demo.simple;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
/**
*
* @author juneau
*/
@Named
@RequestScoped
public class TemperatureController {
private String currentTemperatureF;
private String currentTemperatureC;
public TemperatureController(){
}
protected String readTemperatureFile() {
String temperatureFile = "&lt;&lt;path-to-file&gt;&gt;/temperature.txt";
java.nio.file.Path path = Paths.get(temperatureFile);
String currentTemperature = null;
try (BufferedReader reader = Files.newBufferedReader(path, Charset.forName("UTF-8"))) {
String currentLine = null;
while ((currentLine = reader.readLine()) != null) {//while there is content on the current line
currentTemperature = currentLine;
}
} catch (IOException ex) {
ex.printStackTrace(); //handle an exception here
}
return currentTemperature;
}
/**
* @return the currentTemperatureF
*/
public String getCurrentTemperatureF() {
String temp = readTemperatureFile();
currentTemperatureF = temp.substring(temp.indexOf(",") + 1, temp.lastIndexOf(")"));
return currentTemperatureF;
}
/**
* @param currentTemperatureF the currentTemperatureF to set
*/
public void setCurrentTemperatureF(String currentTemperatureF) {
this.currentTemperatureF = currentTemperatureF;
}
/**
* @return the currentTemperatureC
*/
public String getCurrentTemperatureC() {
String temp = readTemperatureFile();
currentTemperatureC = temp.substring(temp.indexOf("(") + 1, temp.lastIndexOf(","));
return currentTemperatureC;
}
/**
* @param currentTemperatureC the currentTemperatureC to set
*/
public void setCurrentTemperatureC(String currentTemperatureC) {
this.currentTemperatureC = currentTemperatureC;
}
}
</code>
</pre>
<p>An interested service can now use Jakarta <a href="https://jakarta.ee/specifications/cdi/">Contexts and Dependency Injection (CDI)</a> to inject <code>TemperatureController</code> and call on <code>getCurrentTemperatureF()</code> or <code>getCurrentTemperatureC()</code> to obtain the requested temperature format.</p>
<h2>Create the Temperature Resource File</h2>
<p>The <code>TemperatureResource</code> file is a JAX-RS file that includes the code shown below.</p>
<pre>
<code>
package com.demo.simple;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PUT;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.ws.rs.core.MediaType;
/**
* JAX-RS Web Service
*
* @author juneau
*/
@Path("temperature")
@RequestScoped
public class TemperatureResource {
@Inject
private TemperatureController temperatureController;
/**
* Creates a new instance of TemperatureResource
*/
public TemperatureResource() {
}
/**
* Calls upon the TemperatureController and obtains the current temperature
* in Fahrenheit.
*
* @return an instance of java.lang.String
*/
@GET
@Produces({MediaType.TEXT_PLAIN})
public String getXml() {
String currentTemperature = temperatureController.getCurrentTemperatureF();
return currentTemperature;
}
/**
* PUT method for updating or creating an instance of TemperatureResource
*
* @param content representation for the resource
*/
@PUT
@Consumes(MediaType.APPLICATION_XML)
public void putXml(String content) {
}
/**
* Calls upon the TemperatureController and retrieves the current temperature
* in Fahrenheit. Same as getXml();
* @return
*/
@GET
@Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Path("f")
public String getF() {
String currentTemperature = temperatureController.getCurrentTemperatureF();
return currentTemperature;
}
/**
* Calls upon the TemperatureController and retrieves the current temperature
* in Celsius.
* @return
*/
@GET
@Produces({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
@Path("c")
public String getC() {
String currentTemperature = temperatureController.getCurrentTemperatureC();
return currentTemperature;
}
}
</code>
</pre>
<p>This is a web service that will be made available at the URI <code>/resources/temperature</code>, so when the URL <code>http://localhost:8080/poolService/resources/temperature</code> is entered, the temperature in Fahrenheit is displayed. This happens because the method named <code>getXml()</code> is called by default as it is annotated with <code>@GET</code> and does not contain a path. It returns plain text because it is annotated with <code>@Produces({MediaType.TEXT_PLAIN})</code>.</p>
<p>To change the default format to another format, such as XML, you can modify the <code>@Produces</code> annotation to: <code>@Produces({MediaType.APPLICATION_JSON})</code>.</p>
<p>The <code>getXml()</code> method invokes the <code>TemperatureController getCurrentTemperatureF()</code> method to read the temperature and return the result.</p>
<h2>Compile and Build the Project</h2>
<p>Use your favorite IDE, or the command line, to compile and build the project to create a WAR file named <code>simple-hello.war</code>.</p>
<h2>Deploy the Web Service</h2>
<p>I&rsquo;m going to use a micro container to deploy the web service. However, it could also be deployed into any other Jakarta EE-compatible container such as <a href="https://eclipse-ee4j.github.io/glassfish/">Eclipse GlassFish</a>, Payara Server, or Open Liberty. For a complete list of compatible implementations, click <a href="https://jakarta.ee/compatibility/">here</a>.</p>
<p>In this case:</p>
<ul>
<li>Download Payara Micro 5.2020.4 and place the downloaded Java archive (JAR) file into a directory.</li>
<li>Open a terminal and type the code shown below to start Payara Micro and deploy the WAR file: <code>java -jar payara-micro-5.2020.4.jar --deploy &lt;path-to-war-file&gt;/simple-hello.war</code></li>
</ul>
<p>The terminal output will look similar to the example shown below.</p>
<pre>
<code>
Payara Micro URLs:
http://&lt;your-machine&gt;:8080/simple-hello
'simple-hello' REST Endpoints:
GET /simple-hello/resources/application.wadl
GET /simple-hello/resources/hello
GET /simple-hello/resources/temperature
PUT /simple-hello/resources/temperature
GET /simple-hello/resources/temperature/c
GET /simple-hello/resources/temperature/f
]]
</code>
</pre>
<h2>Run the Web Service</h2>
<p>Type the following URL into a browser: <code>http://&lt;your-machine&gt;:8080/simple-hello/resources/temperature</code></p>
<h2>Get More Information</h2>
<p>To learn more about getting started with Jakarta EE, visit the <a href="https://eclipse-ee4j.github.io/starter/">Jakarta EE starter page</a>. You&rsquo;ll find tutorials, examples, and more.</p>
<p>To get involved with the Jakarta EE community, check out our <a href="https://jakarta.ee/connect/">Stay Connected page</a> to choose your preferred method of communications.</p>
<div class="margin-bottom-20">
<?php print $Theme->getShareButtonsHTML(); ?>
</div>
<div class="bottomitem margin-bottom-20">
<h3>About the Author</h3>
<div class="row">
<div class="col-sm-24">
<div class="row margin-bottom-20">
<div class="col-sm-8">
<img class="img-responsive" alt="<?php print $pageAuthor; ?>" src="images/joshj.png" />
</div>
<div class="col-sm-16">
<p class="author-name"><?php print $pageAuthor; ?></p>
<p class="author-bio">
Josh Juneau is an application developer, database administrator, technical writer, and Java evangelist. <a href="http://jj-blogger.blogspot.com/">Visit his blog</a> to learn from his experiences in Java, JavaEE, PL/SQL, and Python/Jython development. Follow Josh on Twitter, <a href="https://twitter.com/javajuneau">@javajuneau</a>.
</p>
</div>
</div>
</div>
</div>
</div>