Wednesday, October 11, 2023

EM-Tirupati Codeathon Series #05

[Question] #1

Swap the variables (Java code)

Write a Java Program that Swap the Values of 02 Variables without Using a 03rd Variable. The Swapped Value Should be In Such a Way that the 1st Variable will hold only 10% (rounded down) of the 2nd value and the 02nd Variable will hold only the 20% (rounded down) of the 1st value.

[Sample Input]

var1=250, var2=400

[Sample Output]

var1=40, var2=50

Code Explaination:

  1. It demonstrates basic arithmetic operations in Java to swap and manipulate integer values.
  2. The program uses a Scanner to collect user input for var1 and var2.
  3. It swaps the values of var1 and var2 without a temporary variable using arithmetic operations
  4. After swapping, both var1 and var2 are scaled down by multiplying them by 0.1 and 0.2, respectively.
  5. The program displays the swapped and scaled values as "Swapped values: var1 = [var1], var2 = [var2]."
GitHub Repo link:  http://surl.li/mpkjd

Source Code(Java):

import java.util.Scanner;

public class Question05_01_Venkata {
    public static void main(String[] args) {
        // Step 1: Input
        Scanner input = new Scanner(System.in);
        System.out.print("Enter the value of var1: ");
        int var1 = input.nextInt();
        System.out.print("Enter the value of var2: ");
        int var2 = input.nextInt();

        // Step 2: Swap using arithmetic operations
        // Swap var1 and var2 without using a temporary variable
        var1 = var1 + var2;
        var2 = var1 - var2;
        var1 = var1 - var2;

        // Step 3: Apply a scaling factor
        // Scale down the swapped values
        var1 = (int) (0.1 * var1);
        var2 = (int) (0.2 * var2);

        // Step 4: Output
        System.out.println("Swapped values: var1 = " + var1 + ", var2 = " + var2);
    }
}

 

[Question] #2

Java Inheritance / Simple oops [www.techgig.com]

Create Two Classes

BaseClass

The Rectangle class should have two data fields-width and height of Int types. The class should have display() method, to print the width and height of the rectangle separated by space.

DerivedClass

The RectangleArea class is Derived from Rectangle class, I.e., It is the Sub-Class of Rectangle class. The class should have read_Input() method, to Read the Values of width and height of the Rectangle. The RectangleArea dass should also Overload the display() Method to Print the Area (width”height) of the Rectangle.

[Sample Input]

The First and Only Line of Input contains two space separated Integers denoting the width and height of the Rectangle.

Constraints

1 <= width, height <= 10³

[Sample Output]

The Output Should Consist of Exactly Two Lines.

In the First e, Print the Width and Height of the Rectangle Separated by Space.

In Second line, Print the Area of the Rectangle

  1. Code Explaination:

  1. Class Structure:
    • Two classes: Rectangle for storing dimensions and RectangleArea for calculation.
    • Inheritance: RectangleArea extends Rectangle for added functionality.
  2. User Input:
    • The program collects user input for rectangle width and height.
    • Input uses the Scanner class, and clear prompts are provided.
  3. Display Method Override:
    • RectangleArea class overrides display method to show dimensions and area.
  4. Area Calculation:
    • The program calculates the rectangle area by multiplying width and height.
  5. Main Method:
    • The entry point creates an instance of RectangleArea.
    • Displays a user-friendly interface with a title and prompts.
    • Collects user input and displays rectangle dimensions and area.
  6. User-Friendly:
    • The code offers a clear and user-friendly interface.
  7. Purpose:
    • Allows users to calculate the area of a rectangle from its dimensions. It follows best coding practices for clarity and usability.

 GitHub Repo link: http://surl.li/lyipp

Source Code(Java):

import java.util.Scanner;

class Rectangle {
    int width;
    int height;

    public void display() {
        System.out.println("Rectangle dimensions: " + width + " x " + height);
    }
}

class RectangleArea extends Rectangle {
    public void readInput() {
        Scanner scanner = new Scanner(System.in);

        System.out.print("Enter the width of the rectangle: "+"\n");
        width = scanner.nextInt();

        System.out.print("Enter the height of the rectangle: "+"\n");
        height = scanner.nextInt();

        scanner.close();
    }

    @Override
    public void display() {
        super.display(); // Display dimensions from the parent class

        int area = width * height;
        System.out.println("Area of the rectangle: " + area);
    }
}

public class Codeathon05_02_Venkata {
    public static void main(String[] args) {
        RectangleArea rectangleArea = new RectangleArea();
        System.out.println("Rectangle Area Calculator");
        System.out.println("--------------------------"+"\n");

        rectangleArea.readInput(); // Prompt user to enter width and height
        rectangleArea.display();   // Display rectangle dimensions and area
    }
}

 

Thank you

Venkata kishore T(Intern)

Shield Warriors,

Data Shield Team,

Enterprise Minds.


 

 


EM-Tirupati Codeathon Series #04

[Question]

Java Advanced — Lambda Expressions [www.techgig.com]

Write the Following Methods that Return a Lambda Expression Performing a Specified Action: Perform Operation is Odd(): The Lambda Expression must return if a Number is Odd or If it is Even. Perform Operation is Prime(): The lambda expression must return if a number is prime or if it is composite. Perform Operation is Palindrome(): The Lambda Expression must return if a number is a Palindrome or if it is not.

[Sample Input]

Input is as Show in the Format Below (Deduce Unknowns!)

Input

3

1 3

2 7

3 7777

Constraints

NA

[Sample output]

Output is as Show in the Format Below (Deduce Unknowns!)

Output

ODD

PRIME

PALINDROME

Code Explaination:

  1. This program uses lambda expressions and functional interfaces to encapsulate different operations for checking numbers, making the code more modular and readable.
  2. The program defines a functional interface called Operation with a single method apply, which takes an integer and returns a boolean.
  3. The ValueChecker class provides methods to create lambda expressions using the Operation functional interface for three specific operations: checking if a number is odd, checking if it's prime, and checking if it's a palindrome.
  4. In the main method of the Question04_Venkata class:
    • An instance of ValueChecker is created.
    • The program reads the number of test cases from the user.
    • For each test case:
      • The program reads two integers from the user, representing a choice and a number.
      • Depending on the choice (1, 2, or 3), it selects the corresponding lambda expression from ValueChecker.
      • The selected lambda expression is applied to the input number using the apply method of the Operation functional interface.
      • The result is stored as a string, indicating whether the input number meets the criteria (e.g., "ODD," "PRIME," "COMPOSITE," "PALINDROME," or "NOT PALINDROME").
      • The results are added to a list.
  5. After processing all test cases, the program displays the results by iterating through the list and printing each result. 

GitHub Repo link: http://surl.li/mpkit

Source Code(Java):

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.StringTokenizer;

// Step 1: Define a functional interface for operations.
interface Operation {
   boolean apply(int number);
}

class ValueChecker {
   public static boolean checkValue(Operation operation, int number) {
      return operation.apply(number);
   }
   // Step 2: Implement methods for operations as lambda expressions.
   public static Operation isOdd() {
      return n -> (n & 1) == 1; // Checks if a number is odd.
   }

   public static Operation isPrime() {
      return n -> {
         if (n < 2) {
            return false;
         }
         int sqrt = (int) Math.sqrt(n);
         for (int i = 2; i <= sqrt; i++) {
            if (n % i == 0) {
               return false;
            }
         }
         return true; // Checks if a number is prime.
      };
   }

   public static Operation isPalindrome() {
      return n -> {
         String original = Integer.toString(n);
         String reversed = new StringBuilder(Integer.toString(n)).reverse().toString();
         return original.equals(reversed); // Checks if a number is a palindrome.
      };
   }
}

public class Question04_Venkata {
   public static void main(String[] args) {
      ValueChecker valueChecker = new ValueChecker();
      Scanner scanner = new Scanner(System.in);
      int testCases = scanner.nextInt();
      Operation operation;
      String result = null;
      scanner.nextLine();
      List<String> results = new ArrayList<>();

      while (testCases-- > 0) {
         String input = scanner.nextLine().trim();
         StringTokenizer tokenizer = new StringTokenizer(input);
         int choice = Integer.parseInt(tokenizer.nextToken());
         int number = Integer.parseInt(tokenizer.nextToken());

         // Step 3: Use the functional interfaces to check values.
         if (choice == 1) {
            operation = valueChecker.isOdd();
            result = valueChecker.checkValue(operation, number) ? "ODD" : "EVEN";
         } else if (choice == 2) {
            operation = valueChecker.isPrime();
            result = valueChecker.checkValue(operation, number) ? "PRIME" : "COMPOSITE";
         } else if (choice == 3) {
            operation = valueChecker.isPalindrome();
            result = valueChecker.checkValue(operation, number) ? "PALINDROME" : "NOT PALINDROME";
         }

         results.add(result);
      }

      scanner.close();

      // Step 4: Display the results.
      for (String output : results) {
         System.out.println(output);
      }
   }
}


