Saturday, 24 June 2017

How to reduce build time in Android Studio for Android Applications

Navigate to File  ==>  Settings ==> Build, Exceution, Deployment ==> Gradle ==> Select Offline Work check box on the right side of the pane under Global Gradle Settings

Sunday, 30 April 2017

How to resolve Spring Boot web application error "Whitelabel Error Page This application has no explicit mapping for /error, so you are seeing this as a fallback."

If you come across  any such error as like below

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.
.........
There was an unexpected error (type=Not Found, status=404).
No message available

then one possible problem would be that the below class wouldn't had been created

For HTML pages use the below class

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
public class ApplicationWebMvcConfig extends WebMvcConfigurerAdapter{

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
   
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/html/");
        resolver.setSuffix(".html");
        return resolver;
    }
}

For JSP pages use the below class

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
@EnableWebMvc
public class ApplicationWebMvcConfig extends WebMvcConfigurerAdapter{

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
    
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/jsp/");
        resolver.setSuffix(".jsp");
        return resolver;
    }
}

Monday, 17 April 2017

How to implement Localization in Spring application

Details given below includes Thymeleaf integration but you can use the framework that applies to  your application.
Following are certain requirements that are needed
Ø  Spring
Ø  Properties Files
Examples:
messages_en.properties - English
wellcome.world = Hello World !
 
                   fileName should have undrescore '_' and place it on classpath. Supported formats and codes can be found in : http://www.oracle.com/technetwork/java/javase/javase7locales-334809.html

Spring Configuration
Ø  SessionLocaleResolver
Register a "SessionLocaleResolver" bean, name it exactly the same characters "localeResolver". It resolves the locales by getting the predefined attribute from user's session.
Ø  LocaleChangeInterceptor
Register a "LocaleChangeInterceptor" interceptor and refer it to any handler mapping that need to support multiple languages. The "paramName" is the parameter value that's used to set the locale.

In dispatcher-servlet.xml add the below ones.
<bean id="localeResolver"
 class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
                             <property name="defaultLocale" value="en" />
</bean>
//paramName - name of the url parameter to hold the locale variable
<bean id="localeChangeInterceptor"
 class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
 <property name="paramName" value="language" />
</bean>
<mvc:interceptors>
          <mvc:interceptor>
                    <mvc:mapping path="/**" />
                   <mvc:exclude-mapping path="/css/**" />
                    <mvc:exclude-mapping path="/js/**" />
                    <mvc:exclude-mapping path="/bootstrap/**" />
                   <mvc:exclude-mapping path="/img/**" />
                   <mvc:exclude-mapping path="/fonts/**" />
                   <bean class="com..sk.tol.base.view.config.UserInterceptor" />
          </mvc:interceptor>
 <ref bean="localeChangeInterceptor"/>
</mvc:interceptors>


This will enable us to change locale simply by passing language parameter in url:
<a href="?language=en">English</a>

Below things needs to be taken care of

LocaleUtils.java
     Just write a utility class which help us to obtain various locale based formats, patterns.
jQuery Datepicker
     Properties Files
jQuery Datepicker has its own objects with language settings, like name of the days, months, etc... which are defined in separate.js files and we need to include corresponding script of every language that we will be using in the application.
<script src="js/jquery.wait.js" th:src="@{/js/locales/bootstrap-datepicker.sk.min.js}"></script>
<script src="js/jquery.wait.js" th:src="@{/js/locales/bootstrap-datepicker.en-GB.min.js}"></script>


LocaleSettings html element
We have to define one invisible element that will hold various locale related information, so we can access it from html, javaScript/jQuery.
 Place it somewhere on top of html hierarchy, so you can access it from every page you need to. In the code below you can see that we are storing the information in html data attributes with the help of Thymeleaf 'th:attr' to call our LocaleUtil java class.
<div id="localeSettings" class="ext-default-hidden"
  th:attr="data-decimal-separator=${@localeUtil.getDecimalSeparator()}, data-thousands-separator=${@localeUtil.getGroupingSeparator()}, data-locale=${#ctx.locale}">
</div>


Initialization and use
When initializing datecipicker, we only need to provide it with locale code, that we can take from our localeSetting element:
var locale = $("#localeSettings").data("locale");
$('.ext-datepicker,#ext-datepicker').datepicker({
 orientation: "bottom auto",
          language: locale
})

The property file  should hold datepicker.date.format  property name and for English language with its message_en.properties file: datepicker.date.format=M d, yyyy

Assigning the format to datepicker element through thymeleaf
<div th:attr="data-date-format=#{datepicker.date.format}" class="ext-datepicker input-append date input-group">
 <input type="datetime" class="span2 form-control ext-readonly-white add-on" th:field="*{createDateFrom}" />
          <div class="input-group-addon add-on">
                    <i class="fa fa-calendar"></i>
 </div>
</div>


jQuery inputmask
Example of Initialization of inputmask for all elements with class "positive-amount-nullable":
var cfgDefaults =
 {
  thousandsSeparator: ",",
           decimalSeparator: "."
 };
function init(){
          var $elm = $("#localeSettings");
          cfgDefaults.decimalSeparator = $elm.data("decimal-separator");
          cfgDefaults.thousandsSeparator = $elm.data("thousands-separator");
};
$(".positive-amount-nullable").off("inputmask").inputmask("currency",
 {
           removeMaskOnSubmit: true,
           placeholder: " ",
          prefix: "",
          allowPlus: false,
          allowMinus: false,
          groupSeparator: cfgDefaults.thousandsSeparator,
          radixPoint: cfgDefaults.decimalSeparator
 }
);


Now we only need to assign css class "positive-amount-nullable" to input we want to get formatted. Example:
  <input type="text" class="form-control positive-amount-nullable" th:field="*{transactionAmount}" />


Serialization / Deserialization in dto's date fields
To enable spring automatic serialization/deserialization just annotate the Date fields as follows. You can use provided custom (de)serializers.
 You can also make your own (de)serializers by extending one of AJsonLocaleDateSerializer.java or AJsonLocaleDateDeserializer.java
 See java.text.DateFormat for more info on the formats used.
@DateTimeFormat(style = "M-")
@JsonSerialize(using = JsonLocaleDateSerializer.class)
@JsonDeserialize(using = JsonLocaleDateDeserializer.class)
private Date transactionDate;

@DateTimeFormat(pattern = "HH:mm")
@JsonSerialize(using = JsonLocaleTimeSerializer.class)
@JsonDeserialize(using = JsonLocaleTimeDeserializer.class)
private Date transactionTime;

@JsonSerialize(using = JsonLocaleDateTimeSerializer.class)
@JsonDeserialize(using = JsonLocaleDateTimeDeserializer.class)
private Date transactionDateTime;


Examples of getting various info on locales
Here are example of various information we can get on front-end by using thymeleaf
<div class="active" th:text="${#ctx.locale}">Current Locale from context from session</div>
<div class="active" th:text="${#dates.createNow()}">Thymeleaf dates utility - gets current Date</div>
<div class="active" th:text="${@localeUtil.formatDate(#dates.createNow())}">Current date formatted by LocaleUtil.java</div>
<div class="active" th:text="${@localeUtil.getDateFormatPattern()}">Get date pattern from LocaleUtil.java</div>
<div class="active" th:text="${@localeUtil.formatTime(#dates.create(2016,9,5,15,45,30,231))}">Current time formatted by LocaleUtil.java</div>
<div class="active" th:text="${@localeUtil.getTimeFormatPattern()}">Get time pattern from LocaleUtil.java</div>


Get current Locale in spring MVC controller
@RequestMapping(value = { "/method" }, method = RequestMethod.GET)
public String someControllerMethod(ExampleDto dto, HttpSession session, Model m, Locale locale ) {

 // Implementation code ...

 return "someResult";
}


The current Locale can be accessed in java code by following way
Locale locale = org.springframework.context.i18n.LocaleContextHolder.getLocale();

Monday, 10 April 2017

How to retrieve data from database using spring jpa hibernate


1. Create a Specification which would construct a query to pull records from database for a particular jpa entity

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.springframework.data.jpa.domain.Specification;

public class TravelEntitySpecification {
        public static Specification<TravelEntity> filterTravelEntity(final String id,final String empId) {

              return new Specification<TravelEntity>() {
                      @Override
                      public Predicate toPredicate(Root<TravelEntity> root, CriteriaQuery<?> query,                                               CriteriaBuilder builder) {

                             Predicate predicate = builder.conjunction();
                             predicate = builder.and(predicate, builder.equal(root.<PK>get(Constant.STRING_ID).get(Constant.STRING_ID), id));

    predicate = builder.and(predicate, builder.equal(root.<PK>get(Constant.STRING_ID).get(Constant.DEFV201_empId), empId));

    return predicate;

   }

  };

 }

2. Create a  Repository interface as like below for the entity

 import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface TravelEntityRepository  extends JpaRepository<TravelEntity, String>, JpaSpecificationExecutor<TravelEntity>{

}

3. Invoke the repository from the dao as like below

public class TravelDAO{
@Autowired
private TravelEntityRepository travelEntityRepository;

public List<TravelEntity> getTravelList(){
return travelEntityRepository.findAll(TravelEntitySpecification.filterTravelEntity("1","2"));
}

public TravelEntity getTravelData(){
return travelEntityRepository.findOne(TravelEntitySpecification.filterTravelEntity("2","2"));
}

Saturday, 8 April 2017

How to configure Logger in an web application


Below logback-appenders.xml helps to create log file

<included>
  <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%date{ISO8601} %-5p [%t][%c:%L] %m%n</pattern>
    </encoder>
  </appender>
 
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${app.logs}//.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>${app.logs}//.%d{yyyy-MM-dd}.log</fileNamePattern>
      <!-- keep 30 days' worth of history -->
      <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>%date{ISO8601} %-5p [%t][%c:%L] %m%n</pattern>
    </encoder>
  </appender>
</included> 

Below logback-loggers.xml provides way to log spring & hibernate  related content

<included>
 <logger name="org.hibernate" level="WARN" />
 <logger name="org.hibernate.type" level="WARN" />
 <logger name="org.springframework" level="WARN" /> 
 <logger name="org.springframework.web" level="WARN" />   
 <logger name="org.springframework.web.servlet" level="WARN" /> 
 <logger name="org.hibernate.SQL" level="debug"/>
 <logger name="org.hibernate.type" level="trace"/>

 <root level="INFO">
  <appender-ref ref="CONSOLE" />
  <appender-ref ref="FILE" />
 </root>
</included> 

How to write simple Spring MVC or Spring Web Controller

Methods provided in the below class are some ways of mapping appropriate request to appropriate urls

@Controller
public class Controller {


 @RequestMapping(value = { "/url" }, method = {RequestMethod.GET,RequestMethod.POST})
 public String showPage(@Valid VO VO,
   BindingResult bindingResult, Locale locale, Model model, HttpSession session) {
   .
   .
   .
   .
 }

 @RequestMapping(value = "/url", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON)
 public @ResponseBody ResponseEntity<VO<vo>> searchByCriteria(
   @RequestBody @Valid FormVO formVO, BindingResult bindingResult, Model m,
   HttpServletRequest request) {
   .
   .
   .
 }

}

How to write Interceptor in Spring MVC or Spring Web


1. Provide the below ones in the dispatcher-servlet.xml containing in your project

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

 <security:global-method-security pre-post-annotations="enabled" />

 <context:component-scan base-package="com" />

 <context:property-placeholder location="file:///${configs}//*.properties" file-encoding="UTF-8" />

 <tx:annotation-driven transaction-manager="transactionManager" />

 <bean id="localeResolver"  class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
  <property name="defaultLocale" value="en" />
 </bean>

 <bean id="localeChangeInterceptor"  class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
  <property name="paramName" value="language" />
 </bean>


 <mvc:interceptors>
  <mvc:interceptor>
   <mvc:mapping path="/**" />
   <mvc:exclude-mapping path="/css/**" />
   <mvc:exclude-mapping path="/js/**" />
   <mvc:exclude-mapping path="/bootstrap/**" />
   <mvc:exclude-mapping path="/img/**" />
   <mvc:exclude-mapping path="/fonts/**" />
   <bean class="com.UserInterceptor" />
  </mvc:interceptor>

  <ref bean="localeChangeInterceptor"/>
 </mvc:interceptors>

 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix">
   <value>/WEB-INF/pages/</value>
  </property>

  <property name="suffix">
   <value>.jsp</value>
  </property>
 </bean>

 <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
     <property name="maxUploadSize" value="100000"/>
 </bean>
</beans>

2.Create a interceptor class as like below

import java.security.Principal;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.ws.rs.core.HttpHeaders;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import com.dto.UserVO;
import com.service.AuthorizationService;

public final class UserInterceptor implements HandlerInterceptor {


 public static class ACCEPTED_URLS_NO_CODE {
  public static final String ROOT = "/";
  public static final String SET_EFFECTIVE_CODE = "/set-effective-code/";
  public static final String ERROR = "/error/";


  public static boolean accept(String path) {
   return ( ROOT.equals(path) || SET_EFFECTIVE_CODE.equals(path) || ERROR.equals(path) );
  }
 }

 private static final Logger LOGGER = LoggerFactory.getLogger(UserInterceptor.class);
 private static final char PROXY_PRINCIPAL_DELIMITER = ',';

 @Value("${principal.proxy}")
 private boolean proxyPrincipal;

 @Autowired
 private AuthorizationService authorizationService;

 @Override
 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

  HttpSession session = request.getSession();
  Principal p = request.getUserPrincipal();
  if (p == null) {
   LOGGER.error("Principal is missing!");
   throw new Exception("Principal is missing!");
  }

  String userName = p.getName();
  if (proxyPrincipal) {
   int index = userName.indexOf(PROXY_PRINCIPAL_DELIMITER) + 1;
   userName = userName.substring(index, userName.indexOf(PROXY_PRINCIPAL_DELIMITER, index));
  }

  UserVO userData = (UserVO) session.getAttribute("currentUser");

  if (userData == null || !userData.getUserName().equals(userName)) {
   userData = authorizationService.getUser(userName);
   session.setAttribute("currentUser", userData);
  }

  if (userData.getTravellerCode() == null) {
   String selectedCode = "T1";

   if (selectedCode != null) {
    userData.selectTravellerCode(selectedCode);
   } else if (!ACCEPTED_URLS_NO_CODE.accept(request.getServletPath()) ) {
        response.addHeader(HttpHeaders.LOCATION, request.getContextPath() + ACCEPTED_URLS_NO_CODE.ROOT);
response.setStatus(HttpServletResponse.SC_FOUND);
    return false;
   }
  }
  return true;
 }

 @Override
 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
 }

 @Override
 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
 }
}