Friday, November 14, 2014

Spring MVC custom body tag library example


Create two java file with following contents:

package com.pkm.maven.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyTagOne extends BodyTagSupport {
    private int mTimes = 0;
    private BodyContent mBodyContent;
    
    public void setTimes(int pTimes) {
        mTimes = pTimes;
    }
    
    @Override
    public void setBodyContent(BodyContent pBodyContent) {
        mBodyContent = pBodyContent;
    }
    
    @Override
    public int doStartTag() throws JspException {
        if (mTimes >= 1) {
            return EVAL_BODY_TAG;
        } else {
            return SKIP_BODY;
        }
    }
    
    @Override
    public int doAfterBody() throws JspException {
        if (mTimes > 1) {
            mTimes--;
            return EVAL_BODY_TAG;
        } else {
            return SKIP_BODY;
        }
    }

    
    @Override
    public int doEndTag() throws JspException {
        try {
            if (mBodyContent != null) {
                mBodyContent.writeOut(mBodyContent.getEnclosingWriter());
            }
        } catch (Exception pIOEx) {
            throw new JspException("Error: " + pIOEx.getMessage());
        }
        return EVAL_PAGE;
    }
}





package com.pkm.maven.tag;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyTagTwo extends BodyTagSupport {    
    @Override
    public int doAfterBody() throws JspException {
        try {
            BodyContent bc = getBodyContent();
            String body = bc.getString();
            JspWriter out = bc.getEnclosingWriter();
            if (body != null) {
                body = body.substring(0, 1).toUpperCase() + body.substring(1);
                out.print(body);
            }
        } 
        catch (Exception ioe) {
            throw new JspException("Error: " + ioe.getMessage());
        }
        return SKIP_BODY;
    }
}

Create the tag library descriptor (TLD) under WEB-INF folder suppose named: "UiTabLib.tld":

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
         version="2.0">
 
     <tlib-version>1.0</tlib-version>
     <short-name>Ui Tab Library</short-name>
     <uri>UiTabLib</uri>
 
     <tag>
        <name>loopText</name>
        <tag-class>com.pkm.maven.tag.BodyTagOne</tag-class>
        <body-content>JSP</body-content>
        <info>This Tag Displayes given text multiple times</info>
        <attribute>
            <name>times</name>
            <required>true</required>
            <description>Provide number of times the text will be repeated</description>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
     <tag>
        <name>capitalize</name>
        <tag-class>com.pkm.maven.tag.BodyTagTwo</tag-class>
        <body-content>JSP</body-content>
        <info>This Tag Displays given string to be capitalized</info>
    </tag>
</taglib>

Reference & use the tag library:

<p>
    Body Tag Example: <br/>
    <% Integer counter = 1; %>
    <UiTabLib:loopText times="10">
        Counter: <%= (counter++) %><br/>
    </UiTabLib:loopText>
   <%= counter %>
</p>
<p>
    String capitalize (text to be capitalized): 
    <UiTabLib:capitalize>text to be capitalized</UiTabLib:capitalize>
</p>

Output would be like this:

Body Tag Example: 
Counter: 1
Counter: 2
Counter: 3
Counter: 4
Counter: 5
Counter: 6
Counter: 7
Counter: 8
Counter: 9
Counter: 10
11
String capitalize (text to be capitalized): Text to be capitalized

Spring MVC simple custom tag library example

Create a java file with following contents:

package com.pkm.maven.tag;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.SimpleTagSupport;

public class NewDateTag extends SimpleTagSupport {
    private String prefix;
 
    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }
    
    @Override
    public void doTag() throws JspException, IOException {
        final JspWriter writer = getJspContext().getOut();
        String pattern = "dd/MM/yyyy H:m:s";
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        if (prefix != null) {
            writer.print(prefix + " ");
        }
        writer.print(format.format(new Date()));
    }
}

Create the tag library descriptor (TLD) under WEB-INF folder suppose named: "UiTabLib.tld":

<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
         version="2.0">
 
     <tlib-version>1.0</tlib-version>
     <short-name>Ui Tab Library</short-name>
     <uri>UiTabLib</uri>
  
     <tag>
         <name>newDate</name>
         <tag-class>com.pkm.maven.tag.NewDateTag</tag-class>
         <body-content>empty</body-content>
         <attribute>
             <name>prefix</name>
             <type>java.lang.String</type>
             <required>false</required>
             <rtexprvalue>true</rtexprvalue>
         </attribute>
     </tag>
</taglib>

Reference & use the tag library:

<%@taglib prefix="UiTabLib" uri="UiTabLib" %>

<p>New Date Tag Lib Output: <UiTabLib:newDate/></p>
<p>New Date Tag Lib Output: <UiTabLib:newDate prefix="Prefix"/></p>

Output would be like this:

New Date Tag Lib Output: 14/11/2014 18:25:12
New Date Tag Lib Output: Prefix 14/11/2014 18:25:12

Saturday, October 11, 2014

HANDLING CUSTOM ERROR PAGES IN TOMCAT WITH SPRING MVC

Download full source code from here
web.xml
<error-page>
    <location>/error.jsp</location>
</error-page>
Create a file named 'error.jsp' under 'WEB-INF' with following contents. This jsp file will redirect to error404 action under error controller.
<!DOCTYPE html>
<%@taglib prefix="UiTabLib" uri="UiTabLib" %>
<html>
    <head>
        <title></title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta http-equiv="REFRESH" content="0;url=<UiTabLib:contextPath/>error/error404.htm?<UiTabLib:logError 

request="${requestScope}"/>">
    </head>
    <body>
        &nbsp;
    </body>
</html>
ErrorController.java
package com.pkm.maven.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

public class ErrorController extends MultiActionController {
    public ModelAndView error404(HttpServletRequest request, HttpServletResponse response) throws Exception {
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );
        String statusCode = request.getParameter("status_code");
        String exception = request.getParameter("exception");
        String requestUri = request.getParameter("request_uri");
        if (requestUri == null) {
            requestUri = "Unknown";
        }
  
        ModelAndView view = new ModelAndView("error/error404");
        view.addObject("statusCode", statusCode);
        view.addObject("exception", exception);
        view.addObject("requestUri", requestUri);
        
        return view; 
    }
}
Create a file named 'error404.jsp' under 'WEB-INF/jsp/error/' folder with following content:
<div>Request URI: ${requestUri}</div>
<div>Status Code: ${statusCode}</div>
<div>Exception: ${exception}</div>


Grail's Create Or Change Database Connection Manually Or Run-time | Using multiple data-sources in a Grail's project | Grail's Multiple Data Sources | Grail's multi tenant data-sources

In src/groovy, create a groovy class named 'UserHolder' with following contents:


package a.b.c

/**
 * Created by pritom on 14/08/2014.
 */
class UserHolder {
    public static Integer DEFAULT = 1;
    private static final ThreadLocal contextHolder = new ThreadLocal();
    public static String DS_PREFIX = "dataSource_";
    public static String DS_POSTFIX = "User";

    static void setEnvironment(Map environment) {
        contextHolder.set(environment);
    }

    static getEnvironment() {
        return contextHolder.get();
    }

    static void clear() {
        contextHolder.remove();
    }
}

Also create a groovy class named 'SwitchableDataSource' in src/groovy with following contents:


package a.b.c

import grails.util.Holders
import org.springframework.context.ApplicationContext
import org.springframework.jdbc.datasource.DriverManagerDataSource
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource

import javax.sql.DataSource

/**
 * Created by pritom on 14/08/2014.
 */
class SwitchableDataSource extends AbstractRoutingDataSource {
    def applicationContext

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext
    }

    protected DataSource determineTargetDataSource() {
        def user = UserHolder.getEnvironment();
        try {
            DriverManagerDataSource ds = super.determineTargetDataSource();
            return ds;
        }
        catch (Exception ex) {
            println "--->Error:: ${ex.getMessage()}";
            try {
                def ga = Holders.getGrailsApplication();
                String beanFullName = UserHolder.DS_PREFIX + user.id + UserHolder.DS_POSTFIX;
                if(user && user.id && ga.mainContext.containsBean( beanFullName ) ) {
                    println "Using data source: '${beanFullName}'";
                    return ga.mainContext.getBean(beanFullName);
                }
            }
            catch (Exception ex2) {
                println "--->Error:: ${ex2.getMessage()}";
            }
        }
    }

    @Override
    protected Object determineCurrentLookupKey() {
        def user = UserHolder.getEnvironment();
        return user?.id ?: UserHolder.DEFAULT;
    }

    @Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        super.setTargetDataSources(targetDataSources);
    }
}

Edit resource.groovy file under grails-app/conf/spring folder:


import a.b.c.SwitchableDataSource
import a.b.c.UserHolder
import org.springframework.jdbc.datasource.DriverManagerDataSource

// Place your Spring DSL code here
beans = {
    parentDataSource(DriverManagerDataSource) { bean ->
        bean.'abstract' = true;
        driverClassName = 'com.mysql.jdbc.Driver'
        username = "root"
    }

    "rootDataSource"(DriverManagerDataSource) { bean ->
        bean.parent = parentDataSource;
        bean.scope = 'prototype';
        url = "jdbc:mysql://localhost/user${UserHolder.DEFAULT}?useUnicode=yes&characterEncoding=UTF-8";
        username = "root"
    }

    def dataSources = [:]
    dataSources[UserHolder.DEFAULT] = ref("rootDataSource");

    dataSource(SwitchableDataSource) {
        targetDataSources = dataSources
    }
}

Now create another groovy class named 'DataSourceService' to bind datasource to your project dynamically/runtime with following contents:


package a.b.c

import grails.spring.BeanBuilder
import org.codehaus.groovy.grails.commons.GrailsApplication
import org.springframework.beans.BeansException
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.context.support.GenericApplicationContext

/**
 * Created by pritom on 14/08/2014.
 */
class DataSourceService implements ApplicationContextAware {
    ApplicationContext applicationContext;
    public GrailsApplication grailsApplication;

    @Override
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Add new bean to system
     * @param beanName
     * @param dsurl
     * @param uid
     * @param pwd
     * @return
     */
    def registerBean( String beanName, String dsurl, String uid, String pwd ) {
        String beanFullName = UserHolder.DS_PREFIX + beanName + UserHolder.DS_POSTFIX;
        if( !applicationContext.containsBean( beanFullName ) ) {
            def bb = new BeanBuilder()
            bb.beans {
                "$beanFullName" { bean ->
                    bean.parent = ref('parentDataSource');
                    bean.scope = 'prototype';
                    url = dsurl;
                    username = uid
                    password = pwd
                }
            }
            bb.registerBeans( applicationContext );

            println "Added $beanFullName"
        }
        else {
            println "Already got a bean called $beanFullName"
        }
    }

    /**
     * Remove bean from system
     * @param beanName
     * @return
     */
    def deRegisterBean( String beanName ) {
        if( applicationContext.containsBean( beanName ) ) {
            (applicationContext as GenericApplicationContext).removeBeanDefinition( beanName )
            println "Removed $beanName"
        }
        else {
            println "Trying to deRegister a bean $beanName that I don't know about"
        }
    }
}

Now create a filter in grails-app/filters named 'SecurityFilters' with following contents:


package filters

import a.b.c.UserHolder

class SecurityFilters {

    def filters = {
        all(controller: '*', action: '*') {
            before = {
     /* This line is for specify which user request to handle */
                if (params.int('user')) {
                    UserHolder.setEnvironment([id: params.int('user')]);
                }
            }
            after = { Map model ->

            }
            afterView = { Exception e ->

            }
        }
    }
}

Example of adding a new datasource to system:


DataSourceService dataSourceService = new DataSourceService();
dataSourceService.setApplicationContext(grailsApplication.mainContext);
dataSourceService.grailsApplication = grailsApplication;
dataSourceService.registerBean(params.user, "jdbc:mysql://localhost/user${params.user}?useUnicode=yes&characterEncoding=UTF-8", "root", "");

Suppose params.user = 3 here.

That's it Download code

Friday, October 10, 2014

Using Java Send Email Using Smtp Server(Html, Attachment, Embedded Image)

First download java mail api jar from: https://java.net/projects/javamail/pages/Home or here.
And add this to your project classpath.


package com.pritom;

import java.util.*;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.*;
import javax.mail.internet.*;

/**
 * Created by pritom on 30/11/2016.
 */
public class SendEmailUsingSmtp {
    private static final String toAddress = "pritom@xxxxx.com";

    public static void main(String[] args) {
        google();
        //office();
        //bleep();
    }

    private static void google() {
        String host = "smtp.gmail.com";
        String port = "587";
        String userName = "xxxxx@gmail.com";
        String password = "xxxxx";
        send(host, port, userName, password);
    }

    private static void office() {
        String host = "smtp.office365.com";
        String port = "587";
        String userName = "xxxxx@office.com";
        String password = "xxxxx";
        send(host, port, userName, password);
    }

    private static void bleep() {
        String host = "bleep.xxxxx.com";
        String port = "587";
        String userName = "pritom@xxxxx.com";
        String password = "xxxxx";
        send(host, port, userName, password);
    }

    private static void send(String host, String port, String userName, String password) {
        String attachments = "attachments/Attachment_1.gif;"
                + "attachments/Attachment_2.pdf;"
                + "attachments/Attachment_3.txt;"
                + "attachments/Attachment_4.docx;"
                + "attachments/Attachment_5.jpg";


        Properties props = new Properties();
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.port", port);
        props.put("mail.smtp.auth", "true");
        props.put("https.protocols", "TLSv1,SSLv3,SSLv2Hello");
        props.put("com.sun.net.ssl.enableECC", "false");
        props.put("jsse.enableSNIExtension", "false");

        String subject = "Java send mail example - TLS Authentication";

        Session mailSession = Session.getInstance(props, new javax.mail.Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(userName, password);
            }
        });

        MimeMessage message = new MimeMessage(mailSession) {
            protected void updateMessageID() throws MessagingException {
                if (getHeader("Message-ID") == null)
                    super.updateMessageID();
            }
        };

        try {

            /* If failed to send email then fail report delivered to following email address */
            /* But remember not all smtp server allow use different email address */
            //props.put("mail.smtp.from", "pritomkucse@gmail.com");

            message.setFrom(new InternetAddress(userName, "Pritom Kumar", "UTF-8"));
            message.setReplyTo(InternetAddress.parse(userName, false));
            message.addRecipient(Message.RecipientType.TO, new InternetAddress(toAddress, toAddress, "UTF-8"));

            message.setSentDate(new Date());
            message.setSubject(subject, "UTF-8");
            Multipart multipart = new MimeMultipart();

            BodyPart messageBodyPart = new MimeBodyPart();
            messageBodyPart.setContent("This is <b>message</b> body, pls see "
                    + "<i style='color: blue; font-size: 40px;'>attachments</i>", "text/html");
            multipart.addBodyPart(messageBodyPart);

            for( int i = 0; i < attachments.split(";").length; i++) {
                String fileName = attachments.split(";")[i];
                messageBodyPart = new MimeBodyPart();
                DataSource source = new FileDataSource(fileName);
                messageBodyPart.setDataHandler(new DataHandler(source));
                messageBodyPart.setFileName(source.getName());
                messageBodyPart.setHeader("Content-ID", "<CONTENT_" + i + ">");
                multipart.addBodyPart(messageBodyPart);
            }

            /* Some custom headers added to email */
            message.addHeader("header-1", "header-1-value");
            message.addHeader("header-2", "header-2-value");

            messageBodyPart = new MimeBodyPart();
            messageBodyPart.setContent("<h1>Attachments are added.</h1>Attached image as embedded:<br/>"
                    + "<img style='width: 50px;' src='cid:CONTENT_4'/>", "text/html");
            multipart.addBodyPart(messageBodyPart);

            message.setContent(multipart );
            println("Start sending email...");
            Transport.send(message);
            println("Mail sent with message ID=" + message.getMessageID());
        }
        catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private static void println(Object o) {
        System.out.println(o);
    }
}

Console output would be like following

Start sending email...
Mail sent with message ID=<2059904228.1.1477967571904.JavaMail.pritom@PRITOM-PC>

In my gmail inbox email would be render as follows:



Use following code block if you want to use SSL Authentication


props.put("mail.smtp.host", HOST);
props.put("mail.smtp.socketFactory.port", PORT);
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.port", PORT);