Tuesday, June 26, 2012

org.springframework.web.HttpSessionRequiredException: Session attribute 'user' required - not found in session

This error comes when the default session of spring expires, and we try to fetch user from @SessionAttribute("user").

The solution is to override the session timing in web.xml:

<session-config>
     <session-timeout>60</session-timeout>
 </session-config>

This will increase your session time to 60 minutes, now you will get this error after 60 mins of idle time.

We can also redirect it to the login page by the following entry in web.xml:

<error-page>
  <exception-type>
       org.springframework.web.HttpSessionRequiredException
  </exception-type>
  <location>/redirect.jsp</location>
</error-page>


Friday, June 22, 2012

Sending Mail using Spring 3.0 & Velocity Template:

Overview:
We would always like to separate our jsp and java part from each other as presentation and logic layer. So formatting our mail in java is not a good idea. So we will use velocity to separate the presentation part of mail into separate template and add that template in our java code before sending the mail. 

Library dependencies
The following additional jars to be on the classpath of your application in order to be able to use the Spring Framework's email library.
·         The  mail.jar library
·         The activation.jar library
  •    The org.springframework.context-3.0.3.RELEASE.jar library
  •    The org.springframework.context.support-3.0.4.RELEASE.jar library
  •    The velocity-1.7.jar library
  •    The velocity-1.7-dep.jar library


application-servlet.xml entry:

 <bean id="emailUtil" class="com.utility.EmailUtil" />
  
 <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean" p:resourceLoaderPath="/WEB-INF/velocity" />
 <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl" p:host="your host" />



EmailUtil.java

import java.util.List;
import java.util.Map;

import javax.mail.internet.MimeMessage;

import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.ui.velocity.VelocityEngineUtils;
import org.springframework.util.Assert;



public class EmailUtil {
    /* Email From param */
    public static final String FROM = "mailId@xyz.com";

    /* Email To param */
    public static final String TO = " mailId@xyz.com ";

    /* Email Subject param */
    public static final String SUBJECT = "test";

    /* Email CC param */
    public static final String CC_LIST = " mailId@xyz.com ";

    private JavaMailSender mailSender;
    private VelocityEngine velocityEngine;

    @Autowired
      public void setMailSender(JavaMailSender mailSender) {
            this.mailSender = mailSender;
      }
   
    @Autowired
      public void setVelocityEngine(VelocityEngine velocityEngine) {
      System.out.println("EmailUtil.setVelocityEngine()");
            this.velocityEngine = velocityEngine;
            System.out.println("EmailUtil.setVelocityEngine():"+this.velocityEngine+"::"+velocityEngine);
      }
   
    public void send(final String templateName, final Map<String, Object> model) {
      System.out.println("EmailUtil.send():templateName:"+templateName+" model:"+model);
        MimeMessagePreparator preparator = new MimeMessagePreparator() {
            @SuppressWarnings("unchecked")
            public void prepare(MimeMessage mimeMessage) throws Exception {
                  System.out.println("EmailUtil.send(...).new MimeMessagePreparator() {...}.prepare()");
                String from = FROM;//(String) model.get(FROM);
                String to = TO;//(String) model.get(TO);
                String subject = SUBJECT;//(String) model.get(SUBJECT);
                System.out.println("from:"+from+"to:"+to+"subject:"+subject);
                Assert.notNull(from);
                Assert.notNull(to);
                Assert.notNull(subject);
                List<String> ccList = (List<String>) model.get(CC_LIST);
                MimeMessageHelper message = new MimeMessageHelper(mimeMessage);
                message.setFrom(from);
                message.setTo(to);
                message.setSubject(subject);
                if (ccList != null) {
                    for (String cc : ccList) {
                        message.addCc(cc);
                    }
                }

                String text = VelocityEngineUtils.mergeTemplateIntoString(
                        velocityEngine, templateName, model);
                System.out.println("EmailUtil.send(...).new MimeMessagePreparator() {...}.prepare(): "+text);
                message.setText(text, true);
            }
        };

        mailSender.send(preparator);
    }
}


