Wednesday 14 June 2023

SpringBoot Pagination With Bootstrap , jquery and Ajax

If we have a large dataset and we want to present it to the user in smaller chunks, pagination is helpful solution. So in the tutorial, I am showing how to create "SpringBoot Ajax Pagination Example" use JQuery Ajax and Bootstrap to build a table solution for pagination with SpringBoot RestAPIs examples.

The Spring Data JPA provides a useful Pageable interface that provides number of methods for building pagination in the UI side. Even you can sort the data returned by the JPA query using the methods provided in this interface API.





--------------------------------- pom.xml---------------------------------


<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.roytuts</groupId>
<artifactId>springboot-jpa-pageable</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>

<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
</parent>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

---------------------------------- ProductRestController -------------------------------

package com.ramsis.springboot.jpa.pageable.rest.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import com.ramsis.springboot.jpa.pageable.dto.ProductDto;
import com.ramsis.springboot.jpa.pageable.service.ProductService;

@RestController
@CrossOrigin(origins = "*")
public class ProductRestController {

@Autowired
private ProductService productService;

@GetMapping("/product")
public Page<ProductDto> products(Pageable pageable) {
return productService.products(pageable);
}

}


-------------------------------- Product Entity------------------------

package com.ramsis.springboot.jpa.pageable.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table
public class Product {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;

@Column
private String name;

@Column
private String prise;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getPrise() {
return prise;
}

public void setPrise(String prise) {
this.prise = prise;
}

}

---------------------------------- ProductDto ----------------------------

package com.ramsis.springboot.jpa.pageable.dto;

public class ProductDto {

private Integer id;
private String name;
private String prise;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrise() {
return prise;
}
public void setPrise(String prise) {
this.prise = prise;
}

}

------------------------ EntityDtoConverter -------------------------

package com.ramsis.springboot.jpa.pageable.converter;


import com.ramsis.springboot.jpa.pageable.dto.ProductDto;

import com.ramsis.springboot.jpa.pageable.entity.Product;


public final class EntityDtoConverter {


private EntityDtoConverter() {

}


public static ProductDto entityToDto(Product product) {

ProductDto productDto = new ProductDto();


productDto.setId(product.getId());

productDto.setName(product.getName());

productDto.setPrise(product.getPrise());

return productDto;

}


public static Product dtoToEntity(ProductDto productDto) {

Product product = new Product();


product.setId(productDto.getId());

product.setName(productDto.getName());

product.setPrise(productDto.getPrise());

return product;

}


}

---------------------------- ProductService --------------------------

package com.ramsis.springboot.jpa.pageable.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.ramsis.springboot.jpa.pageable.converter.EntityDtoConverter;
import com.ramsis.springboot.jpa.pageable.dto.ProductDto;
import com.ramsis.springboot.jpa.pageable.entity.Product;
import com.ramsis.springboot.jpa.pageable.repository.ProductRepository;

@Service
public class ProductService {

@Autowired
private ProductRepository productRepository;

public Page<ProductDto> products(Pageable pageable) {
Page<Product> products = productRepository.findAll(pageable);

Page<ProductDto> pages = products.map(entity -> {
ProductDto dto = EntityDtoConverter.entityToDto(entity);
return dto;
});

return pages;
}

}


------------------------------- ProductRepository -----------------------------

package com.ramsis.springboot.jpa.pageable.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.ramsis.springboot.jpa.pageable.entity.Product;

public interface ProductRepository extends JpaRepository<Product, Integer> {

}

----------------------------------- table-pagination.js ---------------------------