Thank you

Venkata kishore T(Intern)

Shield Warriors,

Data Shield Team,

Enterprise Minds.

EM-Tirupati Codeathon Series #03

[Question]

Monkeys in the Garden [www.techgig.com]

In a garden, trees are arranged in a circular fashion with an equal distance between two adjacent trees. The height of trees may vary. Two monkeys live in that garden and they were very close to each other. One day they quarreled due to some misunderstanding. None of them were ready to leave the garden. But each one of them wants that if the other wants to meet him, it should take maximum possible time to reach him, given that they both live in the same garden.

The conditions are that a monkey cannot directly jump from one tree to another. There are 30 trees in the garden. If the height of a tree is H, a monkey can live at any height from 0 to H. Lets say he lives at the height of K then it would take him K unit of time to climb down to the ground level. Similarly, if a monkey wants to climb up to K height it would again take K unit of time. The time to travel between two adjacent trees is 1 unit. A monkey can only travel in a circular fashion in the garden because there is a pond at the center of the garden.

So the question is where should two monkeys live such that the traveling time between them is maximum while choosing the shortest path between them in any direction clockwise or anti-clockwise. You have to answer only the maximum traveling time.

[Sample Input]

The First Line consists of Total Number of Trees (N). Each of the Following N Lines contains the Height of Trees in a Clockwise Fashion.

Constraints

1 <= Total Trees <= 30

1 <= Height Of Trees(H) <= 10000

[Sample Output]

You must Print an Integer which will be the Maximum Possible Travel Time.


Code Explaination:

  1. The program, "Question03_Venkata," calculates the maximum travel time for two monkeys in a circular garden with varying tree heights.
  2. Users are prompted to input the number of trees and their respective heights.
  3. The calculateMaximumTravelTime method computes the maximum travel time by iterating through each tree as a potential starting point for one of the monkeys.
  4. For each pair of trees, the method calculates clockwise and anticlockwise distances, choosing the shortest path and adding tree heights to determine the total time.
  5. The program employs a Scanner to collect user input and displays the maximum travel time once calculated.
  6. It offers a straightforward tool for analyzing travel times between trees in a circular garden with variable tree heights.
GutHub Repo link : https://rb.gy/bf1d5

Source Code(Java):

import java.util.Scanner;

public class Question03_Venkata {

   /**
    * Calculates the maximum travel time for two monkeys in a circular garden.
    */
  
public static int calculateMaximumTravelTime(int[] treeHeights) {
      int maxTravelTime = 0;
      int n = treeHeights.length;

      for (int i = 0; i < n; i++) {
         int maxTime = 0;

         for (int j = i + 1; j < n; j++) {
            int clockwiseDistance = (n - j + i) % n;
            int anticlockwiseDistance = (j - i) % n;
            int shortestDistance = Math.min(clockwiseDistance, anticlockwiseDistance);

            int totalTime = shortestDistance + treeHeights[i] + treeHeights[j];
            maxTime = Math.max(maxTime, totalTime);
         }

         maxTravelTime = Math.max(maxTravelTime, maxTime);
      }

      return maxTravelTime;
   }

   public static void main(String[] args) {
      Scanner scanner = new Scanner(System.in);

      System.out.print("Enter the number of trees: ");
      int n = scanner.nextInt();

      int[] treeHeights = new int[n];

      System.out.println("Enter the heights of trees (one on each line):");
      for (int i = 0; i < n; i++) {
         treeHeights[i] = scanner.nextInt();
      }

      int maxTravelTime = calculateMaximumTravelTime(treeHeights);
      System.out.println("Maximum Traveling Time: " + maxTravelTime);

      scanner.close();
   }
}

Thank you

Venkata kishore T(Intern)

Shield Warriors,

Data Shield Team,

Enterprise Minds.

 

EM-Tirupati Codeathon Series #02

[Question]

Algorithms/Data Structures — [Problem Solving]

