Showing posts with label JSP. Show all posts
Showing posts with label JSP. Show all posts

Friday, 20 June 2014

Spring Web App Template

I don't create new web apps that often and therefore can easily forget the necessary bits!  This is my memory jogger for how do to these.

Folders
Notes: In eclipse create a new java project with the correct maven folder structure.  This is the sample folder structure

    project_home/src
    project_home/src/main
    project_home/src/main/java
    project_home/src/main/resources
    project_home/src/main/webapp
    project_home/src/main/webapp/WEB-INF
    project_home/src/main/webapp/WEB-INF/jsp
    project_home/src/test
    project_home/src/test/java
    project_home/src/test/resources

pom.xml
Location: project_home/pom.xml
Notes: The basic maven pom which has the correct values for the spring classes although the spring versions can be updated. 

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.me.app</groupId>
    <artifactId>me-web</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Sample Web App</name>
    <description />
    <properties>
        <spring.version>3.1.2.RELEASE</spring.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

Eclipse
Notes: After putting this pom in place convert to a maven project.  In eclipse right click on the project and go to Configure - Convert to Maven Project.  This should create a folder called Maven Dependencies which contains all the libraries defined by the pom.
Right click on the project and go to properties.  
 - Select 'Project Facets' and make sure it is a faceted form with Dynamic Web Module, Java and JavaScript are all checked.
 - Click on Deployment Assembly and make sure that Source /src/main/webapp is mapped to Deploy Path / and also that Source: Maven Dependencies are mapped to Deploy Path /WEB-INF/lib.
 - Click on Web Project Settings and check the context-root value
 - Click on Java Build Path and add main/java, main/resources, test/java and test/resources as source folders.

web.xml
Location: project_home/src/main/webapp/WEB-INF/web.xml
Notes: This is the file that is read by the application server to determine details about the servlet it needs to run.  It contains the main servlet class and mappings of which requests get sent to this servlet.  In this case the servlet is the spring MessageDispatchServlet as this is a spring app.
   
 <web-app 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_2_5.xsd"  
    version="2.5">
  <display-name>Web App</display-name>
  
  <servlet>  
        <servlet-name>webapp</servlet-name>  
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
        <load-on-startup>1</load-on-startup>  
    </servlet>  
  
    <servlet-mapping>  
        <servlet-name>webapp</servlet-name>  
        <url-pattern>/app/*</url-pattern>  
    </servlet-mapping>  
  
</web-app>


servlet.xml
Location: project_home/src/mainwebapp/WEB-INF/servlet.xml
Notes: The servlet xml is the file that is used by the spring MessageDispatcherServlet and is the root of the spring configuration for the web application.

<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation="  
        http://www.springframework.org/schema/beans       
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">  
   
    <context:component-scan base-package="com.me.app.web" />  
   
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="prefix">  
            <value>/WEB-INF/jsp/</value>  
        </property>  
        <property name="suffix">  
            <value>.jsp</value>  
        </property>  
    </bean>  
   
</beans> 


Controller
Location: project_home/src/main/java/com/me/app/web/controller/Greeting.java
Notes: This is a sample controller that maps to a jsp.

package com.me.app.web.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * Sample controller.
 */
@Controller
@RequestMapping("/greeting")
public class Greeting
{
    /**
     * Method to say hello.
     */
    @RequestMapping("/hello")
    public ModelAndView hello()
    {
        final ModelAndView mav = new ModelAndView("hello");
     return mav;
    }
}

jsp
Location: project_home/src/webapp/WEB-INF/jsp/hello.jsp
Notes: This is a very simple jsp file that is used to just smoke test that the application is running.

<html>  
  <head>
    <title>Sample Web App</title>
  </head>  
  <body>
    <center>  
      <h2>Sample Web App</h2>  
      <h4>Hello</h4>  
    </center>  
  </body>  
</html>  

Friday, 8 June 2012

Tiles Tutorial / Setup

Tiles

Tiles is a layout technology which carves pages into different sections or 'tiles'.  These can then be controlled and set using an xml file.  The easiest way to see this is just from a simple example.

Basic Tiles Config

The basic tiles configuration is an xml file (or multiple files) which defines the layouts.


<!DOCTYPE tiles-definitions PUBLIC
       "-//Apache Software Foundation//DTD Tiles Configuration 3.0//EN"
       "http://tiles.apache.org/dtds/tiles-config_3_0.dtd">
      
<tiles-definitions>

    <!-- Main layout -->
    <definition name="myapp.main" template="/WEB-INF/views/main.jsp">
        <put-attribute name="header" value="
/WEB-INF/views/header.jsp" />
        <put-attribute name="footer" value="
/WEB-INF/views/footer.jsp" />
    </definition>

    <definition name="myapp.home" extends="
myapp.main">
        <put-attribute name="body" value="
/WEB-INF/views/home.jsp" />
    </definition>

</tiles-definitions>

JSP Layout

The main.jsp page above is a standard JSP page which has a couple of 'holders' for the tiles elements.

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>

    <html>
       <head />
        <body> 
            <!-- header -->
            <div class="header">
                <tiles:insertAttribute name="header" />
            </div>
             
            <!-- Central Container -->
            <div class="main_content">
                <tiles:insertAttribute name="body" />
            </div>
             
            <!-- footer -->
            <div class="footer">
                <tiles:insertAttribute name="footer" />
            </div>
        </body>
    </html>

