Java @ Desk | Java at your desk

Sorting a List using Lambda Expression in Java 8

Sorting a List using Lambda Expression in Java 8

In this post, we will learn how to sort a list using Lambda Expression in Java 8. In Java 6 or 7, Java pojo object must implements Comparator interface or Comparable interface to sort a collection of objects. The implementation need to be provided in compareTo method to sort a list based on particular property of a class.

In Java 8, the code has been reduced to just a single line. One can use the below 3 implementations:
1) sort method of List interface
2) sort method of Collections class
3) sort using stream() method of List interface

In 3rd strategy, the underlying list does not get sorted. So, either you must create a new object and assign the sorted list or assign the sorted list to the existing list object.
In both the implementations, the sorting logic goes as a Lambda expression.

Consider a Person class below in which sorting logic needs to be implemented on name of the person.
package com.pojo;

public class Person {

 private String id;

 private String name;

 private String address;

 public Person(String id, String name, String address) {
  super();
  this.id = id;
  this.name = name;
  this.address = address;
 }

 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;
 }

 @Override
 public String toString() {
  return this.id + ", " + this.name + ", " + this.address;
 }
}
Below one is the traditional sorting technique
Collections.sort(persons, new Comparator<Person>() {
   public int compare(Person p1, Person p2) {
    return p1.getName().compareTo(p2.getName());
   }
  });



Here is the implementation using Java 8 using Lambda expression
Collections.sort(persons, (p1, p2) -> p1.getName().compareTo(p2.getName()));

Collections.sort(persons, (Person p1, Person p2) -> p1.getName().compareTo(p2.getName()));

persons.sort((p1, p2) -> p1.getName().compareTo(p2.getName()));

// Here, specifically the sorted list need to be assigned to a new list
// or existing list object.  
persons = persons.stream().sorted((p, p2) -> (p.getName().compareTo(p2.getName())))
 .collect(Collectors.toList());


Finally print the list using lambda expression
persons.forEach((person) -> System.out.print(person + "\n"));


Output
IdOne, Andy, Netherland
IdThree, Chris, London
IdTwo, John, Australia
IdFour, Nathan, Paris
IdFive, Peter, Brazil


Spring Boot Messaging Queue RabbitMQ using AMQP

Spring Boot RabbitMQ using AMQP

Below example configures the messaging queue between the sender and the listener. In the example, the scheduler sends the message to the queue every 3 seconds which will be pulled by the Listener class.

The implementation is in the Spring Boot.

AMQP is a protocol that defines communication between systems.

Project Setup
1) pom.xml - Defines the entry for Spring Boot AMPQ library
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-amqp</artifactId>
 <version>1.5.4.RELEASE</version>
</dependency>


2) Sender.java - This class uses a scheduler implementation that pushes the message into the queue every 3 seconds. RabbitTemplate class helps sending the message to the Listener. It pushes the message into the queue.
package com.accenture.springmessage;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

@Service
public class Sender {

 @Autowired
 private final RabbitTemplate rabbitTemplate;

 @Autowired
 public StoryEnsRequestSender(final RabbitTemplate rabbitTemplate) {
  this.rabbitTemplate = rabbitTemplate;
 }

 @Scheduled(fixedDelay = 3000L)
 public void sendMessage() {
  String message = "Hello";
  System.out.println("Send Message - " + message);
  rabbitTemplate.convertAndSend(App.EXCHANGE_NAME, App.ROUTING_KEY, message);
 }
}


3) Listener.java - This class uses the @RabbitListener annotation that fetches the message from the queue. The queue is identified using the queue names attribute.
package com.accenture.springmessage;

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;

@Service
public class Listener {

 @RabbitListener(queues = App.QUEUE_SPECIFIC_NAME)
 public void receiveMessage(final String customMessage) {
  System.out.println("Received message - " + customMessage.toString());
 }
}