An Institutional Broker wants to Review their Book of Customers to see which are Most Active. Given a List of Trades By “Customer Name, Determine which Customers Account for At Least 5% of the Total Number of Trades. Order the List Alphabetically Ascending By Name.”

Example

n = 23

“Customers = {“Big Corp”, “Big Corp”, ”Acme”, “Big Corp”, “Zork” ,”Zork” ,”Abe”, “Big Corp”, “Acme”, “Big Corp” ,”Big Corp”, “Zork”, “Big Corp”, “Zork”, “Zork”, “Big Corp”,” Acme”, ”Big Corp”, “Acme”, “Big Corp”, “Acme”, “Little Corp”, “Nadir Corp”}

 “Big Corp had 10 Trades out of 23, which is 43.48% of the Total Trades.”

 “Both Acme and Zork had 5 trades, which is 21.74% of the Total Trades.”

“The Little Corp, Nadir Corp and Abe had 1 Trade Each, which is 4.35%…”

“So the Answer is [“”Acme””, “” Big Corp ,””Zork””] (In Alphabetical Order) Because only These Three Companies Placed at least 5% of the Trades.

Constraints

• 1 < n < 10⁵
• 1 < Length of customers[] < 20
• The First Character of customers[i] is a Capital English letter.
• All Characters of customers[i] except for the First One are Lowercase.
 Guaranteed that At least One Customer makes at least 5% of Trades.

[Sample Input]

“The First Line contains an integer, n, The Number of Elements in customers.”

“Each Line of the n Subsequent Lines (where 0 s i< n) contains a string, customers[i].”

Sample Case 0 Input For Custom Testing

20

Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Beta

Fnction Description

Complete the function mostActive in the Editor Below.

  • mostActive has the following parameter:
  • String customers[n]: An Array Customers Names
  • (Actual Questions Says String Array, But Signatures is List of Strings)
  • Returns String[] : An Alphabetically Ascending Array

Constraints

• 1 < n < 10⁵

• 1 < Length of customers[] < 20

• The First Character of customers[i] is a Capital English letter.

• All Characters of customers[i] except for the First One are Lowercase.

• Guaranteed that At least One Customer makes at least 5% of Trades.

[Sample Input]

“The First Line contains an integer, n, The Number of Elements in customers.”

“Each Line of the n Subsequent Lines (where 0 s i< n) contains a string, customers[i].”

Sample Case 0 Input For Custom Testing

20

Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Alpha Omega Beta

Function most ACTIVE

customers[] size n = 20

customers[] = [As Provided Above]

[Sample Output]

Alpha

Beta

Omega

[Explanation of Solution]

In this problem  Alpha made 10 Trades out of 20 (50% of the Total), Omega made 9 Trades (45% of the Total). and Beta made 1 Trade (5% of the Total).All of them have met the 5% Threshold, so all the Strings are Returned in an Alphabetically Ordered Array.

Code Explaination:

  1. This code is written to identify and display the most active traders based on a given list of trades.
  1. The code consists of two classes: MostActiveTraders and Codeathon02_Venkat.
  1. MostActiveTraders contains the core logic for finding and displaying the most active traders, while Codeathon02_Venkat serves as the entry point for user input and result display.
  1. It employs two primary data structures: a Map<String, Integer> named tradeCounts to store trade counts for each trader and a List<String> named activeTraders to store the most active traders.
  1. User input is collected through a Scanner, allowing users to specify the number of trades they want to analyze and provide a list of trades (one trade per line).
  1. The findMostActiveTraders method counts the trades for each trader using a for-each loop and sets a threshold based on the number of trades (in this case, 5% of the total).
  1. Active traders are identified by iterating through the tradeCounts map and adding those whose trade counts exceed the threshold to the activeTraders list.
  1. Active traders are sorted alphabetically using Collections.sort.
  1. The displayActiveTraders method is used to display the active traders to the user.
  1. The code includes exception handling for potential IllegalArgumentException, although there is no specific case in the given code where this exception is thrown.

GitHub Repo link: https://rb.gy/609wc

Source Code(Java):

import java.util.*;

class MostActiveTraders {

