Showing posts with label spring mvc. Show all posts
Showing posts with label spring mvc. Show all posts

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>


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>