Spring Security - Pre-Authentication

Using spring security is a scenario where we need to check for users pre-authentication while accessing the application. For example valid user logged-in to ABC application, and inside ABC application there are XYZ services running which require user authentication, but users who access ABC application should not require to authenticate again by XYZ services when they access through ABC application, just need to pre-authenticate by earlier login details. 
Here Spring Security Pre-Authentication plays the role for us. For more details and methods and classes please refer to Spring docs link
Directly lets see simple example to authenticate user based on request param. Here all services and pages are filtered through security chain and only valid users can access like "admin", "dba" and "user".

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/maven-v4_0_0.xsd">
 <modelVersion>4.0.0</modelVersion>
 <groupId>com.app.mvc</groupId>
 <artifactId>springsecuritybyurl</artifactId>
 <packaging>war</packaging>
 <version>1.0-SNAPSHOT</version>
 <name>Spring Security By URL</name>
 <url>http://maven.apache.org</url>
 <properties>
  <spring.version>3.0.5.RELEASE</spring.version>
  <jackson-mapper-asl.version>1.9.9</jackson-mapper-asl.version>
  <jaxb-api.version>2.2.7</jaxb-api.version>
 </properties>
 <dependencies>
  <dependency>
   <groupId>junit</groupId>
   <artifactId>junit</artifactId>
   <version>3.8.1</version>
   <scope>test</scope>
  </dependency>
  <!-- Spring 3 dependencies -->
  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-core</artifactId>
   <version>${spring.version}</version>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-web</artifactId>
   <version>${spring.version}</version>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>org.springframework</groupId>
   <artifactId>spring-webmvc</artifactId>
   <version>${spring.version}</version>
   <scope>compile</scope>
  </dependency>

  <!-- Spring Security -->
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-core</artifactId>
   <version>${spring.version}</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>${spring.version}</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>${spring.version}</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>
  <dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-taglibs</artifactId>
   <version>${spring.version}</version>
   <type>jar</type>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>jstl</artifactId>
   <version>1.2</version>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>taglibs</groupId>
   <artifactId>standard</artifactId>
   <version>1.1.2</version>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>org.codehaus.jackson</groupId>
   <artifactId>jackson-mapper-asl</artifactId>
   <version>${jackson-mapper-asl.version}</version>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>javax.xml.bind</groupId>
   <artifactId>jaxb-api</artifactId>
   <version>${jaxb-api.version}</version>
   <scope>compile</scope>
  </dependency>

  <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.0.1</version>
   <scope>provided</scope>
  </dependency>

 </dependencies>
 <build>
  <finalName>springsecuritybyurl</finalName>
 </build>
</project>


spring-mvc-servlet.xml


<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:security="http://www.springframework.org/schema/security"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.3.xsd">

 <!-- Annotation are configuring the application -->
 <mvc:annotation-driven />

 <!-- Scan this package for all config annotations -->
 <context:component-scan base-package="com.app.controller" />

 <security:http create-session="never" use-expressions="true"
  auto-config="false" entry-point-ref="preAuthenticatedProcessingFilterEntryPoint">
  <security:intercept-url pattern="/jsp/access-denied.jsp"
   access="permitAll()" />
  <security:intercept-url pattern="/accessdenied.do"
   access="permitAll()" />
  <security:intercept-url pattern="/**"
   access="hasRole('ROLE_USER')" />
  <security:custom-filter position="PRE_AUTH_FILTER"
   ref="preAuthFilter" />
  <security:session-management
   session-fixation-protection="none" />
 </security:http>

 <bean id="preAuthFilter" class="com.app.filter.UrlParametersAuthenticationFilter">
  <property name="authenticationManager" ref="appControlAuthenticationManager" />
 </bean>

 <bean id="preAuthenticationProvider"
  class="org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationProvider">
  <property name="preAuthenticatedUserDetailsService" ref="UserDetailsServiceImpl" />
 </bean>


 <security:authentication-manager alias="appControlAuthenticationManager">
  <security:authentication-provider
   ref="preAuthenticationProvider" />
 </security:authentication-manager>


 <bean id="UserDetailsServiceImpl" class="com.app.security.UserDetailsServiceImpl" />

 <bean id="preAuthenticatedProcessingFilterEntryPoint" class="com.app.security.AuthenticationEntryPointDenied" />


 <!-- <bean id="customUserDetailsService" class="com.app.security.CustomUserDetailsService"></bean> 
  <bean id="http403EntryPoint" class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint"></bean> -->

</beans>


web.xml


<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
 <display-name>Spring Security By URL</display-name>
 <context-param>
  <param-name>contextConfigLocation</param-name>
  <param-value>
   /WEB-INF/spring-mvc-servlet.xml
  </param-value>
 </context-param>

 <filter>
  <filter-name>springSecurityFilterChain</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>springSecurityFilterChain</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

 <listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>

 <listener>
  <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
 </listener>

 <servlet>
  <servlet-name>accessTest</servlet-name>
  <jsp-file>/WEB-INF/jsp/access-denied.jsp</jsp-file>
 </servlet>

 <servlet>
  <servlet-name>spring-mvc</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <load-on-startup>1</load-on-startup>
 </servlet>


 <servlet-mapping>
  <servlet-name>accessTest</servlet-name>
  <url-pattern>/accessdenied.do</url-pattern>
 </servlet-mapping>

 <servlet-mapping>
  <servlet-name>spring-mvc</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>





</web-app>


access-denied.jsp


<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jstl/xml" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jstl/sql" %>

<html>
 <head>
  <title>Invalid user</title>
 </head>
 <body>
  <h1>Oops, Access denied....</h1> 
 </body>
</html>


UrlParametersAuthenticationFilter.java


package com.app.filter;

import javax.servlet.http.HttpServletRequest;

import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

public class UrlParametersAuthenticationFilter  extends AbstractPreAuthenticatedProcessingFilter {

 @Override
 protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
  
  //Checking for no. of URL params
  if (request.getParameterMap().size() == 1) {
         return true;
     }
     return false;
 }

 @Override
 protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
  
  String[] credentials = new String[1];
     
  //Getting authentication credentials
  credentials[0] = request.getParameter("param1");
     
     return credentials;
 }

}


AuthenticationEntryPointDenied.java


package com.app.security;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy;

public class AuthenticationEntryPointDenied implements AuthenticationEntryPoint {

 public void commence(HttpServletRequest request,
   HttpServletResponse response, AuthenticationException authException)
   throws IOException, ServletException {
  
  // Redirecting service to access denied page for invalid users
  RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
  redirectStrategy.sendRedirect(request, response, "/accessdenied.do");
  
 }

}


UserDetailsServiceImpl.java


package com.app.security;

import java.util.ArrayList;
import java.util.Collection;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.AuthenticationUserDetailsService;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

public class UserDetailsServiceImpl implements AuthenticationUserDetailsService {

 public UserDetails loadUserDetails(Authentication token)
   throws UsernameNotFoundException {
  UserDetails userDetails = null;

  String[] credentials = (String[]) token.getCredentials();
  boolean principal = Boolean.valueOf(token.getPrincipal().toString());

  if (credentials != null && principal == true) {
   String name = credentials[0];

   // Setting user Authorities
   if ("admin".equalsIgnoreCase(name)) {
    userDetails = getAdminUser(name);
   } else if ("dba".equalsIgnoreCase(name)) {
    userDetails = getDBAUser(name);
   } else if ("user".equalsIgnoreCase(name)) {
    userDetails = getUserUser(name);
   }
  }

  if (userDetails == null) {
   throw new UsernameNotFoundException("Invalid user - "
     + credentials[0]);
  }

  return userDetails;
 }

 private UserDetails getAdminUser(String username) {
  Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
  grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
  grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_DBA"));
  grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_ADMIN"));
  return new User(username, "notused", true, true, true, true,
    grantedAuthorities);
 }

 private UserDetails getDBAUser(String username) {
  Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
  grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
  grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_DBA"));
  return new User(username, "notused", true, true, true, true,
    grantedAuthorities);
 }

 private UserDetails getUserUser(String username) {
  Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();
  grantedAuthorities.add(new GrantedAuthorityImpl("ROLE_USER"));
  return new User(username, "notused", true, true, true, true,
    grantedAuthorities);
 }
}


Employee.java


package com.app.model;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="employee")
@XmlAccessorType(XmlAccessType.NONE)
public class Employee {
 
 @XmlElement(name="firstName")
 private String firstName;
 
 @XmlElement(name="lastName")
 private String lastName;
 
 @XmlElement(name="role")
 private String role;
 
 public String getFirstName() {
  return firstName;
 }
 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }
 public String getLastName() {
  return lastName;
 }
 public void setLastName(String lastName) {
  this.lastName = lastName;
 }
 public String getRole() {
  return role;
 }
 public void setRole(String role) {
  this.role = role;
 }
}


Employees.java


package com.app.model;

import java.util.Collection;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;


@XmlRootElement(name="employees")
@XmlAccessorType(XmlAccessType.NONE)
public class Employees 
{
 @XmlElement(name="employee")
 private Collection<Employee> employees;

 public Collection<Employee> getUsers() {
  return employees;
 }

 public void setUsers(Collection<Employee> employees) {
  this.employees = employees;
 }
}


DemoController.java


package com.app.controller;

import java.util.ArrayList;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.app.model.Employee;
import com.app.model.Employees;

@Controller
@RequestMapping("/employees")
public class DemoController 
{
 @RequestMapping(method = RequestMethod.GET,  headers="Accept=application/xml")
 public @ResponseBody Employees getEmployees() 
 {
  
  String userRole = getUserRole();
  
  System.out.println("User Role : "+userRole);
        
  Employee emp1 = new Employee();
  Employee emp2 = new Employee();
  
  if(userRole.equals("admin")){
  
   emp1.setFirstName("Bala");
   emp1.setLastName("Raj");
   emp1.setRole("ADMIN");
   emp2.setFirstName("Tim");
   emp2.setLastName("Rock");
   emp2.setRole("ADMIN");
  
  }else if(userRole.equals("dba")){
   
   emp1.setFirstName("Steve");
   emp1.setLastName("Jose");
   emp1.setRole("DBA");
   emp2.setFirstName("Bill");
   emp2.setLastName("Fish");
   emp2.setRole("DBA");
   
  }else if(userRole.equals("user")){
   
   emp1.setFirstName("Joy");
   emp1.setLastName("Tiger");
   emp1.setRole("USER");
   emp2.setFirstName("Wood");
   emp2.setLastName("Rich");
   emp2.setRole("USER");
   
  } 
  
  Employees emps = new Employees();
  emps.setUsers(new ArrayList<Employee>());
  emps.getUsers().add(emp1);
  emps.getUsers().add(emp2);
  
  return emps;
 }
 
 private String getUserRole(){
  
  String userRole = "";
  
  SecurityContext context = SecurityContextHolder.getContext();
        Authentication authentication = context.getAuthentication();
        
        for (GrantedAuthority auth : authentication.getAuthorities()) {
            if ("ROLE_ADMIN".equals(auth.getAuthority())){
                userRole = "admin";
                break;
            }
            if ("ROLE_DBA".equals(auth.getAuthority())){
                userRole = "dba";
                break;
            }
            if ("ROLE_USER".equals(auth.getAuthority())){
                userRole = "user";
                break;
            }
        }
        
        return userRole;
 }
}



OUTPUT:

URL : http://localhost:8080/springsecuritybyurl/employees?param1=bill


Invalid User


