DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Low-Code Development: Leverage low and no code to streamline your workflow so that you can focus on higher priorities.

DZone Security Research: Tell us your top security strategies in 2024, influence our research, and enter for a chance to win $!

Launch your software development career: Dive head first into the SDLC and learn how to build high-quality software and teams.

Open Source Migration Practices and Patterns: Explore key traits of migrating open-source software and its impact on software development.

Related

  • Enterprise RIA With Spring 3, Flex 4 and GraniteDS
  • Migrating Spring Java Applications to Azure App Service (Part 1: DataSources and Credentials)
  • How To Build Web Service Using Spring Boot 2.x
  • Visually Designing Views for Java Web Apps

Trending

  • Enhance IaC Security With Mend Scans
  • Tackling Records in Spring Boot
  • Mastering System Design: A Comprehensive Guide to System Scaling for Millions, Part 2
  • GenAI: Spring Boot Integration With LocalAI for Code Conversion
  1. DZone
  2. Coding
  3. Frameworks
  4. Standalone Java application with Jersey and Jetty

Standalone Java application with Jersey and Jetty

I’ve built a small example of running a standalone Java application that both serves static HTML, JavaScript, CSS content, and also publishes a REST web service.

By 
Alan Hohn user avatar
Alan Hohn
·
Jul. 07, 15 · Tutorial
Like (3)
Save
Tweet
Share
38.4K Views

Join the DZone community and get the full member experience.

Join For Free

Introduction

I’ve built a small example of running a standalone Java application that both serves static HTML, JavaScript, CSS content, and also publishes a REST web service. The example uses Jersey and Jetty. This example probably deserves a few posts to allow enough time to explain how the pieces fit together, so I’ll start with the primary Java pieces that make a JAX-RS application.

A couple years back, while I was working through some slides to teach a Java class (mostly Java EE and Spring) I created a REST web service using Spring WebMVC. I wrote a few posts (starting here) about how it works.

I’ve recently been teaching that class again, updating to later versions of Java and later versions of libraries. When I got to the Spring WebMVC class, I wanted to teach it, because I still think it’s a good choice for an application that uses the Spring framework (because it integrates with Spring dependency injection). But of course now we have the Java API for RESTful Web Services (JAX-RS) as an option.

So I’ve adapted the previous example to JAX-RS. Fortunately, some of the little tricks used with the Spring WebMVC application still apply.

Provider Class

JAX-RS divides the work of the REST web service amongst one or more provider classes. Each provider class handles a set of paths within the whole application, and each provider class can have multiple methods that handle specific paths and HTTP methods.

Provider classes are plain old Java objects (POJOs), using annotations to specify JAX-RS parameters. Here is the provider class for this application.

@Path("/calculator")
 public class Calculator {

      @GET
      @Path("/calc/{op}/{left}/{right}")
      public Calculation calculate(@PathParam("op") String op, @PathParam("left") Integer left,
              @PathParam("right") Integer right) {
          Calculation result = new Calculation();
          result.setOperation(op);
         result.setLeft(left);
         result.setRight(right);
         return doCalc(result);
     }

     @POST
     @Path("/calc2")
     public Calculation calculate(Calculation calc) {
         return doCalc(calc);
     }

     private Calculation doCalc(Calculation c) {
         String op = c.getOperation();
         int left = c.getLeft();
         int right = c.getRight();
         if (op.equalsIgnoreCase("subtract")) {
             c.setResult(left - right);
         } else if (op.equalsIgnoreCase("multiply")) {
             c.setResult(left * right);
         } else if (op.equalsIgnoreCase("divide")) {
             c.setResult(left / right);
         } else {
             c.setResult(left + right);
         }
         return c;
     }

 }

The example illustrates both GET and POST HTTP methods, and illustrates passing in parameters, either via components of the URL or via the request body.

The key annotations used above are:

  • @Path: Adds a path component for matching the incoming URL. Path components are cumulative, so the class annotation and the method annotation work together. The path can contain templates used to supply parameters.
  • @GET: Specifies a method that handles HTTP GET requests.
  • @POST: Specifies a method that handles HTTP POST requests.
  • @PathParam: Associates a template in the URL with a method parameter.

Not illustrated in this example is @QueryParam, which works similar to@PathParam but instead matches a form input (either encoded in the URL as ?name1=value1&name2=value2 pairs, or in a name=value list with linebreaks in the request body).

For those familiar with Spring WebMVC, note that the annotations are quite similar. Also note that some annotations, like @RequestBody and@ResponseBody to specify that the request body should be converted to a parameter, or the returned Java object should become the response body, are assumed rather than specified.

JAX-RS Application

The JAX-RS application class allows, among other things, customizing which packages are scanned for providers.



 public class CalculatorApp extends ResourceConfig {

     public CalculatorApp() {
         packages("org.anvard.jaxrs");
     }
}



ResourceConfig is a Jersey class that extends from the standard JAX-RSApplication class and provides package scanning and other helper applications. It also provides an implementation for the standard getClasses()and getSingletons() methods that we would otherwise have to supply ourselves.

web.xml

While it is possible with Servlet 3.0 to deploy applications without use of a deployment descriptor, it makes it easier to connect Jetty with Jersey when running using the Maven Jetty plugin.

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

    <servlet>
        <servlet-name>Calculator</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>org.anvard.jaxrs.server.CalculatorApp</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Calculator</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
</web-app>

This configuration uses a servlet provided by Jersey to delegate to the JAX-RS application class we defined earlier. This also allows us to specify the first component of the path for JAX-RS services (to keep them distinct from static files, which we also want to serve).

Deploying and Running

The Maven POM file handles building a JAR (for a standalone application, discussed in the next post), and a WAR (for deploying to a Servlet container). It also includes the Maven Jetty plugin, allowing us to run the application from the command line using mvn jetty:run.

Client Requirements

The example includes both JavaScript and Java clients, which I will discuss in another post. Any Web client can of course be used, but note that this REST service is careful about responding to clients.

We list a dependency on the Jersey plugin for Jackson, so we can move between Java and JSON. However, the client must specify the header Accept: application/json; otherwise, the server defaults to XML. Also, when supplying data to the server for the POST request, the client must also specify aContent-Type: application/json header.

Next Steps

The next post will provide detail on running the service in a regular Java application using an embedded Jetty server.




application Java (programming language) Jetty (web server) Spring Framework Web Service

Published at DZone with permission of Alan Hohn, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Enterprise RIA With Spring 3, Flex 4 and GraniteDS
  • Migrating Spring Java Applications to Azure App Service (Part 1: DataSources and Credentials)
  • How To Build Web Service Using Spring Boot 2.x
  • Visually Designing Views for Java Web Apps

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: