JAX-RS Restful Web Services with JNDI Datasource for MySQL in Tomcat

JAX-RS Restful Web Services with JNDI Datasource and Connection Pooling for MySQL in Tomcat

In this tutorial we will discuss how to set up JAX-RS RESTful web services and configure a JNDI Datasource with Connection Pooling in Tomcat and connect to MYSQL Database. JNDI (Java Naming and Directory Interface) provides and interface to multiple naming and directory services.

What is JNDI?

The Java Naming and Directory Interface ( JNDI) is an API that allows access into naming and directory services in Java programs. JNDI works by associating names with objects and provide a mechanism of finding objects based on their names. JNDI also focuses on directory services which is another extension of naming services. Using JNDI you can access services like LDAP (Lightweight Directory Access Protocol) and NDS (Novell Directory Services).

naming_service

What is Connection Pooling?

A Connection Pool is a cache of database connections that is actively maintained by the system so that connections may be reused whenever new requests can be used. By creating a connection pool we alleviate the need to create new connections to the database which are time consuming and costly database operations. By using connection pooling we effectively reduce connection creation time which improves system performance. A connection pool will maintain a cache of multiple open connections and reuse them as often as possible before opening up any new connections. The size and growth of the cache is maintained by the properties defined on the context.xml file.

How to Configure MySQL DataSource in Tomcat using JNDI Lookup

Using this tutorial, we will discuss the step by step process of setting up and configuring a MySQL Data Source for Tomcat using a JNDI lookup.

Getting Started

In order to run this tutorial yourself, you will need the following:

Required Libraries

Copy all of the following jars to WebContent->WEB-INF->lib folder.

asm-3.1.jar
jackson-core-asl-1.9.13.jar
jackson-core-lgpl-1.9.13.jar
jackson-jaxrs-1.9.13.jar
jackson-mapper-asl-1.9.13.jar
jackson-mapper-lgpl-1.9.13.jar
jackson-xc-1.9.13.jar
jersey-client-1.18.jar
jersey-core-1.18.jar
jersey-json-1.18.jar
jersey-server-1.18.jar
jersey-servlet-1.18.jar
jsr311-api-1.1.1.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.22.jar
persistence-api-1.0.2.jar

Complete Project Overview

I have added the project overview to give you a full view of the structure and show you all files contained in this sample project.

jax-rs_tomcat_jndi_proj

RESTful Web Service End Points

#URIMethodDescription
1/rest/tomcat/statusGETDisplays the current status of the API being used. Non-restricted REST end-point
2/rest/tomcat/showallcustomersGETShows all customers in the mySQL database and returns the data as JSON objects
3/rest/tomcat/getcustomer?id={id}GETSearches for an customer by its ID returning the customer as a JSON object.
4/rest/tomcat/addcustomerPOSTAdds a customer into our mySQL datastore return the customer as a JSON object.
5/rest/tomcat/updatecustomerPUTUpdate a customer in our mySQL datastore return the customer as a JSON object.
6/rest/tomcat/deletecustomer?id={id}DELETEDeletes a customer by its ID in the mySQL database returning a status of the operation as a JSON string

The Customer Model (Customer.java)

This will be used to as the object which we store and retrieve in order to test out our application. I added it because I wanted my web service to store and retrieve some Java object.

package com.avaldes.model;

import org.codehaus.jackson.annotate.JsonProperty;

public class Customer {
  private int customerId;
  private String firstName;
  private String lastName;
  private String address;
  private String city;
  private String state;
  private String zipCode;
  private int isActive;

  @JsonProperty(value = "customer-id")
  public int getCustomerId() {
    return customerId;
  }

  public void setCustomerId(int customerId) {
    this.customerId = customerId;
  }