URL : http://localhost:8080/springsecuritybyurl/employees?param1=admin


Admin



Download complete sample project from below link.

Spring Security - Pre-Authentication.

Java ExecutorService

We have seen Java Timer Class in our earlier tutorial to. ExecutorService will be better option than using Timer since configured with any number of threads but Timer has only one execution thread.
Another important point to ExecutorService is, if any run-time exception occurred inside TimerTask then current task will be canceled and rest will be continued in ExecutorService. Where as in Timer kill the Thread and following scheduled tasks won’t run further.
Lets see simple example's of how to run a repeated task at a specified interval using ExecutorService.
Java ExecutorService


Single Threaded:


public class JavaExecutorService {

 public static void main(String[] args) throws InterruptedException {
  
  TimerTask repeatedTask = new TimerTask() {
         public void run() {
             System.out.println("OUTPUT : " + Thread.currentThread().getName()  + " : Random Number : "+new Random().nextInt(1000));
         }
     };
     ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
     long delay  = 1000L;
     long period = 1000L;
     executor.scheduleAtFixedRate(repeatedTask, delay, period, TimeUnit.MILLISECONDS);
 }
}


OUTPUT:


OUTPUT : pool-1-thread-1 : Random Number : 608
OUTPUT : pool-1-thread-1 : Random Number : 62
OUTPUT : pool-1-thread-1 : Random Number : 161
OUTPUT : pool-1-thread-1 : Random Number : 141
OUTPUT : pool-1-thread-1 : Random Number : 954
OUTPUT : pool-1-thread-1 : Random Number : 565
OUTPUT : pool-1-thread-1 : Random Number : 839
.
.
.




By Setting Thread-pool Size:


public class JavaExecutorService {

 public static void main(String[] args) throws InterruptedException {
  
  TimerTask repeatedTask = new TimerTask() {
         public void run() {
             System.out.println("OUTPUT : " + Thread.currentThread().getName()  + " : Random Number : "+new Random().nextInt(1000));
         }
     };

     //Setting threadpool size to 5
     ScheduledExecutorService executor = Executors.newScheduledThreadPool(5);
     long delay  = 1000L;
     long period = 1000L;
     executor.scheduleAtFixedRate(repeatedTask, delay, period, TimeUnit.MILLISECONDS);
 }
}


OUTPUT:


OUTPUT : pool-1-thread-1 : Random Number : 562
OUTPUT : pool-1-thread-1 : Random Number : 207
OUTPUT : pool-1-thread-2 : Random Number : 912
OUTPUT : pool-1-thread-1 : Random Number : 165
OUTPUT : pool-1-thread-3 : Random Number : 676
OUTPUT : pool-1-thread-2 : Random Number : 956
OUTPUT : pool-1-thread-2 : Random Number : 987
OUTPUT : pool-1-thread-2 : Random Number : 866
OUTPUT : pool-1-thread-2 : Random Number : 331
OUTPUT : pool-1-thread-3 : Random Number : 183
OUTPUT : pool-1-thread-3 : Random Number : 669
OUTPUT : pool-1-thread-3 : Random Number : 617
OUTPUT : pool-1-thread-3 : Random Number : 719
OUTPUT : pool-1-thread-3 : Random Number : 757
OUTPUT : pool-1-thread-3 : Random Number : 728
OUTPUT : pool-1-thread-3 : Random Number : 77
OUTPUT : pool-1-thread-5 : Random Number : 66
OUTPUT : pool-1-thread-2 : Random Number : 64
OUTPUT : pool-1-thread-4 : Random Number : 643
.
.
.




Java Timer

Timer and TimerTask classes are important java util class used to schedule tasks in a background thread. On other way TimerTask is a task performer and Timer is a scheduler to set the time to run the task. By using these classes we can schedule the task to run at a specified time once or we can set repeated task at an interval. Lets see simple Java example for both by scheduling task once and repeated task at an interval.
Java Timer


Scheduling Task Once:


import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class JavaTimer {

 public static void main(String[] args) {
  
  TimerTask task = new TimerTask() {
         public void run() {
             Random rand = new Random();
             System.out.println(Thread.currentThread().getName() + rand.nextInt(1000));
         }
     };
     
     Timer timer = new Timer("Generate Random Number : ");
      
     long delay = 500L;
     timer.schedule(task, delay);
 }
}


OUTPUT:


Generate Random Number : 237





Repeated Task at Interval:


import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class JavaTimer {

 public static void main(String[] args) {
  
  TimerTask task = new TimerTask() {
         public void run() {
             Random rand = new Random();
             System.out.println(Thread.currentThread().getName() + rand.nextInt(1000));
         }
     };
     
     Timer timer = new Timer("Generate Random Number : ");
      
     long delay = 500L;
     long period = 1000L;
     timer.scheduleAtFixedRate(task, delay, period);;
 }
}


OUTPUT:


Generate Random Number : 519
Generate Random Number : 973
Generate Random Number : 859
Generate Random Number : 942
Generate Random Number : 578
Generate Random Number : 764
Generate Random Number : 256
Generate Random Number : 802
Generate Random Number : 926
Generate Random Number : 69
Generate Random Number : 875
.
.
.

Removing null elements from List in Java

In this tutorial lets see how to remove null elements from the given list by using java Collections. Basic we could think iterating through List and to delete all null elements. But by using Collections class it makes easy to remove all null elements. Lets see simple example to delete null elements from list.
Removing null elements from List in Java


public static void main(String[] args) {
 
 final List<Integer> list = new ArrayList<Integer>();
 Collections.addAll(list, 1,2,null,3,4,null,5,6,null,7,8,null,9);
 
 System.out.println("LIST SIZE : "+list.size()+ " - " + list);
 
 list.removeAll(Collections.singleton(null));
 
 System.out.println("LIST SIZE : "+list.size()+ " - " + list);
}



OUTPUT:


LIST SIZE : 13 - [1, 2, null, 3, 4, null, 5, 6, null, 7, 8, null, 9]
LIST SIZE : 9 - [1, 2, 3, 4, 5, 6, 7, 8, 9]


Create user defined substring functions

 
In many interviews we may asked to substring() a string without using substring function from String class. Below are the simple code how we can write our own substring functions similar to String class functions.


public class MyStringOp {

 public static void main(String[] args) {
  
  String str = "Java Discover";
  
  MyStringOp obj = new MyStringOp();
  
  System.out.println(obj.mySubstring(str, 5));
  
  System.out.println(obj.mySubstring(str, 0,4));
 }
 
 public String mySubstring(String str, int start){
  
  if(start > str.length()) 
   throw new StringIndexOutOfBoundsException(); 
  
  String newStr = "";
  char[] ch = str.toCharArray();
  
  for(int i=start;i<str.length();i++){
   newStr = newStr + ch[i];
  }
  return newStr;
 }
 
 public String mySubstring(String str, int start, int end){
  
  if((start > end) || (start > str.length()) || (end > str.length())) 
   throw new StringIndexOutOfBoundsException(); 
  
  String newStr = "";
  char[] ch = str.toCharArray();
  
  for(int i=start;(i<str.length() && i<end);i++){
   newStr = newStr + ch[i];
  }
  return newStr;
 }
}




OUTPUT:


Discover
Java


Simple Factory Design Pattern class

Lets design simple Factory Design Pattern example with code, like how to design a Factory class and how to get objects from factory. 

Consider the scenario that showroom needs application to access their various Car details through online. Like Car1 runs on Petrol and gives mileage upto 28 KM/L and Car2 runs on Diesel and gives mileage upto 24 KM/L. 
Lets create simple Factory Class to create car objects based on parameter information's.

AANND



public interface Car {
 public String getCallDetails();
}



public class Alto implements Car{