4) App.java - Configuration class to define the queue name, exchange name and routing key. Class must implement RabbitListenerConfigurer and below annotations are used @SpringBootApplication, @EnableScheduling, @EnableRabbit.
Enable Rabbit annnotation is used to enable the rabbit configuration.
Enable Scheduling pushes the message in the queue every 3 seconds.


package com.accenture.springmessage;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerEndpointRegistrar;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;
import org.springframework.scheduling.annotation.EnableScheduling;

/**
 * Hello world!
 *
 */
@SpringBootApplication
@EnableScheduling
@EnableRabbit
public class App implements RabbitListenerConfigurer {
 public static void main(String[] args) throws InterruptedException {
  SpringApplication.run(App.class, args);
 }

 public static final String EXCHANGE_NAME = "appExchange";
 public static final String QUEUE_SPECIFIC_NAME = "appSpecificQueue";
 public static final String ROUTING_KEY = "messages.key";

 @Bean
 public TopicExchange appExchange() {
  return new TopicExchange(EXCHANGE_NAME);
 }

 @Bean
 public Queue appQueueSpecific() {
  return new Queue(QUEUE_SPECIFIC_NAME);
 }

 @Bean
 public Binding declareBindingSpecific() {
  return BindingBuilder.bind(appQueueSpecific()).to(appExchange()).with(ROUTING_KEY);
 }

 @Bean
 public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {
  final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
  rabbitTemplate.setMessageConverter(producerJackson2MessageConverter());
  return rabbitTemplate;
 }

 @Bean
 public Jackson2JsonMessageConverter producerJackson2MessageConverter() {
  return new Jackson2JsonMessageConverter();
 }

 @Bean
 public MappingJackson2MessageConverter consumerJackson2MessageConverter() {
  return new MappingJackson2MessageConverter();
 }

 @Bean
 public DefaultMessageHandlerMethodFactory messageHandlerMethodFactory() {
  DefaultMessageHandlerMethodFactory factory = new DefaultMessageHandlerMethodFactory();
  factory.setMessageConverter(consumerJackson2MessageConverter());
  return factory;
 }

 @Override
 public void configureRabbitListeners(final RabbitListenerEndpointRegistrar registrar) {
  registrar.setMessageHandlerMethodFactory(messageHandlerMethodFactory());
 }
}


5) Output

Send Message - Hello at - Tue Jun 27 19:50:22 IST 2017
Received message - Hello at - Tue Jun 27 19:50:22 IST 2017
Send Message - Hello at - Tue Jun 27 19:50:25 IST 2017
Received message - Hello at - Tue Jun 27 19:50:25 IST 2017
Send Message - Hello at - Tue Jun 27 19:50:28 IST 2017
Received message - Hello at - Tue Jun 27 19:50:28 IST 2017
Send Message - Hello at - Tue Jun 27 19:50:31 IST 2017
Received message - Hello at - Tue Jun 27 19:50:31 IST 2017
Send Message - Hello at - Tue Jun 27 19:50:34 IST 2017
Received message - Hello at - Tue Jun 27 19:50:34 IST 2017

Spring Boot with Mongo DB example

Spring Boot with Mongo DB example

This example demonstrates the integration of Mongo DB with Spring Boot. If you are running Mongo DB locally, then there is no need to configure anything for the Mongo database in the spring boot application.

Spring boot auto configures the mongo db configuration since by default mongo runs on
1) host - localhost or 127.0.0.1
2) port - 27017

If you are running a mongo db on local system, then you just have to configure the mongo repository interface in your spring boot application and use @EnableMongoRepositories annotation. Once you run the spring boot application you will notice a following log in your mongo db command prompt
connection accepted from 127.0.0.1:52994 #1 (1 connection now open)

This indicates that the spring boot application is connected to mongo db and you can perform db operations.

And once you stop the application you will observe
end connection 127.0.0.1:52994 (1 connection now open)


In any case there is a need for configuring the change in host or port, then perform following changes in application.properties file
server.port=8070
spring.dao.exceptiontranslation.enabled=false
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017