    public List<String> findMostActiveTraders(List<String> trades, int numTrades) {

        Map<String, Integer> tradeCounts = new HashMap<>();


        // Count the trades for each trader

        for (String trader : trades) {

            tradeCounts.put(trader, tradeCounts.getOrDefault(trader, 0) + 1);

        }

        int threshold = numTrades * 5 / 100;

        List<String> activeTraders = new ArrayList<>();

        // Find traders with trade counts above the threshold

        for (Map.Entry<String, Integer> entry : tradeCounts.entrySet()) {

            if (entry.getValue() > threshold) {

                activeTraders.add(entry.getKey());

            }

        }

        // Sort the active traders alphabetically

        Collections.sort(activeTraders);

        int totalTrades = trades.size();

        return activeTraders;

    }

    void displayActiveTraders(List<String> activeTraders) {

        System.out.println("Most Active Traders:");

        for (String trader : activeTraders) {

            System.out.println(trader);

        }

    }

}

 

public class Codeathon02_Venkat {

    public static void main(String[] args) {

        MostActiveTraders mat = new MostActiveTraders();

        Scanner scanner = new Scanner(System.in);

        List<String> trades = new ArrayList<>();

        System.out.print("Enter the number of trades you want: ");

        int numTrades = scanner.nextInt();

        scanner.nextLine();

        System.out.println("Enter a list of trades (one trade per line):");

 

        while (trades.size() < numTrades) {

            String input = scanner.nextLine();

            trades.add(input);

        }

        try {

            List<String> activeTraders = mat.findMostActiveTraders(trades, numTrades);

            mat.displayActiveTraders(activeTraders);

        } catch (IllegalArgumentException e) {

            System.out.println("Error: " + e.getMessage());

        }

        scanner.close();

    }

Thank you

Venkata kishore T(Intern)

Shield Warriors,

Data Shield Team,

Enterprise Minds.

Monday, October 9, 2023

EM-Tirupati Codeathon Series #01

[Question]

Algorithms/Data Structures — [Problem Solving]

There is a Specific Need for Changes in a List of Usernames. In a given List of Usernames — For Each Username — If the Username can be Modified and Moved Ahead in a Dictionary. The Allowed Modification is that Alphabets can change Positions in the Given Username.

Example

usernames[] = {“Aab”, “Cat”}

“Aab” cannot be changed to another unique string matching the above rule — Hence, It can Never Find a Place Ahead in the Dictionary. Hence, Output will be “NO”. “Cat” can be Changed to “Act”, “Atc”, “Tca”, “Tac”, “Cta” and Definitely “Act” will Find a Place Before “Cat” in the Dictionary. Hence, Output will be “YES”.

[Function Description]

Complete the function possible Changes in the Editor Below.

Possible Changes has the following parameters:

String usernames[n]: An Array of User Names.

Returns String[n]: An Array with “YES” or “NO” Based on Feasibility

(Actual Question Says String Array, But Signature is List of Strings)

Constraints

• [No Special Constraints Exist, But Cannot Recall Exactly]

[Sample Input]

“The First Line Contains an Integer, n, the Number of Elements in Usernames.”,

“Each Line of the n Subsequent Lines (where 0 < i < n) contains a String usernames[i].”

[Sample Case 0 — Sample Input For Custom Testing]

8

Aab

Cat

Pqrs

Buba

Bapg

Sungi

Lapg

Acba

[Sample Output] (Each Should Be on a Separate Line)

NO YES NO YES YES YES YES YES

Code Explaination:

  1. UsernameValidation is a utility class that encapsulates methods related to username validation and result display.

  2. The possibleChanges method takes a username as input and checks if it can be modified. It compares each character with the characters that follow it and returns true if any character is followed by a smaller character, indicating that the username can be modified.
  3. The displayResults method takes an array of boolean results and displays them as "YES" if the result is true or "NO" if it's false. 
  4. The Question01_Venkata class is the main class that contains the main method and serves as the entry point for the program.
  5. An instance of the UsernameValidation class called validate is created to utilize its validation and display methods. 
  6. Two Scanner objects, scanner and scanner1, are created to read user input.
  7. The user is prompted to input the number of usernames using scanner.nextInt().
  8. Another prompt is displayed, instructing the user to enter string values (usernames).
  9. An array called usernames is created to store the entered usernames.
  10. A boolean array named results is created to store the validation results for each username.
  11. The possibleChanges method from the validate object is called to validate the username and store the result in the results array.
  12. After all usernames are validated, the displayResults method from the validate object is called to display the results.
  13. Results are shown on the console as "YES" if the validation result is true or "NO" if it's false in an Array.
GitHub Repo link:  http://surl.li/mpjte

Source code (Java) :

import java.util.Scanner;

// This class is for username validation and result display

class UsernameValidation {

    

    // Method to check if the username can be modified

    public static Boolean possibleChanges(String username) {

        for (int i = 0; i < username.length(); i++) {

            char currentChar = username.charAt(i);

            for (int j = i + 1; j < username.length(); j++) {

                char nextChar = username.charAt(j);

                if (nextChar < currentChar) {

                    return true;

                }

            }

        }

        return false;

    }

    // Method to display the results

    public static void displayResults(boolean[] results) {

        System.out.println("Output:");

        for (boolean result : results) {

            System.out.println(result ? "YES" : "NO");

        }

    }

}


public class Question01_Venkata {

    public static void main(String[] args) {

        // Creating an instance of UsernameValidation

        UsernameValidation validate = new UsernameValidation();

        Scanner scanner = new Scanner(System.in);

        System.out.println("Please enter the Size:");

        int size = scanner.nextInt();

        Scanner scanner1 = new Scanner(System.in);

        System.out.println("Please enter the Usernames:");


        // Create an array to store usernames

        String[] usernames = new String[size];

        for (int i = 0; i < size; i++) {

            // Read each username, convert it to lowercase, and store it in the array

            usernames[i] = scanner1.next().toLowerCase();

        }

        // Create an array to store the results

        boolean[] results = new boolean[size];

        // Loop through each username and validate it using the UsernameValidation object

        for (int i = 0; i < size; i++) {

            results[i] = validate.possibleChanges(usernames[i]);

        }

        // Display the results using the displayResults method

        validate.displayResults(results);

    }

}


Thank you

Venkata kishore T(Intern)

Shield Warriors,

Data Shield Team,

Enterprise Minds.


Monday, September 11, 2023

Swagger 3 Annotations In Spring Boot

Introduction:

Swagger 3, also known as OpenAPI 3, is a specification for documenting and defining RESTful APIs. It is the third major version of the Swagger specification, which was originally developed by SmartBear Software and later contributed to the OpenAPI Initiative, a consortium of companies and individuals that work together to standardize and evolve the Swagger/OpenAPI specification.


OpenAPI Specification sets forth a set of guidelines for API development and documentation, encompassing versioning, schema, document structure, and other critical elements, which contributes to creating reliable and consistent APIs.


Swagger provides a range of tools (Swagger Editor, Swagger UI, Swagger Codegen…) to support the development, testing, and documentation of these APIs. So we can think about Swagger 3 as OpenAPI 3 specification implementation.

Swagger 3 vs OpenAPI 3?

  • All Swagger tools, which are supported by SmartBear Software, utilize OpenAPI Specification.
  • But not all OpenAPI tools are Swagger tools. There are many open source and pro tools, which are not related to Swagger, support the OpenAPI 3 Specification.

Swagger 3 annotations

Swagger 3 annotations are already included in springdoc-openapi-ui dependency for Spring Boot 2, or springdoc-openapi-starter-webmvc-ui for Spring Boot 3 with io.swagger.v3.oas.annotations package.

Here are some useful annotations:

      • @Tag
      • @Operation
      • @Parameters and @Parameter
      • @Schema
      • @Hidden or @Parameter(hidden = true) or @Operation(hidden = true)
      • @ApiResponses and @ApiResponse

Swagger 2 to Swagger 3 annotations

Swagger 3 is an updated version of Swagger 2 and has some changes in annotations:

      • @Api → @Tag
      • @ApiIgnore → @Parameter(hidden = true) or @Operation(hidden = true) or @Hidden
      • @ApiImplicitParam → @Parameter
      • @ApiImplicitParams → @Parameters
      • @ApiModel → @Schema
      • @ApiModelProperty(hidden = true) → @Schema(accessMode = READ_ONLY)
      • @ApiModelProperty → @Schema
      • @ApiOperation(value = "foo", notes = "bar") → @Operation(summary = "foo", description = "bar")
      • @ApiParam → @Parameter
      • @ApiResponse(code = 404, message = "foo") → @ApiResponse(responseCode = "404", description = "foo")

Add Swagger 3 into Spring Boot

Spring Boot 3

To use Swagger 3 annotation in Spring Boot 3, you need to add the springdoc-openapi-starter-webmvc-ui dependency to your Maven project’s pom.xml file:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
  <version>2.0.3</version>
</dependency>


Or Gradle project with build.gradle file: 

implementation group: 'org.springdoc', name: 'springdoc-openapi-starter-webmvc-ui', version: '2.0.3'


Spring Boot 2

With earlier version of Spring Boot, you can use springdoc-openapi-ui dependency in Maven project’s pom.xml file:

<dependency>
  <groupId>org.springdoc</groupId>
  <artifactId>springdoc-openapi-ui</artifactId>
  <version>1.6.15</version>
</dependency>


Or Gradle project with build.gradle file:

implementation group: 'org.springdoc', name: 'springdoc-openapi-ui', version: '1.6.15'

Swagger 3 annotations example

Rest API

Assume that we have Spring Boot Application that exposes Rest APIs for a Tutorial application in that:

  • Each Tutorial has id, title, description, published status.
  • Apis help to create, retrieve, update, delete Tutorials.
  • Apis also support custom finder methods such as find by published status or by title.

Methods Urls Actions

POST     /api/tutorials                         create new Tutorial

GET     /api/tutorials                         retrieve all Tutorials

GET     /api/tutorials/:id                         retrieve a Tutorial by :id

PUT     /api/tutorials/:id                         update a Tutorial by :id

DELETE     /api/tutorials/:id                         delete a Tutorial by :id

DELETE     /api/tutorials                         delete all Tutorials

GET     /api/tutorials/published         find all published Tutorials

GET     /api/tutorials?title=[keyword] find all Tutorials which title contains keyword

Let’s use Swagger 3 annotations in our Spring Boot app 

Swagger 3 @Tag annotation

In Swagger 3, the @Tag annotation is used to provide additional information about tags in the Swagger documentation. Tags are used to group API operations together and provide a way to categorize and organize them in a meaningful way.

In following example, the @Tag annotation is used to define a tag called “Tutorial” with description: “Tutorial management APIs”. The tag is then applied to the TutorialController class.

@Tag(name = "Tutorial", description = "Tutorial management APIs")
@RestController
@RequestMapping("/api")
public class TutorialController {

  @PostMapping("/tutorials")
  public ResponseEntity<Tutorial> createTutorial(@RequestBody Tutorial tutorial) {

  }

  @GetMapping("/tutorials")
  public ResponseEntity<List<Tutorial>> getAllTutorials(@RequestParam(required = false) String title) {

  }

  @GetMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {

  }

  @PutMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> updateTutorial(@PathVariable("id") long id, @RequestBody Tutorial tutorial) {

  }

  @DeleteMapping("/tutorials/{id}")
  public ResponseEntity<HttpStatus> deleteTutorial(@PathVariable("id") long id) {
    
  }

  @DeleteMapping("/tutorials")
  public ResponseEntity<HttpStatus> deleteAllTutorials() {
    
  }

  @GetMapping("/tutorials/published")
  public ResponseEntity<List<Tutorial>> findByPublished() {
    
  }
}

When the Swagger documentation is generated, the @Tag annotation will group all of the operations that belong to the “Tutorial” tag together in the documentation. This makes it easy for users to find all of the operations that are related to tutorials.


The @Tag annotation can be added to a method inside a Controller to provide a name and description for the tag. For example:

public class TutorialController {

  @Tag(name = "tutorials", description = "Tutorial APIs")

  @PostMapping("/tutorials")

  public ResponseEntity<Tutorial> createTutorial(@RequestBody Tutorial tutorial) {

  }

                  }

 


Swagger 3 @Operation annotation

In Swagger 3, the @Operation annotation is used to provide metadata for a single API operation.
Here’s an example of how the @Operation annotation can be used in Spring Boot:

public class TutorialController {

  @Operation(
      summary = "Retrieve a Tutorial by Id",
      description = "Get a Tutorial object by specifying its id. The response is Tutorial object with id, title, description and published status.",
      tags = { "tutorials", "get" })
  @GetMapping("/tutorials/{id}")
  public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {

  }
}

In this example, the @Operation annotation provides a summary, description and set tags for the getTutorialById method operation.


Swagger 3 @ApiResponses and @ApiResponse annotation

In Swagger 3, the @ApiResponses annotation can be added to an API operation method to provide a list of possible responses for that operation. Each response is specified using an @ApiResponse annotation.

The @ApiResponse annotation specifies the HTTP status code, description, and content of a response. The content is described using the @Content annotation, which includes the media type and schema of the response body.

