Saturday, September 27, 2014

GRAILS Render Or Display XML In Browser


import groovy.xml.XmlUtil
....
def xmlString = "YOUR XML STRING";
def xmlAsText = XmlUtil.serialize(xmlString)
render(text: xmlAsText, encoding:"UTF-8", contentType:"text/xml")

GRAILS Custom Codec Example

All custom codec must be in grails-app/utils folder in any package.
Suppose I first created a package named 'pritom.kumar.codecs'.
Then created a groovy (not other type of class) class inside the package such named 'UpperCodec'.groovy
Class name must be end with 'Codec'.
My custom codec groovy class look like this:
package pritom.kumar.codecs

/**
 * Created by pritom on 05/09/2014.
 */
class UpperCodec {
    static encode = { target ->
        return target != null && target instanceof String ? target.toString().toUpperCase() : target
    }
}
Now you can use this as code in controller, service, other java or groovy classes, views and other places like this.

println "i am pritom kumar".encodeAsUpper();

Will print the following:

I AM PRITOM KUMAR

Basically you can do various things using custom codec.

Friday, September 19, 2014

Spring MVC - Custom Exception Handling & Send Appropriate Error Code

Download full source code


Create a custom exception handler class as follows:


package com.pkm.maven.exception;

public class SpringException extends RuntimeException {
    private String exceptionMsg;
    
    public SpringException(String exceptionMsg) {
        this.exceptionMsg = exceptionMsg;
    }
    
    public String getExceptionMsg() {
        return this.exceptionMsg;
    }
    
    public void setExceptionMsg(String exceptionMsg) {
        this.exceptionMsg = exceptionMsg;
    }
}

Add following lines of code to your XXX-servlet.xml under WEB-INF


<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="com.pkm.maven.exception.SpringException">ExceptionPage</prop>
        </props>
    </property>
    <property name="defaultErrorView" value="error"/>
</bean>

Create a jsp page named 'ExceptionPage.jsp' defined in previous XXX-servlet.xml file under WEB-INF folder.


<h3 class="error">${exception.exceptionMsg}</h3>

Also create a file named 'error.jsp' under WEB-INF/jsp/ folder


<h3>General Error Page</h3>

Now time to throw custom exception

From method1 & method2 i am throwing my custom error so rendering my custom error page 'ErrorPage.jsp' & in method4, I am not throwing any exception but when invoking the line 'nullString.length()', it automatically throwing general exception, so rendering 'error.jsp' as defined in XXX-servlet.xml.


package com.pkm.maven.controller;

import com.pkm.maven.exception.SpringException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

/**
 * Controller action would be like this
 * public (ModelAndView | Map | String | void) actionName(HttpServletRequest, HttpServletResponse [,HttpSession] [,CommandObject]);
 * @author Pritom K Mondal
 */

public class CustomerController extends MultiActionController {    
    public ModelAndView method1(HttpServletRequest request, HttpServletResponse response) throws Exception { 
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );
        throw new SpringException("Error from customer controller and method1() action.");
        //return new ModelAndView("CustomerPage", "msg", "method1() method"); 
    }
 
    public ModelAndView method2(HttpServletRequest request, HttpServletResponse response) throws Exception { 
        response.setStatus( HttpServletResponse.SC_BAD_REQUEST  );
        throw new Exception("Error from customer controller and method2() action.");
        //return new ModelAndView("CustomerPage", "msg", "method2() method"); 
    }
 
    public ModelAndView method3(HttpServletRequest request, HttpServletResponse response) throws Exception { 
        return new ModelAndView("CustomerPage", "msg", "method3() method"); 
    }
 
    public ModelAndView method4(HttpServletRequest request, HttpServletResponse response) throws Exception { 
        String nullString = null;
        Integer length = nullString.length();
        return new ModelAndView("CustomerPage", "msg", "method4() method"); 
    }
}

Output would be like this in browser if you browse 'customer/method1' or 'customer/method2':


Output would be like this in browser if you browse 'customer/method4':


Access Spring-ApplicationContext/ServletContext From Everywhere

Create a java class such named 'AppUtils.java' with following contents:


package com.pkm.maven.common;

import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AppUtils implements ApplicationContextAware {
    private static ApplicationContext ctx;
    private static ServletContext __servletContext;
    
    @Override
    public void setApplicationContext(ApplicationContext ctx) {
        AppUtils.ctx = ctx;
    }
    
    public static ApplicationContext getApplicationContext() {
        return ctx;
    }
    
    public static ServletContext getServletContext() {
        if (__servletContext == null) {
            __servletContext = (ServletContext) ctx.getBean("servletContext");
        }
        return __servletContext;
    }
}

Now make a entry to 'applicationContext.xml'


<bean id="contextApplicationContextProvider" class="com.pkm.maven.common.AppUtils"></bean>

Finally access application context/servlet context from everywhere like this:

package com.pkm.maven.app;

import com.pkm.maven.common.AppUtils;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;

public class AppHandler {
    
