Spring security with spring boot example

Spring Security is a framework what spring calls it. It provides authentication, authorization, and protection against attacks. It has become kind of a standard for securing spring based applications.
In this tutorial we will learn about spring security with spring boot and its example.

Spring Security requires a Java 8 or higher Run-time Environment.

Spring security Features

  1. Authentication
  2. Authorization
  3. Protection against common exploits

1. Authentication

There are many ways to authenticate users, like the most common way is by requiring user to enter username and password. There are many Password Storage Techniques like.

Using Spring Security PasswordEncoder.
Using BCryptPasswordEncoder.
Using DelegatingPasswordEncoder.
Using NoOpPasswordEncoder.

2. Protection against common exploits

Spring Security provides protection against common exploits. Whenever possible, the protection is enabled by default.

CSRF (Cross Site Request Forgery) Attacks
Default Security Http Headers.

Example : Default Security HTTP Response Headers

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=31536000 ; includeSubDomains
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=bloc

3. Http

As a framework, Spring Security does not handle HTTP connections and thus does not provide support for HTTPS directly. However, it does provide a number of features that help with HTTPS usage, like.

Redirect to HTTPS
Strict Transport Security
Proxy Server Configuration

Spring Security with Spring Boot Example

1. Project Structure

springboot-spring-security-project-structure

2. REST Controller – EmployeeController

First creating a REST controller class like this, with few HTTP methods like GET, POST, DELETE.

package com.programmertoday.springsecurity.controller;

import com.programmertoday.springsecurity.model.Employee;
import com.programmertoday.springsecurity.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("api")
public class EmployeeController {

@Autowired
EmployeeService empService;

// Get all Employees
@GetMapping("/employees")
List<Employee> findAll() {
return empService.findAll();
}

// Save Employees
@PostMapping("/employees")
@ResponseStatus(HttpStatus.CREATED)
String newEmployee(@RequestBody Employee newEmployee) {

empService.save(newEmployee);
return "Success fully created Employees";
}

// Delete Employees with id
@DeleteMapping("/employees/{id}")
String deleteBook(@PathVariable Integer id) {

empService.deleteEmpById(id);
return "deleted employee with id " +id + " successfully";
}
}

3. Model Class – Employee

package com.programmertoday.springsecurity.model;

public class Employee {

private int empId;
private String empName;
private String empDept;
private String empLocation;

public Employee(int empId, String empName,
String empDept, String empLocation) {
this.empId = empId;
this.empName = empName;
this.empDept = empDept;
this.empLocation = empLocation;
}

public int getEmpId() {
return empId;
}

public void setEmpId(int empId) {
this.empId = empId;
}

public String getEmpName() {
return empName;
}

public void setEmpName(String empName) {
this.empName = empName;
}

public String getEmpDept() {
return empDept;
}

public void setEmpDept(String empDept) {
this.empDept = empDept;
}

public String getEmpLocation() {
return empLocation;
}

public void setEmpLocation(String empLocation) {
this.empLocation = empLocation;
}
}

4. Service class – EmployeeService

package com.programmertoday.springsecurity.service;

import com.programmertoday.springsecurity.model.Employee;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class EmployeeService {

public List<Employee> findAll() {
List<Employee> empList = new ArrayList<>();
empList.add(new Employee(101,"Maverick","RE","SF"));
empList.add(new Employee(102,"John","CS","NJ"));
empList.add(new Employee(103,"Drake","HE","NYC"));
return empList;
}

public void save(Employee newEmployee) {

System.out.println("saving new employee");
// .. add your own code, it's just for basic understanding
}

public void deleteEmpById(Integer id) {

// .. add your own code, it's just for basic understanding
System.out.println("Employee with "+id+" is deleted");
}

}

5. Config class – SpringSecurityConfig

package com.programmertoday.springsecurity.configs;

import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.
builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.
builders.HttpSecurity;
import org.springframework.security.config.annotation.web.
configuration.WebSecurityConfigurerAdapter;

@Configuration
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

// Creating just 2 users for demonstration
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {

auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER")
.and()
.withUser("admin").password("{noop}password").roles("USER", "ADMIN");

}