 public class TutorialController {

  @ApiResponses({

    @ApiResponse(responseCode = "200", content = { @Content(schema = @Schema(implementation = Tutorial.class), mediaType = "application/json") }),

    @ApiResponse(responseCode = "404", description = "The Tutorial with given Id was not found.", content = { @Content(schema = @Schema()) })

  })

  @GetMapping("/tutorials/{id}")

  public ResponseEntity<Tutorial> getTutorialById(@PathVariable("id") long id) {

  }

}

In this example, the @ApiResponse annotation is used to define two possible responses for the getTutorialById method. The first response (responseCode = "200") indicates a successful response with a JSON representation of the Tutorial object in the response body. The second response (responseCode = "404") indicates that the requested Tutorial Id was not found.


Swagger 3 @Parameter annotation

The @Parameter annotation in Swagger 3 is used to describe a parameter for an operation in an OpenAPI / Swagger document. For example:

public class TutorialController {

  @GetMapping("/tutorials")

  public ResponseEntity<Map<String, Object>> getAllTutorials(

      @Parameter(description = "Search Tutorials by title") @RequestParam(required = false) String title,

      @Parameter(description = "Page number, starting from 0", required = true) @RequestParam(defaultValue = "0") int page,

      @Parameter(description = "Number of items per page", required = true) @RequestParam(defaultValue = "3") int size) {

  }

}

 In the example, the @Parameter annotation describes each of the parameters (title, page, and size) of the getAllTutorials method. The description attribute provides a brief description of each parameter, and the required attribute is set to true to indicate that the parameter is mandatory.

Note that the @Parameter annotation can be used in conjunction with other annotations, such as @RequestParam, @PathVariable, or @RequestBody, depending on the type of parameter being described.

Here is the result:


Or you can use @Parameters annotation to define multiple input parameters for an operation.


public class TutorialController {

  @Parameters({

    @Parameter(name = "title", description = "Search Tutorials by title"),

    @Parameter(name = "page", description = "Page number, starting from 0", required = true),

    @Parameter(name = "size", description = "Number of items per page", required = true)

  })

  @GetMapping("/tutorials")

  public ResponseEntity<Map<String, Object>> getAllTutorials(

      @RequestParam(required = false) String title,

      @RequestParam(defaultValue = "0") int page,

      @RequestParam(defaultValue = "3") int size) {

    return null;

  }

}

Swagger 3 @Schema annotation

In Swagger 3, the @Schema annotation is used in to provide additional information about the schema of a model or parameter in your API.

Let’s use @Schema annotation to define a schema for a Tutorial object.


@Schema(description = "Tutorial Model Information")

public class Tutorial {

  @Schema(accessMode = Schema.AccessMode.READ_ONLY, description = "Tutorial Id", example = "123")

  private long id = 0;

  @Schema(description = "Tutorial's title", example = "Swagger Tutorial")

  private String title;

  @Schema(description = "Tutorial's description", example = "Document REST API with Swagger 3")

  private String description;

  @Schema(description = "Tutorial's status (published or not)", example = "true")

  private boolean published;

  public Tutorial() {

  }

  // getters and setters

}

 

In the example above, the @Schema annotation provides additional information about the Tutorial class and its fields. The description attribute provides a brief description of what each field represents, while the example attribute provides a sample value for each field.

We use accessMode = Schema.AccessMode.READ_ONLY in the id property. This will mark the id property as readOnly: true in the generated OpenAPI definition.

The Schema with its example value is changed now.




Conclusion

By integrating Swagger Annotations with Spring Boot projects, developers can take advantage of improved performance, scalability and increased productivity through automated documentation generation and simplified versioning capabilities. Moreover by leveraging existing framework features such as caching & streaming capabilities included in the Swagger spec; developers can create complex applications in less time which results in cost savings for businesses as well as happier customers who benefit from better performing applications built on top of frameworks like Spring Boot & Swagger integration.


Thank you

Venkata kishore T(Intern)
Shield Warriors,
Data Shield Team,
Enterprise Minds.

EM-Tirupati Codeathon Series #08

[Question] ROBOTIC CRICKET MATCH you should write a program that simulate an automatic cricket match between India and Sri Lanka. The fo...