  @JsonProperty(value = "first-name")
  public String getFirstName() {
    return firstName;
  }

  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }

  @JsonProperty(value = "last-name")
  public String getLastName() {
    return lastName;
  }

  public void setLastName(String lastName) {
    this.lastName = lastName;
  }

  @JsonProperty(value = "address")
  public String getAddress() {
    return address;
  }

  public void setAddress(String address) {
    this.address = address;
  }

  @JsonProperty(value = "city")
  public String getCity() {
    return city;
  }

  public void setCity(String city) {
    this.city = city;
  }

  @JsonProperty(value = "state")
  public String getState() {
    return state;
  }

  public void setState(String state) {
    this.state = state;
  }

  @JsonProperty(value = "zip-code")
  public String getZipCode() {
    return zipCode;
  }

  public void setZipCode(String zipCode) {
    this.zipCode = zipCode;
  }

  @JsonProperty(value = "is-active")
  public int getIsActive() {
    return isActive;
  }

  public void setIsActive(int isActive) {
    this.isActive = isActive;
  }

  @Override
  public String toString() {
    return "Customer [customerId=" + customerId + ", firstName=" 
			+ firstName + ", lastName=" + lastName + ", address=" 
			+ address + ", city=" + city + ", state=" + state 
			+ ", zipCode=" + zipCode + ", isActive=" + isActive + "]";
  }
}

StatusMessage Class

This class is used to return JSON messages back to clients containing status, message properties.

package com.avaldes.model;

import org.codehaus.jackson.annotate.JsonProperty;

public class StatusMessage {

  private Integer status;
  private String message;
  
  public StatusMessage() {
  }

  @JsonProperty(value = "status_code")
  public Integer getStatus() {
    return status;
  }

  public void setStatus(Integer status) {
    this.status = status;
  }

  @JsonProperty(value = "message")
  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }
}

Customer DAO (Data Access Object)

This interface is used to define all of the methods that will be needed when interacting with our MySQL database. With this interface you will see that all of the basic CRUD (Create, Update, Delete and Get) operations are available.

package com.avaldes.dao;

import javax.ws.rs.core.Response;
import com.avaldes.model.Customer;

public interface CustomerDAO {
  
  public Response getCustomer(int id);
  public Response createCustomer(Customer customer);
  public Response updateCustomer(Customer customer);
  public Response deleteCustomer(int id);
  public Response getAllCustomers();  
}

Customer DAO Impl Class

This is the actual concrete class that performs the implementation of the methods defined in the interface CustomerDAO.class.

package com.avaldes.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.apache.log4j.Logger;

import com.avaldes.dao.CustomerDAO;
import com.avaldes.model.Customer;
import com.avaldes.model.StatusMessage;
import com.avaldes.util.Database;

public class CustomerDAOImpl implements CustomerDAO {
  private DataSource datasource = Database.getDataSource();
  private Logger logger = Logger.getLogger(CustomerDAOImpl.class);
  
