Java @ Desk | Java at your desk

Implement Scheduler in Spring Boot

Implement Scheduler in Spring Boot

Scheduler is implemented in Spring Boot using org.springframework.scheduling.annotation.Scheduled annotation. It takes input as a cron expression along with the time zone.

The @Scheduled annotation is used with a method that performs specific tasks at regular intervals. The package of the scheduler class need to be provided in the Spring Boot main application using scanBasePackages property. During deployment, Spring scans the component provided in scanBasePackages and schedules based on cron provided in scheduler class.

Here is the sample code for the same.
import java.time.LocalDateTime;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyScheduler {

 final Logger logger = LoggerFactory.getLogger(MyScheduler.class);

 /* scheduled to run at every 5 minutes */
 @Scheduled(cron = "0 0/5 * * * *", zone = "Asia/Calcutta")
 public void run() {
  logger.debug("Scheduler Service Started at " + LocalDateTime.now());
 }

}


Spring Boot Main class
The main class must provide below annotation along with scanBasePackages.
@SpringBootApplication(scanBasePackages = { "com.scheduler" })

Default method in interface in Java

Default method in interface in Java

Default methods have been introduced in Java 8 in order to extend the feature providing an default implementation across all implementation classes.
The main intention of introducing default method is to have a method with implementation in an existing interface without affecting implementation classes. Introduing a new method declaration in existing interface force the change in all implementation classes. The default method comes with an implementation thus making it all optional for the classes to provide the implementation.
Still, the class can override the default implementation of the default method of interface.
So, interface in Java can define a method. An implementation class may or may not override the default implementation.

package com.learning;

public interface DefaultInterface {

 default public void defaultInterfaceDefinedMethod() {
  System.out.println("Default Interface method is called");
 }
}


package com.learning;

public class DefaultInterfaceImpl implements DefaultInterface {

}


package com.learning;

public class DefaultInterfaceMain {

 public static void main(String args[]) {

  DefaultInterface defaultInterface = new DefaultInterfaceImpl();
  defaultInterface.defaultInterfaceDefinedMethod();
 }

}



For Java 8, the JDK collections have been extended and forEach method is added to the entire collection (which work in conjunction with lambdas). The same mechanism has been used to add Stream in JDK interface without breaking the implementing classes.

What about Multiple Inheritance?
public interface DefaultInterface {

 default public void defaultInterfaceDefinedMethod() {
  System.out.println("Default Interface method is called");
 }
}

public interface DefaultInterfaceTwo {

 default public void defaultInterfaceDefinedMethod() {
  System.out.println("Default Interface Two method is called");
 }
}

public class DefaultInterfaceImpl implements DefaultInterface, DefaultInterfaceTwo {

}


This generates compilation error since the implementation class finds the same default method in both the interfaces. In order to fix this class, we need to provide default method implementation in the class itself i.e. it now becomes mandatory for the class to override the default implementation as shown below
public class DefaultInterfaceImpl implements DefaultInterface, DefaultInterfaceTwo {

 @Override
 public void defaultInterfaceDefinedMethod() {
 }

}


Further, if we want to invoke default implementation provided by any of super interface rather than our own implementation, we can do so as follows,
package com.learning;

public class DefaultInterfaceImpl implements DefaultInterface, DefaultInterfaceTwo {

 @Override
 public void defaultInterfaceDefinedMethod() {
  DefaultInterface.super.defaultInterfaceDefinedMethod();
 }

}


How to iterate a Map of objects using forEach and Lambda in Java 8

How to iterate a Map of objects using forEach and Lambda in Java 8

Prior to Java 8, iterating over a map of object was done using normal Map.Entry interface. In Java 8, forEach method of a Map interface is used to iterate over the map of objects.

forEach method takes 2 parameters as key and value.

Below is the example of the same. Here is a Person class with name, age & address property. The main program creates 3 objects of Person class and iterate over the map using forEach method and prints the key and age of each person.

Person.java
package com.pojo;

public class Person {

 private String id;

 private String name;

 private String address;

 private int age;

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public String getId() {
  return id;
 }

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

 public String getName() {
  return name;
 }

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

 public String getAddress() {
  return address;
 }

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


IterateMap.java
package com.lambda;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.pojo.Person;

public class IterateMap {

 public static void main(String args[]) {

  Map<String, Person> personMap = new HashMap<>();

  Person person = new Person();
  person.setAge(20);
  personMap.put("FirstPerson", person);

  Person personOne = new Person();
  personOne.setAge(25);
  personMap.put("SecondPerson", personOne);

  Person personTwo = new Person();
  personTwo.setAge(32);
  personMap.put("ThirdPerson", personTwo);

  Person personThree = new Person();
  personThree.setAge(14);
  personMap.put("FourthPerson", personThree);

  personMap.forEach((key, personValue) -> {
   System.out.println("Key : " + key + ", Person Age : " + personValue.getAge());
  });
 }
}


How to iterate a List of objects using forEach and Lambda in Java 8

How to iterate a List of objects using forEach and Lambda in Java 8

Prior to Java 8, iterating over a list of object was done using normal for loop or advanced for loop in case of Generics collection. In Java 8, forEach method of a List interface is used to iterate over the list of objects.

forEach method takes a single parameter that is actual object type of which the collection or list object is made of.

Below is the example of the same. Here is a Person class with name, age & address property. The main program creates 3 objects of Person class and iterate over the list using forEach method and prints the age of each person.

Person.java
package com.pojo;

public class Person {

 private String id;

 private String name;

 private String address;

 private int age;

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public String getId() {
  return id;
 }

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

 public String getName() {
  return name;
 }

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

 public String getAddress() {
  return address;
 }

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


IterateList.java
package com.lambda;

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

import com.pojo.Person;

public class IterateList {

 public static void main(String args[]) {

  List<Person> persons = new ArrayList<>();

  Person person = new Person();
  person.setAge(20);
  persons.add(person);

  Person personOne = new Person();
  personOne.setAge(25);
  persons.add(personOne);

  Person personTwo = new Person();
  personTwo.setAge(32);
  persons.add(personTwo);

  Person personThree = new Person();
  personThree.setAge(14);
  persons.add(personThree);

  persons.forEach(personObject -> {
   System.out.println("Person Name - " + personObject.getAge());
  });
 }
}


Format a Date in Java 8 using LocalDateTime

Format a Date in Java 8 using LocalDateTime

Date in Java is formatted using java.time.format.DateTimeFormatter class that formats a date in a particular format. Current date or time is fetched using java.time.LocalDateTime using now() method that returns the current date.

Date returns using now() method is in the format - yyyy-MM-ddTHH:mm:ss. For example, 2017-11-09T19:14:10.402

There are different ways to define the formatter as shown below:
1) DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("yyyy-MM-dd HH:mm:ss").toFormatter(Locale.ENGLISH);
2) DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

Below is the sample program to format a date and get a date in String format.
package com.learning;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Locale;

public class DateFormatJava8 {

 public static void main(String args[]) {

  LocalDateTime now = LocalDateTime.now();

  System.out.println("Original Date - " + now);
  
  DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive().appendPattern("yyyy-MM-dd HH:mm:ss").toFormatter(Locale.ENGLISH);

  String formattedDate = now.format(formatter);
  
  System.out.println("Formatted Date - " + formattedDate);
 }

}


Output:
Original Date - 2017-11-09T19:19:49.428
Formatted Date - 2017-11-09 19:19:49

Filter Java Collection using Java 8 Lambda & Stream Filter

Filter Java Collection using Java 8 Lambda & Stream Filter

In this post, we will learn how to filter a list based on certain criteria. If we have a list of objects and we need a filtered list based on certain condition, then prior to Java 8 we need to iterate through the list and apply if conditions and get each object to add in the temporary list.

In Java 8, stream & filter operations using Lambda expressions helps to get the filtered list in a single statement itself.

Filter a stream of data for a given criteria and perform collect operations to get the collection of objects for the given criteria.

Below is the Java example for the same. There is a list of Person object and filter is applied to get all the persons where age of a person is greated than 18.

package com.pojo;

public class Person {

 private String id;

 private String name;

 private String address;

 private int age;

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 public String getId() {
  return id;
 }

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

 public String getName() {
  return name;
 }

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

 public String getAddress() {
  return address;
 }

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


package com.lambda;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.pojo.Person;

public class FilterListLambda {

 public static void main(String args[]) {

  List<Person> persons = new ArrayList<>();

  Person person = new Person();
  person.setAge(20);
  persons.add(person);

  Person personOne = new Person();
  personOne.setAge(25);
  persons.add(personOne);

  Person personTwo = new Person();
  personTwo.setAge(32);
  persons.add(personTwo);

  Person personThree = new Person();
  personThree.setAge(14);
  persons.add(personThree);

  // Find all persons where age greater than 18 using traditional For Loop

  List<Person> personsAgeGreaterThan18 = new ArrayList<>();

  for (Person tempPerson : persons) {
   if (tempPerson.getAge() > 18) {
    personsAgeGreaterThan18.add(tempPerson);
   }
  }

  // Using Java 8 Lambda & Streams

  personsAgeGreaterThan18 = persons.stream().filter(p -> p.getAge() > 18).collect(Collectors.toList());
 }
}


How to print a list or a collection using Lambda Expression in Java 8

How to print a list or a collection using Lambda Expression in Java 8

In this example, we will learn how to print a list using Lambda expression in Java 8. Traditional methods were using the normal for loop and use the System.out.println method to print the content of a collection.

There are 2 ways to print a list using Lambda expression -
1) Using lambda expression and functional operations
2) Using double colon operator in Java 8

Both these ways reduce the code to a single statement which is more readable and easy to maintain.

Below is the short example to demonstrate both the examples.
package com.lambda;

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

public class ForLoopPrint {

 public static void main(String args[]) {

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

  persons.add("John");
  persons.add("Adam");
  persons.add("Peter");
  persons.add("James");

  System.out.println("Using Old Loop");
  for (String person : persons) {
   System.out.print(person + "; ");
  }
  System.out.println("\n");

  System.out.println("Using lambda expression and functional operations");
  persons.forEach((person) -> System.out.print(person + "; "));

  System.out.println("\n");
  System.out.println("Using double colon operator in Java 8");
  persons.forEach(System.out::println);
 }
}


Here is the output -
Using Old Loop
John; Adam; Peter; James; 

Using lambda expression and functional operations
John; Adam; Peter; James; 

Using double colon operator in Java 8
John
Adam
Peter
James

Spring Rest Template Pass parameters in URL

Spring Rest Template Pass parameters in URL

Spring RestTemplate - org.springframework.web.client.RestTemplate helps in accessing the third party Rest Services. The methods used to get or post the data is similar to what we have learned in the past.

Following are the important methods to get/post/put/delete the data headForHeaders(), getForObject(), postForObject(), put() and delete() etc.

Below example is the rest service that passes the data in the URL and the same is retrieved using the @PathVariable - import org.springframework.web.bind.annotation.PathVariable; annotation as a method argument in rest service.
Below method is the RequestMapping that expects the Path Variable id from the caller.

@RequestMapping(value = "/person/{id}", method = RequestMethod.GET, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> createEmployee(@PathVariable("id") int id) {
 System.out.println("Path Variable Id - " + id);
 return new ResponseEntity<String>("success", HttpStatus.OK);
}


Client Code to call the rest service -
private static void createEmployee() {
 final String uri = "http://localhost:8080/resttemplate/person/10";

 Map<String, String> params = new HashMap<String, String>();
 params.put("id", "1");
 RestTemplate restTemplate = new RestTemplate();
 String result = restTemplate.getForObject(uri, String.class, params);

 System.out.println(result);
}