Here is the maven dependency for spring data for mongo db
<dependency>
 <groupId>org.springframework.data</groupId>
 <artifactId>spring-data-mongodb</artifactId>
 <version>1.10.1.RELEASE</version>
</dependency>


Spring Boot app java class - This class configures the spring controller file plus enables the mongo repository using @EnableMongoRepositories annotation.
package com.springbootservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

import com.repository.AppRepository;

@SpringBootApplication(scanBasePackages = { "com.controller"})
@EnableMongoRepositories(basePackageClasses = AppRepository.class)
public class App {

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




Repository Interface - Mongo comes with the MongoRepository interface that internally performs all the basic db operations like insert, get & delete on its own. You must have to create a repository interface that extends MongoRepository interface along with the type. If you have mongo db data object Person then MongoRepository enables all basic operations on Person object.
package com.repository;

import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;

import com.model.Person;

@Repository()
public interface AppRepository extends MongoRepository<Person, String> {

}


Mongo Model class
package com.model;

import org.springframework.data.annotation.Id;

public class Person {
 @Id
 private String id;

 private String name;

 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;
 }

}


Test Controller - Simply autowire the AppRepository object and start performing DB operations as shown below
@Autowired
private AppRepository appRepository;

@RequestMapping(method = RequestMethod.GET, path = "/test/Mongo", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<String> getTest() {
 String temp = "abc";
 Person person = new Person();
 person.setId("Id");
 person.setName("Kumar");
 appRepository.insert(person);

 Person person2 = appRepository.findOne("Id");
 System.out.println("Person - " + person2);
 System.out.println(person2.getName());
 appRepository.delete("Id");
 System.out.println("Deleted Successfully");
 return new ResponseEntity<String>(temp, HttpStatus.OK);

}

Angular JS routing with Spring 4 MVC using ngRoute

Angular JS routing with Spring 4 MVC using ngRoute

This example demonstrates how routing works in angular js using ngRoute, $routeProvider.

Following components are used:
1) Spring 4.3.0.RELEASE
2) Angular JS 1.4.4
3) Angular JS Route 1.4.4

Configuring Routes
Routes in angular js are configured in the config function using the $routeProvider service. In the example, we will configure 2 routes, 1st to load the list of Persons and 2nd to load list of Customers.
1) templateUrl - This triggers the Spring's controller to decide which html page to navigate to
2) controller - This triggers the angular js controller
3) resolve - This triggers the angular js service

app.js
'use strict';

var indexApp = angular.module('indexApp', [ 'ngRoute' ]);

indexApp.config([ '$routeProvider', function($routeProvider) {
 $routeProvider.when('/loadPersons', {
  templateUrl : 'loadPersons',
  controller : "PersonController as personCtrl",
  resolve : {
   async : [ 'PersonService', function(PersonService) {
    return PersonService.fetchPersons();
   } ]
  }
 }).when('/loadCustomers', {
  templateUrl : 'loadCustomers',
  controller : "CustomerController as custCtrl",
  resolve : {
   async : [ 'CustomerService', function(CustomerService) {
    return CustomerService.fetchCustomers();
   } ]
  }
 });
} ]);


Service JS
Angular JS service file will communicate with the Spring controller where the services are configured. The call to spring is done using the $http.

appService.js
'use strict';

indexApp.factory('CustomerService', [ '$http', '$q', function($http, $q) {
 return {
  fetchCustomers : function() {
   return $http.get('customers').then(function(response) {
    return response.data;
   }, function(errResponse) {
    console.error('Error while fetching Items');
    return $q.reject(errResponse);
   });
  }
 };
} ]);

indexApp.factory('PersonService', [ '$http', '$q', function($http, $q) {
 return {
  fetchPersons : function() {
   return $http.get('persons').then(function(response) {
    return response.data;
   }, function(errResponse) {
    console.error('Error while fetching Items');
    return $q.reject(errResponse);
   });
  }
 };
} ]);