$(document).ready(function() {

let totalPages = 1;

function fetchNotes(startPage) {

//console.log('startPage: ' +startPage);

/**

* get data from Backend's REST API

*/

$.ajax({

type : "GET",

url : "http://localhost:8080/product",

data: {

page: startPage,

size: 10

},

success: function(response){

$('#noteTable tbody').empty();

// add table rows

$.each(response.content, (i, product) => {

let noteRow = '<tr>' +

'<td>' + product.id + '</td>' +

'<td>' + product.name + '</td>' +

'<td>' + product.prise + '</td>' +

'</tr>';

$('#noteTable tbody').append(noteRow);

});

if ($('ul.pagination li').length - 2 != response.totalPages){

// build pagination list at the first time loading

$('ul.pagination').empty();

buildPagination(response);

}

},

error : function(e) {

alert("ERROR: ", e);

console.log("ERROR: ", e);

}

});

}

function buildPagination(response) {

totalPages = response.totalPages;

var pageNumber = response.pageable.pageNumber;

var numLinks = 10;

// print 'previous' link only if not on page one

var first = '';

var prev = '';

if (pageNumber > 0) {

if(pageNumber !== 0) {

first = '<li class="page-item"><a class="page-link">« First</a></li>';

}

prev = '<li class="page-item"><a class="page-link">‹ Prev</a></li>';

} else {

prev = ''; // on the page one, don't show 'previous' link

first = ''; // nor 'first page' link

}

// print 'next' link only if not on the last page

var next = '';

var last = '';

if (pageNumber < totalPages) {

if(pageNumber !== totalPages - 1) {

next = '<li class="page-item"><a class="page-link">Next ›</a></li>';

last = '<li class="page-item"><a class="page-link">Last »</a></li>';

}

} else {

next = ''; // on the last page, don't show 'next' link

last = ''; // nor 'last page' link

}

var start = pageNumber - (pageNumber % numLinks) + 1;

var end = start + numLinks - 1;

end = Math.min(totalPages, end);

var pagingLink = '';

for (var i = start; i <= end; i++) {

if (i == pageNumber + 1) {

pagingLink += '<li class="page-item active"><a class="page-link"> ' + i + ' </a></li>'; // no need to create a link to current page

} else {

pagingLink += '<li class="page-item"><a class="page-link"> ' + i + ' </a></li>';

}

}

// return the page navigation link

pagingLink = first + prev + pagingLink + next + last;

$("ul.pagination").append(pagingLink);

}

$(document).on("click", "ul.pagination li a", function() {

var data = $(this).attr('data');

let val = $(this).text();

console.log('val: ' + val);

// click on the NEXT tag

if(val.toUpperCase() === "« FIRST") {

let currentActive = $("li.active");

fetchNotes(0);

$("li.active").removeClass("active");

// add .active to next-pagination li

currentActive.next().addClass("active");

} else if(val.toUpperCase() === "LAST »") {

fetchNotes(totalPages - 1);

$("li.active").removeClass("active");

// add .active to next-pagination li

currentActive.next().addClass("active");

} else if(val.toUpperCase() === "NEXT ›") {

let activeValue = parseInt($("ul.pagination li.active").text());

if(activeValue < totalPages){

let currentActive = $("li.active");

startPage = activeValue;

fetchNotes(startPage);

// remove .active class for the old li tag

$("li.active").removeClass("active");

// add .active to next-pagination li

currentActive.next().addClass("active");

}

} else if(val.toUpperCase() === "‹ PREV") {

let activeValue = parseInt($("ul.pagination li.active").text());

if(activeValue > 1) {

// get the previous page

startPage = activeValue - 2;

fetchNotes(startPage);

let currentActive = $("li.active");

currentActive.removeClass("active");

// add .active to previous-pagination li

currentActive.prev().addClass("active");

}

} else {

startPage = parseInt(val - 1);

fetchNotes(startPage);

// add focus to the li tag

$("li.active").removeClass("active");

$(this).parent().addClass("active");

//$(this).addClass("active");

}

});

(function(){

// get first-page at initial time

fetchNotes(0);

})();

});


------------------------------------------------------ index.html -------------------------------------------

<!DOCTYPE html>

<html lang="en">

<head>

<title>Bootstrap Ajax SpringBoot Pagination</title>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, initial-scale=1">

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">

</head>

<body>

<div class="container">

<div class="row">

<div class="col-sm-7" style="background-color: #f6e796; margin: 5px; padding: 5px; border-radius: 5px; margin: auto;">

<div class="alert alert-warning">

<h4>SpringBoot Pagination + Bootstrap + jquery + Ajax </h4>

</div>

<table id="noteTable" class="table table-hover table-sm">

<thead class="thead-dark">

<tr>

<th>Id</th>

<th>Name</th>

<th>Prise</th>

</tr>

</thead>

<tbody>

</tbody>

</table>

<ul class="pagination justify-content-center" style="margin:10px 0; cursor: pointer;">

</ul>

</div>

</div>

</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js" crossorigin="anonymous"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/2.10.2/umd/popper.min.js" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.min.js" crossorigin="anonymous"></script>

<script src="table-pagination.js"></script>

</body>

</html>






Friday 5 May 2023

How to mask and unmask input text in html