  @Override
  public Response getCustomer(int id) {
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    
    Customer customer = null;
    String sql = "select customer_id, first_name, last_name, address, "
								+ "city, state, zip_code, is_active from Customers "
								+ "where customer_id = ?";
    
    try {
      conn = datasource.getConnection();
      ps = conn.prepareStatement(sql);
      ps.setInt(1, id);
      rs = ps.executeQuery();
      
      if (rs.next()) {
        customer = new Customer();
        customer.setCustomerId(rs.getInt("customer_id"));
        customer.setFirstName(rs.getString("first_name"));
        customer.setLastName(rs.getString("last_name"));
        customer.setAddress(rs.getString("address"));
        customer.setCity(rs.getString("city"));
        customer.setState(rs.getString("state"));
        customer.setZipCode(rs.getString("zip_code"));
        customer.setIsActive(rs.getInt("is_active"));
      } else {
        logger.error(
					String.format("Customer with ID of %d is not found.", id));
        StatusMessage statusMessage = new StatusMessage();
        statusMessage.setStatus(Status.NOT_FOUND.getStatusCode());
        statusMessage.setMessage(
					String.format("Customer with ID of %d is not found.", id));
        return Response.status(404).entity(statusMessage).build();
      }
    } catch (SQLException e) {
      logger.error("Error: " + e.getMessage());
      e.printStackTrace();
    } finally {
      if (rs != null) {
        try {
          rs.close();
        } catch (SQLException e) {
          logger.error("Error closing resultset: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (ps != null) {
        try {
          ps.close();
        } catch (SQLException e) {
          logger.error("Error closing PreparedStatement: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (conn != null) {
        try {
          conn.close();
        } catch (SQLException e) {
          logger.error("Error closing connection: " + e.getMessage());
          e.printStackTrace();
        }
      }
    }
    return Response.status(200).entity(customer).build();
  }

  @Override
  public Response createCustomer(Customer customer) {
    Connection conn = null;
    PreparedStatement ps = null;
    Statement stmt = null;
    ResultSet rs = null;
    StatusMessage statusMessage = null;
    int autoID = -1;
    
    String sql = "insert into customers (first_name, last_name, "
								+ "address, city, state, zip_code, is_active) "
								+ "values (?,?,?,?,?,?,?)";
    
    try {
      conn = datasource.getConnection();
      ps = conn.prepareStatement(sql);
      ps.setString(1, customer.getFirstName());
      ps.setString(2, customer.getLastName());
      ps.setString(3, customer.getAddress());
      ps.setString(4, customer.getCity());
      ps.setString(5, customer.getState());
      ps.setString(6, customer.getZipCode());
      ps.setInt(7, customer.getIsActive());
      
      int rows = ps.executeUpdate();
      
      if (rows == 0) {
        logger.error("Unable to create customer...");
        statusMessage = new StatusMessage();
        statusMessage.setStatus(Status.NOT_FOUND.getStatusCode());
        statusMessage.setMessage("Unable to create customer...");
        return Response.status(404).entity(statusMessage).build();
      }
      
      stmt = conn.createStatement();
      rs = stmt.executeQuery("select LAST_INSERT_ID()");

      if (rs.next()) {
          autoID = rs.getInt(1);
          customer.setCustomerId(autoID);
      }
       
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      if (rs != null) {
        try {
          rs.close();
        } catch (SQLException e) {
          logger.error("Error closing resultset: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (ps != null) {
        try {
          ps.close();
        } catch (SQLException e) {
          logger.error("Error closing PreparedStatement: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (conn != null) {
        try {
          conn.close();
        } catch (SQLException e) {
          logger.error("Error closing connection: " + e.getMessage());
          e.printStackTrace();
        }
      }
    }
    return Response.status(200).entity(customer).build();
  }

  @Override
  public Response updateCustomer(Customer customer) {
    Connection conn = null;
    PreparedStatement ps = null;
    
    String sql = "update customers set first_name=?, last_name=?, "
        + "address=?, city=?, state=?, zip_code=?, is_active=? "
        + "where customer_id = ?";
    
    try {
      conn = datasource.getConnection();
      ps = conn.prepareStatement(sql);
      ps.setString(1, customer.getFirstName());
      ps.setString(2, customer.getLastName());
      ps.setString(3, customer.getAddress());
      ps.setString(4, customer.getCity());
      ps.setString(5, customer.getState());
      ps.setString(6, customer.getZipCode());
      ps.setInt(7, customer.getIsActive());
      ps.setInt(8, customer.getCustomerId());
      
      int rows = ps.executeUpdate();
      
      if (rows == 0) {
        logger.error("Unable to update customer...");
        StatusMessage statusMessage = new StatusMessage();
        statusMessage.setStatus(Status.NOT_FOUND.getStatusCode());
        statusMessage.setMessage("Unable to update customer...");
        return Response.status(404).entity(statusMessage).build();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      if (ps != null) {
        try {
          ps.close();
        } catch (SQLException e) {
          logger.error("Error closing PreparedStatement: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (conn != null) {
        try {
          conn.close();
        } catch (SQLException e) {
          logger.error("Error closing connection: " + e.getMessage());
          e.printStackTrace();
        }
      }
    }
    return Response.status(200).entity(customer).build();
  }

  @Override
  public Response deleteCustomer(int id) {
    Connection conn = null;
    PreparedStatement ps = null;
    StatusMessage statusMessage = null;
    
    String sql = "delete from customers where customer_id = ?";
    
    try {
      conn = datasource.getConnection();
      ps = conn.prepareStatement(sql);
      ps.setInt(1, id);
      int rows = ps.executeUpdate();
      
      if (rows == 0) {
        logger.error(
					String.format("Unable to DELETE customer with ID of %d...", id));
        statusMessage = new StatusMessage();
        statusMessage.setStatus(Status.NOT_FOUND.getStatusCode());
        statusMessage.setMessage(
					String.format("Unable to DELETE customer with ID of %d...", id));
        return Response.status(404).entity(statusMessage).build();
      }
    } catch (SQLException e) {
      logger.error("Error: " + e.getMessage());
      e.printStackTrace();
    } finally {
      if (ps != null) {
        try {
          ps.close();
        } catch (SQLException e) {
          logger.error(
						"Error closing PreparedStatement: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (conn != null) {
        try {
          conn.close();
        } catch (SQLException e) {
          logger.error("Error closing connection: " + e.getMessage());
          e.printStackTrace();
        }
      }
    }
    
    statusMessage = new StatusMessage();
    statusMessage.setStatus(Status.OK.getStatusCode());
    statusMessage.setMessage(
			String.format("Successfully deleted customer with ID of %d...", id));
    return Response.status(200).entity(statusMessage).build();
  }

  @Override
  public Response getAllCustomers() {
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    
    List<Customer> allCustomers = new ArrayList<Customer>();
    String sql = "select customer_id, first_name, last_name, address, "
                + "city, state, zip_code, is_active from Customers";
    
    try {
      conn = datasource.getConnection();
      ps = conn.prepareStatement(sql);
      rs = ps.executeQuery();
      
      while (rs.next()) {
        Customer cust = new Customer();
        cust.setCustomerId(rs.getInt("customer_id"));
        cust.setFirstName(rs.getString("first_name"));
        cust.setLastName(rs.getString("last_name"));
        cust.setAddress(rs.getString("address"));
        cust.setCity(rs.getString("city"));
        cust.setState(rs.getString("state"));
        cust.setZipCode(rs.getString("zip_code"));
        cust.setIsActive(rs.getInt("is_active"));
        allCustomers.add(cust);
      }
      
      if (allCustomers.isEmpty()) {
        logger.error("No Customers Exists...");
        StatusMessage statusMessage = new StatusMessage();
        statusMessage.setStatus(Status.NOT_FOUND.getStatusCode());
        statusMessage.setMessage("No Customers Exists...");
        return Response.status(404).entity(statusMessage).build();
      }
    } catch (SQLException e) {
      e.printStackTrace();
    } finally {
      if (rs != null) {
        try {
          rs.close();
        } catch (SQLException e) {
          logger.error("Error closing resultset: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (ps != null) {
        try {
          ps.close();
        } catch (SQLException e) {
          logger.error(
						"Error closing PreparedStatement: " + e.getMessage());
          e.printStackTrace();
        }
      }
      if (conn != null) {
        try {
          conn.close();
        } catch (SQLException e) {
          logger.error("Error closing connection: " + e.getMessage());
          e.printStackTrace();
        }
      }
    }
    return Response.status(200).entity(allCustomers).build();
  }
}

Complete Program (RestfulTomcatJNDIExample.java)

package com.avaldes.service;

import java.io.IOException;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;

import com.avaldes.dao.CustomerDAO;
import com.avaldes.dao.impl.CustomerDAOImpl;
import com.avaldes.model.Customer;

@Path("tomcat")
public class RestfulTomcatJNDIExample {
    private Logger logger 
        = Logger.getLogger(RestfulTomcatJNDIExample.class); 
    
    @Path("status")
    @GET
    @Produces(MediaType.TEXT_HTML)
    public String getStatus() {
        logger.info("Inside getStatus()...");
        return "TomcatJNDIExample Status is OK...";
    }

    @GET
    @Path("getcustomer")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getCustomer(
                @DefaultValue("0") @QueryParam("id") int id) {

        CustomerDAO daoImpl = new CustomerDAOImpl();
        logger.info("Inside getCustomer...");
        
        Response resp = daoImpl.getCustomer(id);
        return resp;
    }

    @POST
    @Path("addcustomer")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createCustomer(Customer customer) {

        CustomerDAO daoImpl = new CustomerDAOImpl();
        logger.info("Inside createCustomer...");
        
        Response resp = daoImpl.createCustomer(customer);
        return resp;
    }
    
    @PUT
    @Path("updatecustomer")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response updateCustomer(Customer customer) {

        CustomerDAO daoImpl = new CustomerDAOImpl();
        logger.info("Inside createCustomer...");
        
        Response resp = daoImpl.updateCustomer(customer);
        return resp;
    }
    
    @DELETE
    @Path("deletecustomer")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response deleteCustomer(
                @DefaultValue("0") @QueryParam("id") int id) {

        CustomerDAO daoImpl = new CustomerDAOImpl();
        logger.info("Inside deleteCustomer...");
        
        Response resp = daoImpl.deleteCustomer(id);
        return resp;
    }
    
    @GET
    @Path("showallcustomers")
    @Produces(MediaType.APPLICATION_JSON)
    public Response showAllCustomers() throws JsonGenerationException,
        JsonMappingException, IOException {

        CustomerDAO daoImpl = new CustomerDAOImpl();
        logger.info("Inside showAllCustomers...");
        Response resp = daoImpl.getAllCustomers();
        
        return resp;
    }
}

LOG4J Configuration File (log4j.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "
    -//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">

	<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

  <!-- Appenders -->
  <appender name="console" class="org.apache.log4j.ConsoleAppender">
  <param name="Target" value="System.out" />
    <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-5p: %c - %m%n" />
    </layout>
  </appender>
  
  <!-- Application Loggers -->
  <logger name="com.avaldes">
    <level value="info" />
  </logger>

  <!-- Root Logger -->
  <root>
    <priority value="warn" />
    <appender-ref ref="console" />
  </root>
</log4j:configuration>

Web Deployment Descriptor (web.xml)

This is a pretty straight forward deployment descriptor file – only thing you need to add is the resource reference. A resource reference allows you to define your JNDI requirements so that you can set up your data source in Tomcat. Please ensure you add it to the web.xml file as shown below.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID"
	version="3.0">
  <display-name>Tomcat JNDI Example</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>
			com.sun.jersey.spi.container.servlet.ServletContainer
		</servlet-class>
    <init-param>
      <param-name>
				com.sun.jersey.config.property.packages
			</param-name>
      <param-value>com.avaldes</param-value>
    </init-param>
    <init-param>
      <param-name>
				com.sun.jersey.api.json.POJOMappingFeature
			</param-name>
      <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/rest/*</url-pattern>
  </servlet-mapping>
    
  <resource-ref>
        <description>MySQL Datasource</description>
        <res-ref-name>jdbc/tutorialdb</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
  </resource-ref>
</web-app>

Configure Context for Tomcat (Context.xml)

This optional file contains a <Context> tag (Context Fragment) for your Tomcat web application. This separate file was introduced with Tomcat 5 so that a less obtrusive mechanism than a full server restart would be available.

Context elements may be defined in multiple places in Tomcat:

  • In the $CATALINA_HOME/conf/context.xml file: the Context element information will be loaded by all webapps.
  • In the $CATALINA_HOME/conf/[enginename]/[hostname]/context.xml.default file: the Context element information will be loaded by all webapps of that host.
  • In META-INF/context.xml inside your applicationand packaged in the WAR file.
<Context>
  <Resource 
    name="jdbc/tutorialdb" 
    auth="Container" 
    type="javax.sql.DataSource"
    maxActive="25" 
    maxIdle="10" 
    maxWait="10000"
		removeAbandoned="true"
    removeAbandonedTimeout="300" 
    defaultAutoCommit="true"
    factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
    username="webuser" 
    password="EasyAs123!" 
    driverClassName="com.mysql.jdbc.Driver"
    url="jdbc:mysql://localhost:3306/tutorialdb" />
</Context>

Tomcat Resource Factory Settings

  • name – Resource name matching the resource reference name (<res-ref-name>) we used in the web deployment descriptor (web.xml).
  • auth – Specify whether the web Application code signs on to the corresponding resource manager programmatically or via the Container. The two values available are Container or Application.
  • driverClassName – Name of the fully qualified Java class name of the JDBC driver.
  • username – Database username used for authentication purposes.
  • password – Database password used for authentication purposes.
  • url – Connection URL to be passed to the JDBC driver.
  • type – The fully qualified Java class name expected by the web application when it performs a lookup for this resource.
  • maxActive – The maximum number of connections that can be allocated from this pool at the same time.
  • maxIdle – The maximum number of connections that can sit idle in this pool at the same time.
  • maxWait – The maximum number of milliseconds that the pool will wait (when there are no available connections) for a connection to be returned before throwing an exception.
  • maxTotal – The maximum number of connections that can be allocated from this pool at the same time (Tomcat 8).
  • removeAbandoned – Flag to determine whether to remove abandoned connections from the pool (true or false).
  • removeAbandonedTimeout – The number of seconds after which a borrowed connection is assumed to be abandoned.
  • defaultAutoCommit – Default auto-commit state of the connections created by this pool (true or false).

Creating the Customer Table in MySQL

CREATE TABLE `tutorialdb`.`customers` (
  `customer_id` INT NOT NULL AUTO_INCREMENT,
  `first_name` VARCHAR(45) NULL,
  `last_name` VARCHAR(45) NULL,
  `address` VARCHAR(45) NULL,
  `city` VARCHAR(30) NULL,
  `state` VARCHAR(20) NULL,
  `zip_code` VARCHAR(10) NULL,
  `is_active` TINYINT(1) NULL,
  PRIMARY KEY (`customer_id`)
);

Inserting sample data into Customer Table in MySQL

I have included a sample insert statement using SQL to ease you database work and makeit easier for you to get started sooner.

INSERT INTO `tutorialdb`.`customers`
(`first_name`,
`last_name`,
`address`,
`city`,
`state`,
`zip_code`,
`is_active`)
VALUES
('Amaury',
'Valdes',
'100 Main Street',
'Wayne',
'New Jersey',
'07470',
1);

INSERT INTO `tutorialdb`.`customers`
(`first_name`,
`last_name`,
`address`,
`city`,
`state`,
`zip_code`,
`is_active`)
VALUES
('Jessica',
'Silva',
'1285 South Street',
'Clifton',
'New Jersey',
'07013',
1);

Testing out the Web Services

To test out the application I used Postman which is a Google Chrome Application. Using this tool I validated each of the REST API calls. Please review the screen shots below:

Testing out using POSTMAN Chrome Extension

Download the Complete Source Code

That’s It!

I hope you enjoyed this tutorial. It was certainly a lot of fun putting it together and testing it out. Please continue to share the love and like us so that we can continue bringing you quality tutorials. Happy Coding!!!

java_jaxrs_tomcat_jndi

Related JAX-RS Tutorial Posts

  • RESTful Web Services with AngularJS, Bootstrap and Java using JAX-RS and Jersey
    In this tutorial we will develop a full blown CRUD application using JAX-RS API and Jersey to implement RESTful web services. JAX-RS stands for Java API for RESTful Web Services and by using this powerful API developers can easily build REST services. Jersey RESTful Web Services is an open source framework for developing RESTful Web Services in Java that provides support for JAX-RS APIs.
  • JAX-RS Security using JSON Web Encryption(JWE) with AngularJS, Bootstrap, Grid-UI and MongoDB Example
    In this tutorial we will discuss how to use AngularJS, Bootstrap and Grid-UI to connect to secure JAX-RS RESTful web services using JWE/JWT/JWS for Authentication and Authorization. In our example implementation, we will be using Symmetric Encryption where the receiver and sender share a common key.
  • JAX-RS Security using JSON Web Encryption (JWE) with JWS/JWT for Authentication and Authorization
    In this tutorial we will discuss how to secure JAX-RS RESTful web services using JSON Web Encryption(JWE), JSON Web Key (JWK), JSON Web Signature(JWS), and JSON Web Tokens(JWT) for Authentication and Authorization. JSON Web Encryption (JWE) encrypted content using Javascript Object Notation (JSON) based structures.
  • JAX-RS Security using JSON Web Tokens (JWT) for Authentication and Authorization
    In this tutorial we will discuss how to secure JAX-RS RESTful web services using JSON Web Tokens Authentication and Authorization. This form of security is used for authenticating a client using a signed token which can be verified by application servers. This token-based form of security is a ideal candidate for Cross-domain (CORS) access and when server-side scalability is a prime motivation factor.
  • JAX-RS Security using API-KEY for Authorization
    In this tutorial we will discuss how to secure JAX-RS RESTful web services using API-KEY or Service Key for Authorization. This form of security is used to ensure that certain RESTful endpoints are protected against unauthorized use.
  • JAX-RS Security using Digest Authentication and Authorization
    In this JAX-RS Digest Authentication and Authorization tutorial we will discuss how to set up digest security for our RESTful web service. This form of access authentication is slightly more complex than the previously discussed JAX-RS Basic Authentication Tutorial.
  • JAX-RS Security using Basic Authentication and Authorization
    In this JAX-RS basic authentication and authorization tutorial we will discuss how to set up security for our RESTful web service. We will need to ensure that some of the URIs are protected and only clients that have been authenticated and authorized are able to gain access and make use of them.
  • Upload and Download Multiple Binary Files using MongoDB
    In this tutorial we are going to develop multiple file upload and file download capability using RESTful web service using JAX-RS and Jersey storing the contents of files into MongoDB Database using a powerful feature in MongoDB for managing large files called GridFS.
  • Inserting and Retrieving Binary Data with MongoDB using JAX-RS RESTful Web Service
    In this tutorial we are going to develop file upload and file download capability using RESTful web service using JAX-RS and Jersey storing the contents of files into MongoDB Database using a powerful feature in MongoDB for managing large files called GridFS. The bulk of the framework for this tutorial came from my previous tutorial so you find many similarities between the two posts.
  • Inserting and Retrieving Binary Data with SQL Server Database using JAX-RS RESTful Web Service
    In this tutorial we are going to develop file upload and file download capability using RESTful web service using JAX-RS and Jersey storing the contents of the file into SQL Server Database using BLOB. Our example will be able to store PDF files, Excel files, Word Document files, Powerpoint files, Image files, or any other type of file available us provided we have ample amount of storage space.
  • File Download Example Using RESTful Web Service with JAX-RS and Jersey
    In this example we are going to develop file download capability using RESTful web service using JAX-RS and Jersey. As you will see, downloading a File using Jersey is very easy as it uses the HTTP GET for the file operations. In our web service, we will be allowing you to download the file via two mechanisms. You will be able to download by HTTP query parameters via @QueryParam and also by using the path parameters via @PathParam.
  • JAX-RS Restful Web Services with JNDI Datasource for MySQL in Tomcat
    In this tutorial we will discuss how to set up JAX-RS RESTful web services and configure a JNDI Datasource with Connection Pooling in Tomcat and connect to MYSQL Database. JNDI (Java Naming and Directory Interface) provides and interface to multiple naming and directory services.
  • File Upload Example Using RESTful Web Service with JAX-RS and Jersey
    In this example we are going to develop file upload capability using RESTful web service using JAX-RS and Jersey. As you will see, uploading a File using Jersey is pretty straight forward as it uses HTTP POST with the encoding type of multipart/form-data for the file operations.
  • RESTful Web Services @FormParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract form parameters submitted by a form using @FormParam annotation.
  • RESTful Web Services @MatrixParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract matrix parameters from the request URL using the @MatrixParam annotations.
  • RESTful Web Services @QueryParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract query parameters from the request URL using the @QueryParam annotation.
  • RESTful Web Services @PathParam Example using JAX-RS and Jersey
    In this example we are going to develop a simple RESTful web service using JAX-RS and Jersey to extract path parameters from the request URL using the @PathParam annotation.

Please Share Us on Social Media

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *