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>  

Thursday 19 June 2014

Dynamically Updating JavaFX Table

There are many tricks on the web for updating tables when a value changes and the table doesn't update such as adding and removing columns to force the table to refresh.  I think there may be a refresh table option in Java 8 now.  However, getting the data structure correct makes a big difference.

Using Properties
Use properties in the backing object so that the table can bind to them and get the updates.  In the example below the name is immutable so doesn't need a property but the count is changeable so use a property value and importantly include the countProperty() method.


public class MyTableData
{
    /**
     * A value that doesn't change so just stored as a string.
     */
    private final String name;
        
    /**
     * A changeable value so stored as a property.
     */
    private final SimpleIntegerProperty count;
    
    /**
     * Constructs a new MyTableData with the given parameters.
     *
     * @param name The name
     * @param count The count
     */
    public MyTableData (final String name, final Integer count)
    {
        this.name= name;
        this.count = new SimpleIntegerProperty(count);
    }

    /**
     * Gets the namevalue.
     *
     * @return the name
     */
    public String getName()
    {
        return name;
    }

    /**
     * Gets the count value.
     *
     * @return the count
     */
    public int getCount()
    {
        return count.get();
    }

    /**
     * Set the count value.
     *     * @param count The new value to set
     */
    public void setCount(final int count)
    {
        this.count.set(count);

    }

    /**
     * The count property.
     *
     * @return The count property
     */
    public IntegerProperty countProperty() 
    {
        return count;
    }
}

The Table
In the table create the columns as normal,

        // Count Column
        final TableColumn<MyTableData, Number> countCol = new TableColumn<MyTableData, Number>("Count");
        countCol.setCellValueFactory(new PropertyValueFactory<MyTableData, Number>("count"));