<html>
   <head>
      <style>

              .form-group{
                position: relative;
                width: 50%;
                overflow:hidden;
              }

              .form-group > .toggleMask{
                position: absolute;
                top: 0;
                right: -20px;
                text-indent: -30px;
                height:100%;
                line-height: 2;
                pointer-events: auto;
                z-index: 5;
                cursor: pointer;
              }
              .form-group > .toggleMask ~ input{
                padding-right: 30px;
              }
              .form-group > .toggleMask:checked::before{
                content:"\e105";
              }
       </style>

   <script src=https://stacksnippets.net/scripts/snippet-javascript-console.min.js?v=1 type="text/javascript"></script>
   <link href=https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css rel="stylesheet"/>        
  </head>

 <body>
  <div class="form-group">
    <input type='checkbox' class="glyphicon glyphicon-eye-close toggleMask"/>
    <input type="password" id="data" class="form-control" />
    <button onclick="chackdate()"> check </button>
  </div>

   <script>
       document.querySelector('.toggleMask').addEventListener('change', onToggleMaskChange);
        function onToggleMaskChange(){
          this.nextElementSibling.type = this.checked ? 'text' : 'password'
        }                    
                             
       function chackdate(){
          var data = document.getElementById("data").value;
           alert(data);
       }
   </script>    
  </body>
</html>
--------------------------------------------------------------------------------------------------

Mask and unmask text on onmouseover event in html


<html>

  <head>
   <script>
       function mouseover() {
          let obj = document.getElementById('myPassword');
              obj.type = 'text';
       }
       function mouseout() {
          let obj = document.getElementById('myPassword');
              obj.type = 'password';
       }
   </script>

<input type="password" name="password" id="myPassword" size="30" onmouseover="mouseover();" onmouseout="mouseout();" />

</body>
</html>



Thursday 30 March 2023

How to Implement Fuzzy Search or Approximate String Search in Java

What Is Fuzzy Matching ?

Fuzzy Matching or Approximate String Matching is among the most discussed issues in IT.
It is a method that offers an improved ability to identify two elements of text, strings, or entries that are approximately similar but are not precisely the same.
In other words, a fuzzy method may be applied when an exact match is not found for phrases or sentences on a database. Indeed, this method attempts to find a match greater than the application-defined match percentage threshold.

As below mentioned code you can implement Fuzzy Search. 


import org.apache.commons.codec.language.Soundex;
import org.apache.commons.text.similarity.LevenshteinDistance;
import me.xdrop.fuzzywuzzy.FuzzySearch;

public class FuzzySearch {

   public boolean searchFuzzy(String searchableName, String targetName) {
       boolean matches=false;
       int  fuzzySearchNameThreashold=70;
        System.out.println("FuzzySearch.tokenSetRatio(searchableName, targetName) >> "+FuzzySearch.tokenSetRatio(searchableName, targetName));
        System.out.println("levenshteinDistanceMatch(searchableName, targetName) >> "+levenshteinDistanceMatch(searchableName, targetName));
       if((soundexMatch(searchableName,targetName)
        || FuzzySearch.tokenSetRatio(searchableName, targetName) >= fuzzySearchNameThreashold
        || levenshteinDistanceMatch(searchableName, targetName) >= fuzzySearchNameThreashold)) {    
              matches = true;
        }
       return matches;
    }

   public boolean soundexMatch(String searchableName, String targetName) {
         Soundex soundex = new Soundex();
         return soundex.soundex(searchableName).equals(soundex.soundex(targetName));
   }

     public double levenshteinDistanceMatch(String searchableName, String targetName) {
         LevenshteinDistance levenshteinDistance = new LevenshteinDistance();
         return (100 - Math.round((((double) levenshteinDistance.apply(searchableName, targetName) / searchableName.length()) * 100)));
       }

 public static void main(String aa[]) {
       FuzzySearchUtil fuzzySearchUtil = new FuzzySearchUtil();
       boolean flag = fuzzySearchUtil.searchFuzzy("Amn","Aman Kumar");
       System.out.println("flag >> "+flag);
 }

    }
}

----------------------- Maven Dependency -------------------------

           <dependency>
                <groupId>me.xdrop</groupId>
                <artifactId>fuzzywuzzy</artifactId>
                <version>1.3.1</version>
             </dependency>

        <!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
             <dependency>
                 <groupId>commons-codec</groupId>
                 <artifactId>commons-codec</artifactId>
                 <version>1.10</version>
             </dependency>

           <dependency>
              <groupId>org.apache.commons</groupId>
              <artifactId>commons-text</artifactId>
              <version>1.3</version>
           </dependency>




Saturday 26 November 2022

Create Rest APT to Encrypt and Decrypt message using AES/CBC/PKCS5PADDING algorithm

Project Structure



Calling Response from Postman tool





------------------------------------------- Controller ---------------------------------------------
package com.ramsis.encrypt.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.ramsis.encrypt.util.EncryptionDecryption;
import com.ramsis.encrypt.dto.POJO;

@RestController
public class Controller {
   
@Autowired
EncryptionDecryption ecndnc;

@Value("${EncDncKey}")
String publickey;

@CrossOrigin(origins = "*")
@PostMapping("/Ngdecrypt")
public POJO NGdecrypt(@RequestBody POJO pojo) throws Exception {

String msg = pojo.getMessage();
String enckey = pojo.getKeys();
String decryptString = null;
// String publickey = "3K4G2pb4dl8M/7YaOrGiPA=="; // 128 bit key
try {
if (!enckey.equalsIgnoreCase(publickey)) {
System.out.println("You are not Authorised.");
pojo.setMessage("Not Authorised.");
System.out.println(pojo.getMessage());
return pojo;
}

decryptString = ecndnc.decrypt(publickey, null, msg);
pojo.setMessage(decryptString);
} catch (Exception ex) {
ex.getMessage();
}

return pojo;
}

@CrossOrigin(origins = "*")
@PostMapping("/Ngencrypt")
public POJO Ngencrypt(@RequestBody POJO pojo) throws Exception {

String msg = pojo.getMessage();
String enckey = pojo.getKeys();
String encryptString = null;
try {
if (!enckey.equalsIgnoreCase(publickey)) {
System.out.println("You are not Authorised.");
pojo.setMessage("Not Authorised.");
return pojo;
}
encryptString = ecndnc.encrypt(publickey, null, msg);
pojo.setMessage(encryptString);
//System.out.println(encryptString);
} catch (Exception ex) {
ex.getMessage();
}
return pojo;
}
}

----------------------------------------EncryptionDecryption----------------------------------------

package com.ramsis.encrypt.util;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Component;

@Component
public class EncryptionDecryption {

public static String encrypt(String key, String initVector, String value) {
byte[] encrypted =null;
try {
initVector = key.substring(0, 16); // 16 bytes IV
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

   encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string: " + Base64.encodeBase64String(encrypted));
} catch (Exception ex) {
ex.printStackTrace();
}
return Base64.encodeBase64String(encrypted);
}

public static String decrypt(String key, String initVector, String encrypted) {
byte[] original =null;
try {
initVector = key.substring(0, 16);
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
   original = cipher.doFinal(Base64.decodeBase64(encrypted));
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(original);
}

}

------------------------------------------------ CallAPI ----------------------------------------------
package com.ramsis.encrypt.callApi;

import org.json.JSONObject;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

public class CallAPI {

public void restAPITest(String url, String message) {

String key = "3K4G2pb4dl8M/7YaOrGiPA==";
try {
RestTemplate restTemplate = new RestTemplate();
JSONObject personJsonObject = new JSONObject();
personJsonObject.put("keys", key);
personJsonObject.put("message", message);

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

HttpEntity<String> entityHttp = new HttpEntity<String>(personJsonObject.toString(), headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entityHttp, String.class);
/*
* String answer = restTemplate.postForObject(url, entity, String.class);
* System.out.println(answer);
*/
if (response.getStatusCodeValue() == 200) {
System.out.println(response.getBody());
}

} catch (Exception ex) {
ex.printStackTrace();
}
}

public static void main(String args[]) throws Exception {
CallAPI call = new CallAPI();
//call.restAPITest("http://localhost:8080/Ngencrypt", "ramsis-code");
call.restAPITest("http://localhost:8080/Ngdecrypt", "TaZydiy5PHtA4ME8744bOA==");

}
}

Sunday 20 November 2022

Spring Boot Rest API OneToMany Relationship with JPA Repository

In this Post I am showing how you can easily create a Rest API using JPA Repository with OneToMany Relationships between two Entities.

Project Structure



Calling Response from Postman tool














------------------------------------------ json ------------------------------------------------

{
"title":"Linux",
"author": "Jimmy",
"isbn": "890900",
    "pages" : [{ "number": "30", "content": "Switches", "chapter" : "3"},{ "number": "125", "content":          "Router", "chapter" : "8"}]
}


------------------------------------------ pom.xml -------------------------------------------

# Changing the server port
server.port=9090

# MySQL connection properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=cctns@123
spring.datasource.url=jdbc:mysql://localhost:3306/testdb?createDatabaseIfNotExist=true&useSSL=false

# Log JPA queries
# Comment this in production
spring.jpa.show-sql=true

# Drop and create new tables (create, create-drop, validate, update)
# Only for testing purposes - comment this in production
spring.jpa.hibernate.ddl-auto=update

# Hibernate SQL dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect


---------------------------------------- Book Entity ------------------------------------------------

package com.ramsis.onetomany.entity;

import java.io.Serializable;
import java.util.Objects;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@Entity
@Table(name = "books")
public class Book implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "title" ,nullable = false)
    private String title;
    @Column(name = "author" ,nullable = false)
    private String author;
    @Column(name = "isbn" ,unique = true)
    private String isbn;
    @JsonIgnoreProperties("book")
    @OneToMany(mappedBy = "book", fetch = FetchType.LAZY,
            cascade = CascadeType.ALL)
    private Set<Page> pages;

    public Book() {
    }

    public Book(String title, String author, String isbn) {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public Set<Page> getPages() {
        return pages;
    }

    public void setPages(Set<Page> pages) {
        this.pages = pages;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return id.equals(book.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", author='" + author + '\'' +
                ", isbn='" + isbn + '\'' +
                '}';
    }
}

------------------------------------------ Page Entity -----------------------------------------------

package com.ramsis.onetomany.entity;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Objects;

@Entity
@Table(name = "pages")
public class Page implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
   
    @Column(name = "number", nullable = false)
    private int number;
   
    @Column(name = "content" ,nullable = false)
    private String content;
   
    @Column(name = "chapter", nullable = false)
    private String chapter;
   
    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "book_id", nullable = false)
    private Book book;

    public Page() {
    }

    public Page(int number, String content, String chapter, Book book) {
        this.number = number;
        this.content = content;
        this.chapter = chapter;
        this.book = book;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getChapter() {
        return chapter;
    }

    public void setChapter(String chapter) {
        this.chapter = chapter;
    }

    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Page page = (Page) o;
        return id.equals(page.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }

    @Override
    public String toString() {
        return "Page{" +
                "id=" + id +
                ", number=" + number +
                ", content='" + content + '\'' +
                ", chapter='" + chapter + '\'' +
                ", book=" + book +
                '}';
    }
}