 public String getCallDetails() {
  return "Alto runs on Petrol and gives mileage upto 18 KM/L";
 }
}



public class Swift implements Car{

 public String getCallDetails() {
  return "Swift runs on Diesel and gives mileage upto 24 KM/L";
 }
}



public class CarFactory {

 public static Car getCar(String carName){
  
  Car car = null;
  
  if(carName.equalsIgnoreCase("alto")){
   car = new Alto();
  
  }else if(carName.equalsIgnoreCase("swift")){
   car = new Swift();    
  }
  
  return car;
 }
}



public class ShowRoomApplication {

 public static void main(String[] args) {
  
  Car car1 = CarFactory.getCar("alto");
  String details = car1.getCallDetails();
  System.out.println(details);
  
  Car car2 = CarFactory.getCar("swift");
  details = car2.getCallDetails();
  System.out.println(details);
  
  
 }
}



Output:


Alto runs on Petrol and gives mileage upto 28 KM/L
Swift runs on Diesel and gives mileage upto 24 KM/L

Java Thread Local with simple example

 

Java ThreadLocal is an interesting and important Class in Java where most the developers unaware of it. Lets see what is Java ThreadLocal by its importance and how to use it with simple sample code.
Java Thread Local with simple example


What is Java ThreadLocal?
Java ThreadLocal gives the scope of an Object which stored in the ThreadLocal. We can set any Object in the Thread Local which inturns to be global access for the Thread from anywhere. 
Only thing which we need to keep in mind that to maintain a separate instance copy for each thread, so that Object conflict won't occur between multiple threads.
Values stored in ThreadLocal are local to each threads, i.e., each thread will have it's own ThreadLocal Objects where one thread can not access/modify other thread's Thread Local Objects unless it satisfies preview statement. 

Where to use Java ThreadLocal?
Lets a take situation that we need to use some global value for each thread which can be access across and anywhere the Thread is been called (For example in any methods). In those cases we can value or Object in ThreadLocal and same value or Object can be accessed anywhere in particular Thread call. 

There are 4 methods in ThreadLocal class and they are

  • initialValue() - Returns the current thread's "initial value" for this thread-local variable.
  • get() - Returns the value in the current thread's copy of this thread-local variable.
  • set() - Sets the current thread's copy of this thread-local variable to the specified value.
  • remove() - Removes the current thread's value for this thread-local variable.

Lets see simple example how to use ThreadLocal in Java.


public class MyLocalThreadHolder{
 
 private static final ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();

 public static void set(String val) {
  myThreadLocal.set(val);
 }
 
 public static void delete() {
  myThreadLocal.remove();
 }
 
 public static String get() {
 return myThreadLocal.get();
 }
}



public class TestThreadLocal extends Thread{

 public TestThreadLocal(String tName) {
  this.setName(tName);
 }
 
 public static void main(String[] args) {
 
  TestThreadLocal t1 = new TestThreadLocal("First thread...");
  TestThreadLocal t2 = new TestThreadLocal("Second thread...");
  TestThreadLocal t3 = new TestThreadLocal("Third thread...");
  
  t1.start();
  t2.start();
  t3.start();
 }
 
 @Override
 public void run() {
  //Setting thread name in ThreadLocal
  MyLocalThreadHolder.set(currentThread().getName());
  new PrintLocalThread().printThreadName(); 
 }
}



public class PrintLocalThread {
  
 public void printThreadName(){
  //Getting thread name from ThreadLocal and printing
  String currentThreadName = MyLocalThreadHolder.get();
  System.out.println("Before ----> : "+currentThreadName);
  
  //Removing value set in ThreadLocal
  MyLocalThreadHolder.delete();
  
  currentThreadName = MyLocalThreadHolder.get();
  System.out.println("After ----> : "+currentThreadName);
 }  
}


OUTPUT:


Before ----> : Second thread...
After ----> : null
Before ----> : First thread...
After ----> : null
Before ----> : Third thread...
After ----> : null