Velocity Template:

invalid-tx.vm and put this in src package.

As of todate ($date.format('MM/dd/yyyy', $effectiveDate)), the following list of transactions are invalid:
#foreach($tx in $txList)
    $tx.indx, $number.format("currency", $tx.amount, $locale)
#end


Now we can send mail using:

emailUtil.send("invalid-tx.vm", model);

Done !!!


Simple Plain Java Program to send mail:

Sending test mail using plain java file:

import org.springframework.mail.MailException;
import org.springframework.mail.MailSender;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;

public class RunMail {
      private static final String TO = " mailId@xyz.com ";
      private static final String JAVAMAIL_TEXT = "Hello World! mail generated using JavaMail.";

      public static void main(String[] args) {

            JavaMailSimpleMailSender sender1 = new JavaMailSimpleMailSender();
            sender1.sendMessage(TO, JAVAMAIL_TEXT);
            }
      }

      class JavaMailSimpleMailSender{
            public void sendMessage(String to, String text) {
                  SimpleMailMessage msg = new SimpleMailMessage();
                  msg.setTo(to);
                  msg.setSubject("Test Message");
                  msg.setFrom("mailId@xyz.com ");
                  msg.setText(text);

                  MailSender sender = getMailSender();
                  try {
                  sender.send(msg);
                  } catch (MailException e) {
                  e.printStackTrace();
                  }
                  }
      protected MailSender getMailSender() {
      JavaMailSenderImpl sender = new JavaMailSenderImpl();
      sender.setHost("your.host.com");
      return sender;
      }
      }

Wednesday, June 20, 2012

Displaytag table search using datatables jquery plugin


Add client side search (filter) functionality to displaytag generated table.

Displaytag doesn't allow us to have a table header. So, we used Rhett Sutphin’s patch which adds the support for <display:header>.

Used datatable jquery plugin to filter the data on the client side








The display tag jar that contains the latest patch can be downloaded from:


The jquery can be downloaded from:


Include the above downloaded scripts in jsp page:

<script type="text/javascript" src="js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src=" js/jquery-1.7.1.min.js"></script>

The Display Table will be drawn like this:

<display:table name="${modelsList}" id="model" uid="models" pagesize="" style="background-color:white" decorator="subtotaler" requestURI="" cellspacing="1" cellpadding="5">
<display:setProperty name="basic.empty.showtable" value="true" />
   <display:header>
     <thead id="sModel">
      <tr>
       <th><input type="text" name="modelName" class="search_init"/></th>
<th><input type="text" name="modelDescription" class="search_init"/></th>
            </tr>
        </thead>
       </display:header>
       <display:column property="modelName" title="Quote"/>
       <display:column property="modelDescription" title="Service Model"/>
      </display:table>

For the Search on <display:header> add the following script:

<script type="text/javascript">
    var confirmed = false;
    $(function () {
        /* Search functionality */
        var oTable = $('#models').dataTable({
            "bPaginate":false,
            "bLengthChange":false,
            "bFilter":true,
            "bSort":false,
            "bInfo":false,
            "bAutoWidth":false,
            "bStateSave":false
        });
        $("thead input").keyup(function () {
            /* Filter on the column (the index) of this element */
            oTable.fnFilter(this.value, $("thead input").index(this));
        });

        $("thead input").focus(function () {
            if (this.className == "search_init") {
                this.className = "";
                this.value = "";
            }
        });

        $("thead input").blur(function (i) {
            if (this.value == "") {
                this.className = "search_init";
                this.value = asInitVals[$("thead input").index(this)];
            }
        });
    });
</script>





Monday, June 18, 2012


Configuration of Dwr 3 with Spring 3.0




If you are using spring MVC then web.xml:


<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"                                                                                                     xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
  <display-name>SpringDwr</display-name>
  <servlet>
    <servlet-name>springdwr</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet- class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>springdwr</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>

 <servlet-mapping>
  <servlet-name>springdwr</servlet-name>
  <url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
 <welcome-file-list>
        <welcome-file>add.jsp</welcome-file>
</welcome-file-list>
           
</web-app>


You will not require to have dwr.xml.


Along with the spring configuration in your application-servlet.xml following entries will be done:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
      xmlns:context="http://www.springframework.org/schema/context"
      xmlns:dwr="http://www.directwebremoting.org/schema/spring-dwr"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
            http://www.directwebremoting.org/schema/spring-dwr  http://www.directwebremoting.org/schema/spring-dwr-3.0.xsd">


<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
   
<!-- DWR will scan all Spring managed beans containing @RemoteProxy or
     @RemoteMethod annotations and register Creator proxies for them.
     This will NOT scan any classes not managed by Spring. -->
      <dwr:annotation-config id="springdwr" />

<!-- DWR will scan the classpath and search classes containing @RemoteProxy                                                                                                                                                                                                            or @RemoteMethod annotations. This will register the beans and Creator proxies for these classes.-->
      <dwr:annotation-scan base package="com.springdwr.controller,com.springdwr.service" scanDataTransferObject="true" scanRemoteProxy="true" />

      <!-- DWR will map util.js and engine.js files to the dwrController. You can then include this files as external Javascript references from your JSP -->
      <dwr:url-mapping />

      <!-- Defines the dwrController. During production, set the debug property to false -->
      <dwr:controller id="dwrController" debug="true" />

<!-- This is required if you want to configure any beans not managed by Spring. Leaving it enabled doesn't do any negative effects. Here's a sample config: -->
      <dwr:configuration />
      <context:component-scan base-package="com.springdwr.*" />



The class which will be used:

package com.springdwr.service;

import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @Service enables the class to be used as a Spring service
 * @RemoteProxy enables the class to be used as a DWR service
 * @Transactional enables transaction support for this clas
 */
@Service("springService")
@RemoteProxy(name="dwrService")
@Transactional
public class ArithmeticService {
      /**
       * @RemoteMethod exposes this method to DWR.
       * Your JSP pages can access this method as Javascript
       * Your Spring beans can still access this method.
       */
      @RemoteMethod
      public Integer add(Integer value1, Integer value2) {
            return value1+ value2;
      }
     
}


The JSP :

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <script type='text/javascript' src="/SpringDwr/dwr/engine.js"></script>
 <script type='text/javascript' src="/SpringDwr/dwr/util.js"></script>
 <script type="text/javascript" src="/SpringDwr/dwr/interface/dwrService.js"></script>     
      <title>Spring 3.0 MVC – DWR 3.0 Integration Tutorial</title>
</head>
<body>
<h3>3.0 MVC – DWR 3.0 Integration Tutorial</h3>
<div style="border: 1px solid #000; width: 3000px;">
      Add Two Numbers: <br/>
      <input id="num1" type="text" size="5"> +
      <input id="num2" type="text" size="5">
      <input type="submit" value="Add" onclick="add()" /> <br/>
      Sum: <span id="sum">(Result will be shown here)</span>
</div>
<script type="text/javascript">
      function add() {
            // Retrieve the value of text inputs
            var operand1 = dwr.util.getValue("num1");
            var operand2 = dwr.util.getValue("num2");
           
            // Pass two numbers, a callback function, and error function
            dwrService.add(operand1, operand2, {
                  callback : handleAddSuccess,
                  errorHandler : handleAddError
            });
      }

      // data contains the returned value
      function handleAddSuccess(data) {
            // Assigns data to result id
            dwr.util.setValue("sum", data);
      } 
      function handleAddError() {
            // Show a popup message
            alert("Can't add the values!");
      }
</script>

</body>
</html>