----------------------------------------------- BookService -----------------------------------------

package com.ramsis.onetomany.service;

import java.util.List;
import java.util.Set;

import com.ramsis.onetomany.dto.BookDto;
import com.ramsis.onetomany.entity.Book;
import com.ramsis.onetomany.entity.Page;

public interface BookService {

public List<Book> getBooks();
public Book addBook(BookDto book);
public Book updateBook(BookDto book);
public Book getBookByIsbn(String id);

}

-------------------------------------------------BookServiceImpl ----------------------------------

package com.ramsis.onetomany.service;

import java.util.List;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ramsis.onetomany.dto.BookDto;
import com.ramsis.onetomany.dto.PageDto;
import com.ramsis.onetomany.entity.Book;
import com.ramsis.onetomany.entity.Page;
import com.ramsis.onetomany.repository.BookRepository;
import com.ramsis.onetomany.repository.PageRepository;

@Service
public class BookServiceImpl implements BookService {

@Autowired
BookRepository bookRepo;

@Autowired
PageRepository pageRepo;

@Override
public Book getBookByIsbn(String id) {
// TODO Auto-generated method stub
return bookRepo.findByIsbn(id);
}

@Override
public Book addBook(BookDto book) {
Book bookEntity = new Book();
Page pageEntity = null;
bookEntity.setAuthor(book.getAuthor());
bookEntity.setIsbn(book.getIsbn());
bookEntity.setTitle(book.getTitle());
Set<PageDto> pageList = book.getPages();
Book bookEntityobj = bookRepo.save(bookEntity);

for (PageDto pagedata : pageList) {
pageEntity = new Page(
pagedata.getNumber(),
pagedata.getContent(),
pagedata.getChapter(),
bookEntityobj);
pageRepo.save(pageEntity);
}

return bookEntityobj;
}

@Override
public Book updateBook(BookDto book) {
Book bookEntity = new Book();
Page pageEntity = null;
bookEntity.setAuthor(book.getAuthor());
bookEntity.setIsbn(book.getIsbn());
bookEntity.setTitle(book.getTitle());
Set<PageDto> pageList = book.getPages();
Book bookEntityobj = bookRepo.save(bookEntity);

for (PageDto pagedata : pageList) {
pageEntity = new Page(
pagedata.getNumber(),
pagedata.getContent(),
pagedata.getChapter(),
bookEntityobj);
pageRepo.save(pageEntity);
}

return bookEntityobj;
}

@Override
public List<Book> getBooks() {
// TODO Auto-generated method stub
return  (List<Book>) bookRepo.findAll();
}

}

---------------------------------------------- Controller ---------------------------------------------

package com.ramsis.onetomany.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import com.ramsis.onetomany.dto.BookDto;
import com.ramsis.onetomany.entity.Book;
import com.ramsis.onetomany.service.BookService;

@RestController
public class PageBookController {
   
@Autowired
BookService bookService;

@GetMapping("/home")
public String home() {
return "Welcome in RestApi with OneToMany Relation, home Page";
}

@PostMapping("/addBook" )
public Book addBook(@RequestBody  BookDto book) {
return this.bookService.addBook(book);
}

@PostMapping("/updateBook" )
public Book updateBook(@RequestBody  BookDto book) {
return this.bookService.updateBook(book);
}

@GetMapping("/getBookIsbn/{eid}")
public Book getBookByIsbn(@PathVariable("eid") String eid) {
return this.bookService.getBookByIsbn(eid);
}

@GetMapping("/getBooks")
public List<Book> getBooks() {
return this.bookService.getBooks();
}
}

------------------------------------------------- BookDto --------------------------------------------

package com.ramsis.onetomany.dto;

import java.util.Set;

public class BookDto {
private Long id;
private String title;
private String author;
private String isbn;
private Set<PageDto> pages;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public Set<PageDto> getPages() {
return pages;
}
public void setPages(Set<PageDto> pages) {
this.pages = pages;
}

}

-------------------------------------------------- PageDto -------------------------------------------

package com.ramsis.onetomany.dto;

public class PageDto {
private Long id;
private int number;
private String content;
private String chapter;
private BookDto book;

public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getChapter() {
return chapter;
}
public void setChapter(String chapter) {
this.chapter = chapter;
}
public BookDto getBook() {
return book;
}
public void setBook(BookDto book) {
this.book = book;
}

}


------------------------------------------------- OnetomanyApplication -------------------------

package com.ramsis.onetomany;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

import com.ramsis.onetomany.repository.BookRepository;
import com.ramsis.onetomany.repository.PageRepository;

@SpringBootApplication
@EnableJpaAuditing
public class OnetomanyApplication {

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


@Bean
   public CommandLineRunner mappingDemo(BookRepository bookRepository,
                                        PageRepository pageRepository) {
       return args -> {
        /*
        System.out.print( bookRepository.findById(Long.valueOf(1)));
           // create a new book
           Book book = new Book("Linux", "Cdac", "99844");

           // save the book
           bookRepository.save(book);

           // create and save new pages
           pageRepository.save(new Page(2, "Introduction contents of Linux", "Intro", book));
           pageRepository.save(new Page(102, "Switches", "Switches WAN", book));
           pageRepository.save(new Page(70, "Router", "Router WAN", book));
         
           */
       };
   }
}

-------------------------------------------- BookRepository ---------------------------------------

package com.ramsis.onetomany.repository;

import org.springframework.data.repository.CrudRepository;

import com.ramsis.onetomany.entity.Book;

public interface BookRepository extends CrudRepository<Book, Long> {

    Book findByIsbn(String isbn);
    Book save(Book book);
}

--------------------------------------------------------

Saturday 10 September 2022

Enabling Cross Origin Requests for a RESTful Web Service
How to Resolve Cross Origin Error in Java Spring Application




This Cross Origin Error Occurs then you are trying to access your Spring boot or Spring Application from outer source. Like Angular, React and other ways.
you can resolve this Error by creating A Cross CORSFilter or you can create simpleCorsFilter Bean in Configuration class

------------------------------------------- CORSFilter ----------------------------------------------------------

import javax.servlet.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
 
 @Component
  public class CORSFilter implements Filter {
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException{
  HttpServletResponse response = (HttpServletResponse) res;
  response.setHeader("Access-Control-Allow-Origin", "*");
  response.setHeader("Access-Control-Allow-Methods", "POST, GET");
  response.setHeader("Access-Control-Max-Age", "3700");
  response.setHeader("Access-Control-Allow-Headers","Content-Type");
  response.setHeader("Access-Control-Allow-Credentials","true");
  chain.doFilter(req, res);
  }
  public void init(FilterConfig filterConfig) {
  }
  public void destroy() {
  }
  }

------------------------------------------------------ simpleCorsFilter  Bean -------------------------------------

@Bean
public FilterRegistrationBean simpleCorsFilter() {  
   UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();  
   CorsConfiguration config = new CorsConfiguration();  
   config.setAllowCredentials(true);
   // *** URL below needs to match the Vue client URL and port ***
   config.setAllowedOrigins(Collections.singletonList("https://192.168.1.204:4200"));
   config.setAllowedMethods(Collections.singletonList("*"));  
   config.setAllowedHeaders(Collections.singletonList("*"));  
   source.registerCorsConfiguration("/**", config);
   
   FilterRegistrationBean bean = new FilterRegistrationBean<>(new CorsFilter(source));
   bean.setOrder(Ordered.HIGHEST_PRECEDENCE);  
   return bean;  
}  


Wednesday 3 August 2022

How to create A Pagination using Hibernate in Java








----------------------------- DAO.java ---------------------------------------

package com.ramsiscode;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.criterion.Projections;


public class DAO {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
private static int pageSize = 8;
Session session = null;
public  List getData(int pageNumber) {
 
  //Session session = sessionFactory.getCurrentSession();
 
  List result = null;
  try {
session = sessionFactory.openSession();
    session.beginTransaction();
   
    Query query = session.createQuery("from Employee");
     query = query.setFirstResult(pageSize * (pageNumber - 1));
     query.setMaxResults(pageSize);
     
    result = query.list();
    session.getTransaction().commit();
  } catch (Exception e) {
    e.printStackTrace();
  }finally{
  if(session!=null){
  session.close();
  }
  }
  return result;
}
 

  public  Long getMaxRow() {
  Long result = 0l;
 // SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
  //Session session =null;
  try{
  session = sessionFactory.openSession();  
  session.beginTransaction();
  Criteria crit = session.createCriteria(Employee.class);
  crit.setProjection(Projections.rowCount());
 
  //result = session.createCriteria(Employee.class).setProjection(Projections.rowCount());
  //Query query = session.createQuery("select COUNT(empId) from Employee");
  session.getTransaction().commit();
 
  if(crit.list().size()>0)
  {
  result=   (Long) crit.list().get(0);
  }
 
  System.out.println("--------- rowCount -------- "+result);
 
 
  }catch(Exception e)
  {e.printStackTrace();}
  finally{
 if(session!=null){
  session.close();
  }
  }
  return result;
  }


private static Integer parseInt(Object object) {
// TODO Auto-generated method stub
return null;
}
}

------------------------------ Employee.java ------------------------

package com.ramsiscode;
import java.io.*;
public class Employee {
public long empId;
public String empName=null;
public String empJob=null;
public long empSal;
public long getEmpId() {
return empId;
}
public void setEmpId(long empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public String getEmpJob() {
return empJob;
}
public void setEmpJob(String empJob) {
this.empJob = empJob;
}
public long getEmpSal() {
return empSal;
}
public void setEmpSal(long empSal) {
this.empSal = empSal;
}

}

---------------------------- PaginationCreateQueryControl.java -------------------------------

package com.ramsiscode;
import java.io.DataInputStream;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class PaginationCreateQueryControl {
private static  SessionFactory sessionFactory;
 private Session getSession()
 {
 Session s =null;
    try{
sessionFactory = new Configuration().configure("com\\xml\\hibernate.cfg.xml").buildSessionFactory();
s=sessionFactory.openSession();
}catch(HibernateException e){
System.out.println(e.getMessage());
  }finally{
  if(s!=null){
  s.close();
  }
  }
  return s;
 }

 public  List param(String[] args) throws Exception
{
List list = null;
Session s = getSession();
try{
DataInputStream ds=new DataInputStream(System.in);
System.out.println("*********************\n");
System.out.println("Enter the Degree to Search");
String first=ds.readLine();

Query query = s.createQuery("from Student stu where stu.degree = :deg order by stu.id ASC");
query.setString("deg",first);
query.setFirstResult(0);
query.setMaxResults(3);
list = query.list();
}catch(HibernateException e)
  {
    System.out.println(e.getMessage());
     }finally{
  if(s!=null){
  s.close();
  }
  }
  return list;
  }
}

---------------------------- Employee.hbm.xml ------------------------

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.ramsiscode.Employee" table="emp">
   <id name="empId" column="EMPNO" type="long">
     <generator class="native"/>
   </id>
   <property name="empName" column="ENAME" />
   <property name="empJob" column="JOB" />
   <property name="empSal" column="SAL" type="long"/>
 </class>
</hibernate-mapping>

----------------------------- hibernate.cfg.xml ------------------------

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="studentFactory">
       <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://10.68.238.96:3306/exampledb</property>
<property name="connection.username">cctns_app</property>
<property name="connection.password">cctns@123</property>
       <property name="connection.pool_size">5</property>
       <!-- SQL dialect -->
       <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
       <!-- Echo all executed SQL to stdout -->
       <property name="show_sql">true</property>
  <property name="hbm2ddl.auto">update</property>
<mapping resource="\com\\xml\\Student.hbm.xml"/>
<mapping resource="\com\\xml\\Employee.hbm.xml"/>

</session-factory>
</hibernate-configuration>

--------------------------- pagingEmp.jsp --------------------------