    public static String getContextPath() {
        try {
            ApplicationContext applicationContext = AppUtils.getApplicationContext();
            ServletContext servletContext = AppUtils.getServletContext();
            return servletContext.getContextPath();
        }
        catch (Exception ex) {
            return "<b>ERROR</b>";
        }
    }
}

Wednesday, September 17, 2014

Spring MVC with ControllerClassNameHandlerMapping MultiActionController


maven2-servlet.xml


<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">

    <context:component-scan base-package="com.pkm.maven"/>
    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
        <property name="caseSensitive" value="true" />
        <!--<property name="pathPrefix" value="/pathPrefix" />-->
    </bean>
    <bean class="com.pkm.maven.controller.CustomerController"/>

    <bean id="viewResolver"
    	class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
        <property name="viewClass">
            <value>com.pkm.maven.common.JstlView</value>
        </property>
    </bean>
</beans>

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>maven2</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>maven2</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

CustomerController.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 CustomerController extends MultiActionController{
 
    public ModelAndView method1(HttpServletRequest request, HttpServletResponse response) throws Exception { 
        return new ModelAndView("CustomerPage", "msg", "method1() method"); 
    }
 
    public ModelAndView method2(HttpServletRequest request, HttpServletResponse response) throws Exception { 
        return new ModelAndView("CustomerPage", "msg", "method2() method"); 
    }
}

You have to create a file named 'CustomerPage.jsp' under WEB-INF/jsp/

URL would be like this

  • customer/method1.htm
  • customer/method2.htm

Download example src code

Sunday, September 14, 2014

Spring MVC Framework Global Layout Used To Be Template

In your xxxxx-servlet.xml you can extend the viewResolver viewClass with your own implementation (Download full source code)


<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
        <property name="caseSensitive" value="true" />
        <!--<property name="pathPrefix" value="/pathPrefix" />-->
    </bean>


    <bean class="com.pkm.controllers.UserController"/>
    
    <bean id="viewResolver"
     class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
        <property name="viewClass">
            <value>com.pkm.common.JstlView</value>
        </property>
    </bean>

</beans>

JstlView.java

package com.pkm.common;

import java.util.Map;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.view.InternalResourceView;

public class JstlView extends InternalResourceView {
    @Override
    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
        String dispatcherPath = prepareForRendering(request, response);
        if (model != null) {
            for (Map.Entry pairs : model.entrySet()) {
                String key = pairs.getKey().toString();
                Object value = pairs.getValue();
                request.setAttribute(key, value);
            }
        }

        // set original view being asked for as a request parameter
        request.setAttribute("_____CONTROLLER_VIEW_NAME_____", dispatcherPath);

        // force everything to be template.jsp
        RequestDispatcher rd = request.getRequestDispatcher("/WEB-INF/template.jsp");
        rd.include(request, response);
    }
}

template.jsp


<!doctype html>
<html lang="en">
<head>
    <title>Hello :: Spring Application</title>
</head>
<body>
    <header>
        <jsp:include page="header.jsp"/>
    </header>
    <jsp:include page="${_____CONTROLLER_VIEW_NAME_____}"/>    <footer>
        <jsp:include page="footer.jsp"/>
    </footer>
</body>
</html>

Spring MVC with ControllerClassNameHandlerMapping

Project Structure: (Download example)


springapp-servlet.xml


<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
        <property name="caseSensitive" value="true" />
        <!--<property name="pathPrefix" value="/pathPrefix" />-->
    </bean>
    <bean class="com.pkm.controllers.UserController"/>    
    <bean id="viewResolver"
     class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
        <property name="prefix">
            <value>/WEB-INF/jsp/</value>
            <!--All controller based view file goes here-->
        </property>
        <property name="suffix">
            <value>.jsp</value>
            <!--View file extension would be jsp-->
        </property>
    </bean>
</beans>

web.xml


<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 

xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
        <servlet-name>springapp</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springapp</servlet-name>
        <url-pattern>*.htm</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

UserController.java


package com.pkm.controllers;

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView; 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; 
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; 
import java.io.IOException;
 
public class UserController implements Controller { 
    protected final Log logger = LogFactory.getLog(getClass()); 
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException { 
        logger.info("Returning hello view"); 
        logger.info(request.getQueryString());
        logger.info(request.getParameterMap());
        logger.info(request.getRequestURI());
        logger.info(request.getRequestURL());
        logger.info(request.getDispatcherType());
        ModelAndView modelAndView = new ModelAndView("user");
        modelAndView.addObject("obj1", "Object 1");
        modelAndView.addObject("obj2", "Object 2");
        return modelAndView;
    } 
}

WEB-INF/index.jsp


<html>
  <head><title>Example :: Spring Application</title></head>
  <body>
    <h1>Example - Spring Application</h1>
    <p>This is my test.</p>
    <a href="user.htm">GO TO USER CONTROLLER</a>
  </body>
</html>

WEB-INF/jsp/user.jsp


<html>
  <head><title>Hello :: Spring Application</title></head>
  <body>
    <h1>Hello - Spring Application</h1>
    <p>Greetings.</p>
    <p>Object1: ${obj1}</p>
    <p>Object2: ${obj2}</p>
  </body>
</html>