Controller Js
Angular JS controller file sets the response of service to the UI scope variables defined in JSP page.

appController.js
'use strict';

indexApp.controller('CustomerController', [ 'async', function(async) {
 var self = this;
 self.customers = async;
} ]);

indexApp.controller('PersonController', [ 'async', function(async) {
 var self = this;
 self.persons = async;
} ]);


Welcome Page
This page configures the indexApp ng app and displays the content using the ng-view directive.



index.jsp - In below JSP, when user clicks on "Get Persons List" hyperlink, it calls the config of app.js and check with the $routeProvider for the matching URL. It finds the "/loadPersons" and it hits the "templateUrl : 'loadPersons'" that goes to MainController.java to define the HTML page to navigate to. In MainController.java, it finds "persons" and so navigates to persons.jsp as shown below and displays the content on ng-view.

<!DOCTYPE html>
<html ng-app="indexApp">
<head>
<title>Person App</title>
<script src="resources/js/angular.js"></script>
<script src="resources/js/angular-route.js"></script>
<script src="resources/js/app.js"></script>
<script src="resources/js/appService.js"></script>
<script src="resources/js/jquery.min.js"></script>
</head>

<body>
 Home Screen
 <li><a href="#/loadPersons">Get Persons List</a></li>
 <li><a href="#/loadCustomers">Get Customers List</a></li>
 <div ng-view></div>
 <script src="resources/js/appController.js"></script>
</body>
</html>


persons.jsp
<!DOCTYPE html>
<html ng-app="personApp">
<head>
<title>Person App</title>
<script src="resources/js/angular.js"></script>
<script src="resources/js/angular-route.js"></script>
<script src="resources/js/app.js"></script>
<script src="resources/js/personService.js"></script>
<script src="resources/js/jquery.min.js"></script>
</head>

<body>
 Persons Data -
 <div ng-repeat="person in personCtrl.persons">
  Person Name - {{person.name}} <br> Person Id - {{person.id}}
 </div>
 <li><a href="#/back">Back</a></li>
 <script src="resources/js/personController.js"></script>
</body>
</html>


customers.jsp
<!DOCTYPE html>
<html ng-app="customerApp">
<head>
<title>Person App</title>
<script src="resources/js/angular.js"></script>
<script src="resources/js/angular-route.js"></script>
<script src="resources/js/appRoute.js"></script>
<script src="resources/js/customerService.js"></script>
<script src="resources/js/jquery.min.js"></script>
</head>

<body>
 Customers Data -
 <div ng-repeat="customer in custCtrl.customers">
  Customer Name - {{customer.name}} <br> Customer Id -
  {{customer.id}}
 </div>
 <li><a href="#/back">Back</a></li>
 <script src="resources/js/customerController.js"></script>
</body>
</html>

angular js $http rest controller status code 0

angular js $http rest controller status code 0

Angular JS $hhtp returns the status code 0 on calling the get request from the spring rest controller. The rest controller in the example below produces "application/json".

The response come fine if the URL is tested in the browser. It successfully prints the response on the chrome browser, but the same request returns the status code 0 if called from angular js $http. Below is the sample request and spring rest controller for the same.

angularController.js
var app = angular.module('customerApp', []);
app.controller("customerController", function($scope, $http) {
 $http.get('http://localhost:8060/customers').then(
   function successCallback(response) {
          $scope.customer = {name: response.data.name, id: response.data.id};
   }, function errorCallback(response) {
   });
});


CustomerController.java
package com.accenture.restviability.controller;

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

import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.acc.auto.service.request.Customer;

@RestController()
public class CustomerController {

 @RequestMapping(method = RequestMethod.GET, path = "/customers", produces = MediaType.APPLICATION_JSON_VALUE)
 public ResponseEntity<Customer> getCustomers() {
  System.out.println("Entered in Get Customers");
  List<Customer> customers = new ArrayList<Customer>();
  Customer customer = new Customer();
  customer.setName("Kumar");
  customer.setId("1");
  return new ResponseEntity<Customer>(customer, HttpStatus.OK);
 }
}