Here you can see that the 'tiles' elements are brought in by the tiles tag.  These place holders are resolved by the xml file configuration for the page that has been requested. The ModelAndView will control the tiles name that is to be used.

Controller

The ModelAndView which is returned by the Controller will define the view to use based on the definition name in the tiles configuration.  For example


    ModelAndView mav = new ModelAndView("myapp.home");

This will use the 'myapp.home' definition which itself extends the 'myapp.main' definition.  As a result the full page is rendered using this hierarchy.

Spring Config

Finally the spring configuration needs to be told how to resolve the view name.  This is standard with spring, whether it is jsp view resolver, Freemarker, etc.  For tiles the configuration looks like this,

    <!-- Configure Tiles -->
    <bean id="tilesConfigurer" class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">

        <property name="definitions">
            <list>
                <value>/WEB-INF/tiles/myapp.xml</value>
            </list>
        </property>

        <property name="preparerFactoryClass"
                  value="org.springframework.web.servlet.view.tiles2.SpringBeanPreparerFactory"/>
    </bean>

    <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
        <property name="viewClass" value="org.springframework.web.servlet.view.tiles2.TilesView"/>
    </bean>

Here the 'tileConfigurer' gives a list of the definitions that are used.  This means that the definitions can be split into logical lumps and you don't end up with a file which is unmanageably large!  The 'viewResolver' is a standard spring element which tells spring how to resolve the view name.

Maven

Maven dependencies,

  <dependency>
    <groupId>org.apache.tiles</groupId>
    <artifactId>tiles-extras</artifactId>
    <version>3.0.4</version>
  </dependency>

Preparer Classes

In the situation of having a menu defined in Tiles you don't want to have to remember to get every controller to put particular elements in the model. An easy way of extracting this is to use a ViewPreparer. Implement the ViewPreparer interface and complete the execute() method.  Then in the tiles definition you can add a preparer="myAppPreparer"

    <!-- Main layout -->
    <definition name="myapp.main" template="/WEB-INF/views/main.jsp" preparer="myAppPreparer">
        <put-attribute name="header" value="
/WEB-INF/views/header.jsp" />
        <put-attribute name="footer" value="
/WEB-INF/views/footer.jsp" />
    </definition>

The preparer name here is a fully qualified path name by default but can be a spring bean and therefore have its dependencies injected by spring. To make spring resolve these beans you need to have the 'preparerFactoryClass' configured in the spring tilesConfigurer(see above).

The HttpServletRequest can be obtained within a ViewPreparer as follows,

    /**
     * {@inheritDoc}
     */
    @Override
    public void execute(final TilesRequestContext tilesRequestContext, final AttributeContext attributeContext)
    {
        final HttpServletRequest request = (HttpServletRequest) tilesRequestContext.getRequestObjects()[0];
        ... other code to add to the request ...
    }

Loose Ends

There are occasions when a url is required within the application or spring context and the url needs to be mapped to the tiles names.  This is possible by using a spring mvc:controller

  <mvc:view-controller path="my_url" view-name="my.tiles.definition"/>

This then allows the 'my_url' to be used within the application and context.

Thursday, 7 June 2012

Basic JSP Tags

Basic JSP Commands

Here are a load of basic jsp tags that I'll add to over time.  Initially though, it'll just cover the real basics

In a JSP page there are certain elements which are always available.  These include

request - HttpServletRequest
session - HttpSession

For example to view the username of the currently logged in user you can use

    <%= request.getUserPrincipal().getName() %>

You can also do this with the c:out command below if you use the pageContext first.

JSP Tags

To use the basic JSP tags you'll need to include the import at the top of the jsp page.

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>  
 

c:out

Use this to 'print' to the screen eg

    <c:out value="${modelValue}"/>

where modelValue is put into the ModelMap in the controller.

c:if

Use this to conditionally add items

    <c:if test="${myValue == 'Value'}">
        do something
    </c:if>

c:choose / c:when / c:otherwise

This is the equivalent to the if - else if - else statement

    <c:choose>
        <c:when test="${myValue == 'Value'}">
            do something
        </c:when>
        <c:when test="${myValue == 'AnotherValue}">
            do something else
        </c:when>
        <c:otherwise>
            do the fall back action
        </c:otherwise>
    </c:choose>

c:url

This is a really useful tag which allows you to just create a link and the tag will take care of the server name, port and application context

    <c:url value="/my_link" />

you can also add attributes

    <c:url value="/my_link"> 
        <c:param name="link" value="${linkId}" /> 
    </c:url>

c:forEach

This is a basic iterator for looping through lists etc

    <c:forEach var="item" items="${itemList}" varStatus="status">

        ${status.first ? 'Start' : ''}

        ${status.index}: ${item.name}

        ${status.last ? 'End' : ''}

    </c:forEach>

c:set

It is occasionally necessary to create a variable that is used by other jsp commands or tags. You can do this by using the c:set tag, for example

    <c:set var="linkId" value="${param.link}"/>
You can set different scopes for these by using the scope="..." attribute,
    <c:set var="linkId" scope="session" value="${param.link}" />
but by default it is page-scope only.