// Securing the endpoints with HTTP Basic authentication
@Override
protected void configure(HttpSecurity http) throws Exception {

http
//HTTP Basic authentication
.httpBasic()
.and()
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/api/employees/**").hasRole("USER")
.antMatchers(HttpMethod.POST, "/api/employees").hasRole("ADMIN")
.antMatchers(HttpMethod.DELETE, "/api/employees/**").hasRole("ADMIN")
.and()
.csrf().disable()
.formLogin();//.disable();

}

}

6. SpringBootApplication – SpringSecurityApplication Class

Now run the application.

package com.programmertoday.springsecurity;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringSecurityApplication {

public static void main(String[] args) {
SpringApplication.run(SpringSecurityApplication.class, args);
}

}

OUTPUT

Example 1 : Unauthorized Login Unsuccessful because of Spring Security

// With a different user(user123) who is not an authorized user
C:\>curl localhost:8080/api/employees -u user123:password
{“timestamp”:”2020-04-05T14:39:25.805+0000″,”status”:401,”error”:”Unauthorized”,”message”:”Unauthorized”,”path”:”/api/employees”}

// Calling Delete API with a user who is not authorized to access Delete API
C:\>curl -X DELETE localhost:8080/api/employees/1 -u user:password
{“timestamp”:”2020-04-05T14:37:23.688+0000″,”status”:403,”error”:”Forbidden”,”message”:”Forbidden”,”path”:”/api/employees/1″}

Example 2 : Successful Login

GET API : with user=user and password=password

C:\>curl localhost:8080/api/employees -u user:password
[{“empId”:101,”empName”:”Maverick”,”empDept”:”IT”,”empLocation”:”SF”},{“empId”:102,”empName”:”John”,”empDept”:”CS”,”empLocation”:”NJ”},{“empId”:103,”empName”:”Drake”,”empDept”:”HE”,”empLocation”:”NYC”}]

DELETE API Call : with user=admin and password=password

C:\> curl -X DELETE localhost:8080/api/employees/1 -u admin:password
deleted employee with id 1 successfully

Try testing in Browser as well

Open the browser : localhost:8080/api/employees – it will redirect to /login first

Provide the right credentials as configured in the SpringSecurityConfig class

spring-security-api-login
spring-security-api-example

Summary

In this tutorial we learnt how to use spring security with REST APIs and spring boot. We created a spring boot REST based simple project and secured it using spring security. At the end we also saw the output of the code using curl command lines as well as in the browser.

Please comment below for suggestions and questions, I hope you liked it !


REST API Security

Security is the biggest API technology challenge seen today to be solved. Organizations today Understand the Need for REST API Security or any API Security for that matter.

Secure REST APIs

Why is Security Important?

Api Security is one of the biggest challenge that everyone including IT organizations want to see solved. Solving Security related issues will lead to growth of APIs.

In case your API does not have an Authorization/Authentication mechanism, it might lead to misuse of your API, loading the servers and the API itself, making it less responsive to others.

Factors Not to Overlook

why-is-REST-API-Security-important

1. Protection of Data :

Data protection is one of the most important security concern. It is really very important to define access rights to different kinds of api methods (especially PUT and Delete methods).

Good level of authentication is needed to access these apis and these should also be logged for audit.

2. Protection against Attacks :

There are several kinds of attacks which can occur on APIs, to name a few

Injection Attacks :

Like the SQL injection and the XSS cross site scripting attack, where an attacker code which is malicious is injected or embedded to a non-secure applications or softwares.
In case of APIs untrusted data can be transferred to the APIs as a query or command and if this data is successfully injected as the input to the APIs can do a lot of damage or leak information.
You can handle this by adding input validations and constraints.

DoS Attack :

In Denial of Service attack, attackers pushed a load of messages to the server in this case the API servers.
With the aim to request the server multiple invalid requests making the API non-functional.
In case someone succeeds in making a DoS attack, it meants that who-so-ever was the consumer or user of those API services will not be able to access it anymore.

Exposing Senstive Data :

Senstive data may include information like user personal information, tokens, passwords, social security details, banking details like credit cards etc. This Sensitive data requires high security, for this sensitive data can be encrypted using many techniques like SSL certificates, TLS.

Authorized Access Only :

Authorization is one important factor to pay attention to. Missing on this part may lead to access to valuable or senstive information. It can make the service vulnerable to attackers or any user who is not suppose to have that extra peace of information for that matter. Proper access controls should be given to it’s users.

3. Anti-Farming :

Today, RESTful API’s most common use case is the online Booking industry, many Huge websites have a business model of consuming multiple multi-sector services like Hotel, airline ticketing, movie tickets, etc and taking advantage of APIs actually built by other individual companies in these sectors.

In cases like these if your APIs are not secured it does not have an auth mechanism, it may lead to miss-use of your APIs and also it can have performance issues or it can become non-responsive to other users.


Ways to Secure APIs 🙂

RESTful APIs are stateless, so the auth security must not depend on the session or cookie alone, these auth parameters should be validated on each and every request to the server most likely using the headers. There are multiple ways to secure RESTful APIs, we will put light into some of them below.

  1. Basic Auth
  2. API Keys
  3. OAuth
  4. JWT

1. Basic Authentication

Probably One of the simplest way to implement access controls in RESTful APIs. It does not require any cookies or sessions, it just passes auth credentials through the HTTP headers.

So it involves the Client sending userid and password seperated by a single colon encoded with Base64 all together in a string.

Example : userid “maverick” and password “pass123” seperated by single colon.

maverick:pass123

Authorization: Basic bWF2ZXJpY2s6cGFzczEyMw==

The basic auth is not very secure method of user authentication, the most serious flaw with basic auth is that you pass userid and password over the network in the header in the form of encoded string.

But Still if you are using this technique then it should be used with TLS or SSL (https)protocol in order to protect sensitive information.

2. API Keys

API keys are for projects or applications, authentication is for users. For Example, Google Cloud exposing API Keys to access it and identify the application.

While API keys identify the calling project, they don’t identify the calling user. For instance, if you have created an application that is calling an API, an API key can identify the application that is making the call, but not the identity of the person who is using the application.

You use API Keys when :

  • You do want to block anonymous traffic. API keys identify an application’s traffic for the API producer.
  • You want to control the number of calls made to your API.
  • You want to identify usage patterns in your API’s traffic.

You cannot use API Keys for :

  • Identifying individual users — API keys don’t identify users, they identify projects. Secure authorization.
  • Identifying the creators of a project/application.

3. OAuth 2

The OAuth 2.0 is an authorization framework that enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner or by allowing the third-party application to obtain access on its own behalf. RFC 6794 .

OAuth gained popularity from usage by Google, Facebook, Microsoft and Twitter, who allow usage of their accounts to be shared with third-party applications or websites.

OAuth works over HTTPS and authorizes devices, APIs, applications and servers with access tokens rather than credentials.

OAuth 2.0 can be used to read data of a user from another application without compromising the user’s personal and sensitive data, like user credentials. For Example user using Facebook OAuth login for logging into Quora. It also supplies the authorization workflow for web, desktop applications, and mobile devices.

To simplify, you can thing it as a hotel key card. If you have that key card, you can get access to you room and other resources. But how do you get a Key card? You will have to do an authentication of your identity and booking at the front desk reception. After they authenticate you and give you the key card, you get access to other resources of the hotel as well.

OAuth Tokens :

The OAuth uses tokens, to authorize user. Access Tokens and the refresh tokens.

Access Tokens :

Are the tokens used by the client to access the resource API, they have an expiry. This is not something used by sercret clients but are available with public clients.

Refresh Tokens :

These tokens can live much longer like in days,months,years. This token is used to get new access tokens. To get a Refresh tokens applications typically need secret clients with authentication.

Access token can also be put in the authorization header, eg:

Authorization: Bearer 0123456789abcxyz

4. JWT – Json Web Token

What is JSON Web Token, or JWT (pronounced as “jot”)? It is one of the Token authentication standard. It allows you to digitally sign information(called as claims) with a signature which can be verified later with a secret signing key.

JWT can store any type of data, which like OAuth access tokens should be passed in the authorization header.

Authorization: Bearer JWT

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1hdmVyaWNrIiwiaWF0IjoxNTE2MjM5MDIyf.
qkBSwSUiWDRyLlG4STgn1w0VIAbA1qEtqSBZ2g8Kgc4

Anatomy of JWT

A JWT token looks like this

rest-security-jwt-token-anatomy
<Header in Red>.<Payload in blue>.<Signature in green>

Header Section

Json Structure whihch consists of the algorithm type and the type of token, for example here algo is of type HS256 and type of token as JWT.

{
  "alg": "HS256",
  "typ": "JWT"
}

Then this JSON is Base64 Encoded and it looks something like this

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Payload

The second part of the JWT token is the payload, which has the user data which used intend to pass and other information related to the token.

{
  "sub": "1234567890",
  "name": "Maverick",
  "iat": 1516239022
}

sub : is the Subject
name : name of the user
iat : Issued At is dateTime in number format

Then this payload JSON is Base64 Encoded and it looks something like this

eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1hdmVyaWNrIiwiaWF0IjoxNTE2MjM5MDIyfQ

Signature

The signature in JWT is part of token which is used to verify the user/sender of the JWT is who they claim they are.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
your-256-bit-secret

) 

Signature is a combination of [ Base64 encoded header + base64 encoded payload and the secret ] using the algorithm specified HMACSHA256.

qkBSwSUiWDRyLlG4STgn1w0VIAbA1qEtqSBZ2g8Kgc4

And the complete encoded JWT token with the signature and the secret will look something like this

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ik1hdmVyaWNrIiwiaWF0IjoxNTE2MjM5MDIyfQ.qkBSwSUiWDRyLlG4STgn1w0VIAbA1qEtqSBZ2g8Kgc4

Try it out : Create your own JWT token here – https://jwt.io/

rest-security-jwt-token-header-payload-signature

How JWT works ?

rest-security-how-jwt-token-works

How Secure is JWT ?

Remember not to put sensitive information in it for example password, id’s, SSN, etc.

What if someone Steals my JWT ?

So you have to be careful about it, how you pass your JWT, it should pass through HTTPS protocol and it should be in conjunction with other established authentication mechanisms like the OAuth, etc.

JWT Use case

These days JWT being very common can be used for authentication, in Single sign on, Subsequent API request authorization.

Summary

In this article, we looked into one of the most challenging part in APIs, the REST API Security. We looked into some of the important factors which makes the API security even more important to understand.

Then we looked into various ways to secure REST APIs. To name a few methods like Basic Authentication, API keys, OAuth2, JWT.

I hope you liked this article ! Please leave your comments below.



Related posts

RSS Error: WP HTTP Error: A valid URL was not provided.

REST Webservices naming guidelines

In REST there is no strict naming rule conventions but there are certain guidelines which ensure that our webservices api URLs are easy to read and understand.

We are free to implement it in any way we want to.

Naming guidelines of REST WebServices

Just remember Nothing is right or wrong here in naming REST URIs as these are not the rules but best practices.

1. Simple Names

As such nothing specific, but the naming of REST API should be self-describing and simple.

Example

/users/12345
/api?type=user&id=12345

2. Use Nouns not verbs

Your URI should refer to a thing (a noun) and not an action (verb).

Example

http://www.programmertoday.com/rest/v1/users
http://www.programmertoday.com/rest/v1/users/{userId}
http://www.programmertoday.com/rest/v1/users/{userId}/orders
http://www.programmertoday.com/rest/v1/users/{userId}/orders/{order-id}

http://www.programmertoday.com/rest/v1/orders/{order-id}

http://www.programmertoday.com/rest/v1/products/{product-id}

we must avoid using uri names like below:
http://www.programmertoday.com/rest/v1/getUsers
http://www.programmertoday.com/rest/v1/getProducts

3. Try using Plural Nouns

Though name can be in singular noun as well but well recommended is to use plural nouns.

Example

/employees which represents all employees
/employees/{emp-id} represents a particular employee

4. Use lower case

Example

Recommended
/employees/{emp-id} 

Not-Recommended
/Employees/{emp-id}

5. Use Hyphens(-) to sepreate two words

Example

/employees/{emp-id}

6. Do not use Underscores(_)

Because Some search engines and browsers may concaternate the two words seperated by underscore.

Example

Not-Recommended
/employees/{emp_id} 

7. Filters like pagination, Limited search, sorting

For requirements like these, we should not go and create seperate resources Rather we should use query params to achieve the same.

Example

http://domain/rest/v1/orders?orders=Online

http://domain/rest/v1/products?category=toys&within=100

8. Do not name APIs with HTTP methods for CRUD operations

Example

HTTP GET : http://domain/rest/v1/products/{product-id}

HTTP DELETE : http://domain/rest/v1/products/{product-id} 

Not-recommended
http://domain/rest/v1/getorders
http://domain/rest/v1/remove/products
http://domain/rest/v1/delete/products
http://domain/rest/v1/updateproduct

9. Versioning

Always version your API. Versioning helps you iterate faster and prevents invalid requests from hitting updated endpoints. It also helps smooth over any major API version transitions as you can continue to offer old API versions for a period of time.

Example

HTTP GET : http://domain/rest/v1/products/{product-id}

HTTP GET : http://domain/rest/v2/products/{product-id}

Summary

In this tutorial, we learnt about the REST Webservices naming guidelines which one should follow not as a rule but as a good practice.
I hope you liked it !


REST WebServices Statelessness

The Statelessness means not having any state, REST means Representational State Transfer, which boils down to the same things that the server hosting REST does not store any state about the client session on its side.

Each request from the client to server must contain all of the information necessary to understand the request, and it cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client. Client is responsible for storing and handling all application state related information on client side.

To maintain statelessness, one should not store authorization details of client on the server, each request to the server should contain all the required details. As each request is considered to be a new request.

Advantages of REST being Stateless :

  1. It has drastically reduced the code – by reducing the code of server side snychronization logic.
  2. East to scale up, as there are no sessions to maintain so any server can handle multiple requests.
  3. Easy to cache as well.
  4. Server knows about each request by each client as the client carries all required information with each request, and can be tracked.
  5. Web services need not maintain the client’s previous interactions.

Summary

In this tutorial we learnt about the statelessness of REST apis and its advantages.
I hope you liked it !


Why don’t browsers support PUT and DELETE requests ?

why-dont-browsers-support-put-and-delete-requests

Browsers do support PUT and DELETE, but it is HTML that doesn’t.

This is because HTML 4.01 and the final W3C HTML 5.0 spec both say that the only HTTP methods that their form elements should allow are GET and POST.

Web pages trying to use forms with method="PUT" or method="DELETE" would fall back to the default method, GET for all current browsers. This breaks the web applications’ attempts to use appropriate methods in HTML forms for the intended action, and ends up giving a worse result — GET being used to delete things!

PUT as a form method makes no sense, you wouldn’t want to PUT a form payload. DELETE only makes sense if there is no payload, so it doesn’t make much sense with forms either.

Conclusion

If using web browser to test a rest api of http method PUT or DELETE, it will not work and would fall back to default GET method and hence the REST API URL will not give proper response.


REST Jackson API Hello World REST API Example

In this article we will learn how to use JACKSON api in a jersey based rest web services project in java. Jersey uses Jackson to convert object to / form JSON. In this tutorial, we show you how to convert a “Track” object into JSON format, and return it back to user.

Tools used

Maven
JDK 1.8 (even 1.6 would work fine)
Eclipse/IntelliJ(you can use whichever you are comfortable with)
Tomcat Server 8

These steps are followed in this tutorial,

it’s Damn Easy !

Step 1: create a java web project in eclipse and convert it to maven project.
Step 2: add jersey jackson dependency in pom.xml and update the project.
Step 3: create an API class.
Step 4: in the web.xml add the servlet and servlet mapping.
Step 5: Just run the project, Hurray !

POM Dependencies

<properties>
    <jersey2.version>2.28</jersey2.version>
    <jaxrs.version>2.0.1</jaxrs.version>
</properties>

<dependencies>
  <!-- JAX-RS -->
      <dependency>
          <groupId>javax.ws.rs</groupId>
          <artifactId>javax.ws.rs-api</artifactId>
          <version>${jaxrs.version}</version>
      </dependency>
      <!-- Jersey 2.28 -->
      <dependency>
          <groupId>org.glassfish.jersey.containers</groupId>
          <artifactId>jersey-container-servlet</artifactId>
          <version>${jersey2.version}</version>
      </dependency>
      <dependency>
          <groupId>org.glassfish.jersey.core</groupId>
          <artifactId>jersey-server</artifactId>
          <version>${jersey2.version}</version>
      </dependency>
      <dependency>
          <groupId>org.glassfish.jersey.inject</groupId>
          <artifactId>jersey-hk2</artifactId>
          <version>2.28</version>
      </dependency>

      <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/
        jersey-media-json-jackson -->
      <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.28</version>
      </dependency>
</dependencies>
  

Note: What happens when you do not add jersey-media-json-jackson jar in pom.xml ? The API when hit returns a SEVERE exception:
SEVERE: MessageBodyWriter not found for media type=application/json, type=class com.programmertoday.restjersey.model.Department, genericType=class com.programmertoday.restjersey.model.Department.
Because the resource is trying to produce an object of type json, but it does not find any convertor which converts Object into a json, hence adding the above jackson jar resolves this issue.

1. API code

package com.programmertoday.restjersey.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/api")
public class JerseyResource {

  @GET
  @Path("/department")
  @Produces(MediaType.APPLICATION_JSON)
    public Department getDepartment()
    {
          return new Department("IT","Information Technology");
    }
}
   

2. Model Class

package com.programmertoday.restjersey.model;

public class Department {

  private String depName;
  private String depCode;

  public Department(String a, String b) {
    this.depCode = a;
    this.depName = b;
  }

  public String getDepName() {
    return depName;
  }

  public void setDepName(String depName) {
    this.depName = depName;
  }

  public String getDepCode() {
    return depCode;
  }

  public void setDepCode(String depCode) {
    this.depCode = depCode;
  }
}
    

3. Web.xml

<?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>RESTful_Project</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
              <param-name>jersey.config.server.provider.packages</param-name>
              <param-value>com.programmertoday.restjersey.api</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
      
</web-app>
      

TEST the code

Add a tomcat server and run the project !!

Using any REST client OR any web browser like google chrome open the below url to hit the api.

http://localhost:8080/RESTful_Project/rest/api/department

{"depName":"Information Technology","depCode":"IT"}

Summary

In this article we learnt how to create a simple Jersey based REST API with JACKSON, which leverages us to convert the model class to JSON on the fly. There is no need to write a JSON Array explicitly for this. It’s Super simple and easy !.
Hope you liked the article !


REST Jersey Hello World REST API Example

In this tutorial we will learn how to make a jersey based rest web services project in a java. And if you are new to rest web services this tutorial will also help you create your first basic sample rest api project.

Libraries used

Jersey 2.28

Note : Jersey 2.28 library has been released and is available in maven central! Jersey 2.28, the first Jakarta EE implementation of JAX-RS 2.1 has finally been released.
https://jersey.github.io/

Tools used

Maven
JDK 1.8 (even 1.6 would work fine)
Eclipse/IntelliJ(you can use whichever you are comfortable with)
Tomcat Server 8

These steps are followed in this tutorial.

it’s Damn Easy !

Step 1: create a java web project in eclipse and convert it to maven project.
Step 2: add jersey dependency in pom.xml and update the project.
Step 3: create an API class.
Step 4: in the web.xml add the servlet and servlet mapping.
Step 5: Just run the project, Hurray !

POM Dependencies

<properties>
    <jersey2.version>2.28</jersey2.version>
    <jaxrs.version>2.1.1</jaxrs.version>
</properties>

<dependencies>
  <!-- JAX-RS -->
      <dependency>
          <groupId>javax.ws.rs</groupId>
          <artifactId>javax.ws.rs-api</artifactId>
          <version>${jaxrs.version}</version>
      </dependency>
      <!-- Jersey 2.28 -->
      <dependency>
          <groupId>org.glassfish.jersey.containers</groupId>
          <artifactId>jersey-container-servlet</artifactId>
          <version>${jersey2.version}</version>
      </dependency>
      <dependency>
          <groupId>org.glassfish.jersey.core</groupId>
          <artifactId>jersey-server</artifactId>
          <version>${jersey2.version}</version>
      </dependency>

<!-- add the below dependency for the below reason, otherwise it throws Injection Exception -->
      <dependency>
          <groupId>org.glassfish.jersey.inject</groupId>
          <artifactId>jersey-hk2</artifactId>
          <version>2.28</version>
      </dependency>
</dependencies>
  

Here is the reason. Starting from Jersey 2.26, Jersey removed HK2 as a hard dependency. It created an SPI as a facade for the dependency injection provider, in the form of the InjectionManager and InjectionManagerFactory. So for Jersey to run, we need to have an implementation of the InjectionManagerFactory. There are two implementations of this, which are for HK2 and CDI.

1. API code

package com.programmertoday.restjersey.api;

import javax.ws.rs.GET;
import javax.ws.rs.Path;

@Path("/api")
public class JerseyResource {

  @GET
  @Path("/message")
    public String getMyMessage()
    {
          return "Hello World - its Jersey 2 REST API";
    }
}
 

2. Web.xml

<?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>RESTful_Project</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  
  <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
              <param-name>jersey.config.server.provider.packages</param-name>
              <param-value>com.programmertoday.restjersey.api</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
      
</web-app>
      

TEST the code

Add a tomcat server and run the project !!

Using any REST client OR any web browser like google chrome open the below url to hit the api.

http://localhost:8080/RESTful_Project/rest/api/message

http://localhost:8080/RESTful_Project/rest/api/message

Summary

In this article we learnt how to create a simple Jersey based REST API Project and how to run it, its Super simple and easy !.
Hope you liked the article !


RESTful HTTP Status Codes

Http code Standards:

1xx: Informational – Communicates transfer protocol-level information
2xx: Success -Indicates that the client’s request was accepted successfully.
3xx: Redirection – Indicates that the client must take some additional action in order to complete their request.
4xx: Client Error – This category of error status codes points the finger at clients.
5xx: Server Error – The server takes responsibility for these error status codes.

Use HTTP status codes

200 – OK – Eyerything is working
201 – OK – New resource has been created
204 – OK – The resource was successfully deleted
304 – Not Modified – The client can use cached data
400 – Bad Request – The request was invalid or cannot be served. The exact error should be explained in the error payload. E.g. „The JSON is not valid“
401 – Unauthorized – The request requires an user authentication
403 – Forbidden – The server understood the request, but is refusing it or the access is not allowed.
404 – Not found – There is no resource behind the URI.
422 – Unprocessable Entity – Should be used if the server cannot process the enitity, e.g. if an image cannot be formatted or mandatory fields are missing in the payload.
500 – Internal Server Error – API developers should avoid this error. If an error occurs in the global catch blog, the stracktrace should be logged and not returned as response.

Summary

In this tutorial we learnt about REST Http Status Codes, the Most used Http status codes and its meaning.
Hope you liked the article !


Idempotency – REST Http methods

To define, it means if REST APIs make multiple requests and have the same effect as making a single request then that REST call is called idempotent.

In a similar way, there are idempotent HTTP methods, that if called multiple times does not produce different outcomes.

Which methods are idempotent and which not?

GET, PUT, DELETE, HEAD, OPTIONS and TRACE are idempotent.
POST is NOT idempotent.

Understand WHY !

1. HTTP – GET, HEAD, OPTIONS and TRACE

These methods are for retrieving data so invoking these methods will not write any data to the server, hence these methods are idempotent.

2. HTTP – PUT

Usually – not always – PUT APIs are used for performing update operations to a resource/record. Even if the PUT API is being called N number of times, the very first call will do the update but the next N-1 calls will not do any change as they will just overwrite what has already been written, hence PUT is idempotent too.

3. HTTP – DELETE

When you invoke N number of DELETE requests, the very first request will delete the resource/record but the other N-1 calls to this method will not do any further deletions for Obvious reasons as the record has already been deleted, hence DELETE is idempotent.

4. HTTP – POST

Usually – not everytime – POST APIs are used to create a new resource/record on server. And if you make N number of requests, then N number of resources/records will be created on the server, hence POST is not idempotent.

REST webservices Hello world tutorial

Next Follow this – tutorial and learn how to create REST webservices using Jersey(library).

Summary

In this article we learnt about idempotency in REST Http Status Codes, its meaning and its Understanding.
Hope you liked the article !