The above angular method returns the status code 0 on calling the spring rest controller. The issue occure because of HTTP Access Control CORS issues.

Angular does not consume the response from the server that does not include Access-Control-Allow-Origin header in the response. The server responding back the angular JS calls must include the headers specified by CORS. In order to make it work, you need to include the below annotation of Spring.

@CrossOrigin(maxAge = 3600) from import org.springframework.web.bind.annotation.CrossOrigin;
package of Spring

Spring 4 Annotation Configuration without web.xml file using WebApplicationInitializer

Spring 4 Annotation Configuration without web.xml file using WebApplicationInitializer

Spring 4 allows annotation based configuration to initialize the web application without having the web.xml as well as spring configuration xml file. The spring controller and services are loaded using the annotation @ComponentScan.

With servlet 3.x there is no need of the spring configuration file defined in web.xml. Servlet 3.x allows annotation based loading of configuration classes for controllers and services.

Below example will load the controllers and services classes on server start up i.e. there will be a class to replace web.xml to map the Spring Dispatcher Servlet and load it on server start up. Rest controller example is implemented here that returns the JSON response to the caller.

pom.xml - Add Spring 4.x release and Servlet 3.x release to support annotation based loading of Dispatcher Servlet
<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>Blogger</groupId>
 <artifactId>Blogger</artifactId>
 <version>0.0.1-SNAPSHOT</version>
 <packaging>war</packaging>
 <build>
  <finalName>blogger</finalName>
  <sourceDirectory>src</sourceDirectory>
  <plugins>
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.5.1</version>
    <configuration>
     <source>1.8</source>
     <target>1.8</target>
    </configuration>
   </plugin>
   <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
     <warSourceDirectory>WebContent</warSourceDirectory>
    </configuration>
   </plugin>
  </plugins>
 </build>
 <dependencies>
  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</version>
  </dependency>
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>4.3.1.RELEASE</version>
  </dependency>
  <dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.7.5</version>
  </dependency>
 </dependencies>
</project>


AppConfig.java - This class bootstrap Spring 4 MVC Rest in our application on server startup
package com.rest.spring4.annotationconfiguration.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.rest.spring4.annotationconfiguration")
public class AppConfig {

}


AppInitializer.java - This class is loaded by Servlet 3.x. This class will replace web.xml and it will map the spring’s dispatcher servlet and bootstrap it.
package com.rest.spring4.annotationconfiguration.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
 @Override
 protected Class[] getRootConfigClasses() {
  return new Class[] { AppConfig.class };
 }

 @Override
 protected Class[] getServletConfigClasses() {
  return null;
 }

 @Override
 protected String[] getServletMappings() {
  return new String[] { "/" };
 }
}




Person.java - Domain object for JSON response
package com.rest.spring4.annotationconfiguration.pojo;

public class Person {

 private String id;

 private String name;

 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;
 }
}


PersonRestController.java - This class contains the Rest mapping to load the list of person objects in JSON format
package com.rest.spring4.annotationconfiguration.restcontroller;

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

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.rest.spring4.annotationconfiguration.pojo.Person;

@RestController
public class PersonRestController {

 @GetMapping("/persons")
 public ResponseEntity getPersons() {
  List<Person> persons = new ArrayList<Person>();

  Person person = new Person();
  person.setId("Id 1");
  person.setName("Person Name 1");

  persons.add(person);

  Person person2 = new Person();
  person2.setId("Id 2");
  person2.setName("Person Name 2");

  persons.add(person2);

  return new ResponseEntity(persons, HttpStatus.OK);
 }
}


Output:
[{"id":"Id 1","name":"Person Name 1"},{"id":"Id 2","name":"Person Name 2"}]