  <%@page import="com.ramsiscode.DAO" %>
  <%@page import="java.util.List" %>
  <%@page import="java.lang.Math" %>
  <%@page import="java.util.ArrayList" %>
  <%@ taglib uri='http://java.sun.com/jsp/jstl/core' prefix='c'%>
  <jsp:directive.page contentType="text/html; charset=UTF-8" />
 <link rel="stylesheet" type="text/css" href="css/screen.css" />
 <%
     int pageNumber=1;
     int footerPageLimit =4;
     String  prePage ="1";
     String nextPage ="1";
   
     int empListSize = 0;
     List sizeList =(List)  session.getAttribute("EmpList");
     if(sizeList!=null){
    empListSize = ((Integer) sizeList.size());
     }
     
     DAO dao = new DAO();
     Long   maxRow = dao.getMaxRow();
     System.out.println("maxRow size ------------"+maxRow);
     Integer pageLinks = Math.round(maxRow/8)+1;
     System.out.println("pageLinks ------------"+pageLinks);
     session.setAttribute( "pageLinks", pageLinks);

     
     if(request.getParameter("page") != null) {
       session.setAttribute("page", request.getParameter("page"));
       pageNumber = Integer.parseInt(request.getParameter("page"));
       
        Integer pageLinks_Session = (Integer) session.getAttribute("pageLinks");
        if(pageNumber>(pageLinks_Session)){
      pageNumber=1;
       }
       
        if(empListSize==0){
      pageNumber=1;
       }
       
       nextPage = (pageNumber +1) + "";
       prePage = (pageNumber -1) + "";
 
       String pages = request.getParameter("page");
      if(pages.equalsIgnoreCase("1")){
      prePage="1";
       }
     } else {
       session.setAttribute("page", "1");
     }
     
     /**********************************/
   
     session.setAttribute( "EmpList", dao.getData(pageNumber));

     
     /**********************************/

     
     System.out.println("empListSize : "+empListSize);
     if(empListSize==0){
    session.setAttribute("page", "1");
    nextPage ="1";
    prePage ="1";
     }
     
     int  prePages = (pageNumber)- 1;
     prePage =(String.valueOf(prePages));
     if(pageNumber==1){
    prePage ="1";
     }
     
     /**********************************/
     int startPage=  pageNumber;
     int endPage =  startPage+footerPageLimit-1;
     if(empListSize==0){
    startPage = 1;
    endPage = startPage+footerPageLimit-1;
     }
     /* if(pageNumber>=pageLinks){
    startPage=pageNumber;
    endPage=pageNumber;
     } */
     /**********************************/
     
     String myUrl = "pagingEmp.jsp?page=" + nextPage;
     String preUrl = "pagingEmp.jsp?page=" + prePage;
     System.out.println(myUrl);
 
     pageContext.setAttribute("myUrl", myUrl);
     pageContext.setAttribute("preUrl", preUrl);
%>
 <h2 align="center">Hibernate Pagination</h2>
<%--  <jsp:useBean id="EmpList" scope="request" type="java.util.List"></jsp:useBean> --%>

 <table>
   <tr>
     <th>Emp Id</th>
     <th>Name</th>
     <th>Job</th>
     <th>Salary</th>
   </tr>
   <c:forEach items="${EmpList}" var="emp" begin="0" end="10">
     <tr>
       <td><c:out value="${emp.empId}"></c:out></td>
       <td><c:out value="${emp.empName}"></c:out></td>
       <td><c:out value="${emp.empJob}"></c:out></td>
       <td><c:out value="${emp.empSal}"></c:out></td>
     </tr>
   </c:forEach>
 </table>
 <BR/>
 <Table>
 <tr>
 <td colspan="2"><a href="${pageScope.preUrl}"><<&nbsp;previous</a>&nbsp;
     <c:forEach  var="i" begin="<%=startPage %>" end="<%=endPage %>">
        <a href="?page=${i}"> <c:out value="${i}"></c:out></a>
     </c:forEach>
     &nbsp; <a href="${pageScope.myUrl}">nextPage&nbsp;>></a></td>
 </tr>
 </Table>

Download Code