Getting started with Spring Annotations

In the last article, I introduced you about how to write a console application with Spring and by setting up ClassPathXmlApplicationContext context, however, I prefer to configure Spring application without using XML.

Remember the day I was a Java developer in 2009, I was really afraid of XML configuraiton, Spring and Java EE at that time were a whole bunch of XML files. After that, I always try to find frameworks that support for configuration over annotation. Luckily, Spring framework supports for that.

Preresiquites

You need to have:

  • Java installed on your machine
  • Maven istalled
  • A IDE like NetBeans, STS or IntelliJ Idea to editing the source code.
  • JDK 1.8

Generate project structure

Using the terminal ( or command line) to create a standard Java project structure:

mvn archetype:generate -DgroupId=com.tumivn.hello -DartifactId=HelloSpring 
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 

Open the pom.xml inside the project folder to add dependencies (Spring libs):

<properties>

    ...

    <spring.version>4.2.0.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    ...

</dependencies>

We use Spring version 4.2.0.RELEASE.

Create FirstService and SecondService class

package com.tumivn.hello;

import org.springframework.stereotype.Component;

@Component
public class FirstService {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
    public void info() {
        System.out.println("Service's name: " + getName());
    }

    public String getName() {
        return name;
    }
}

The SecondService class depends on FirstService bean call firstService2:

package com.tumivn.hello;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class SecondService {

    private FirstService firstService;

    @Autowired
    @Qualifier("firstService2")
    public void setFirstService(FirstService firstService){
        this.firstService = firstService;
    }   

    public void info() {
        System.out.println("Second service's with firstService: " + firstService.getName());
    }
}

However, right now, we do not have the SecondService bean with name firstService2. As you see, we have FirstService and SecondService are both Spring components.

Create App class

The App class has two dependencies:

package com.tumivn.hello;

import com.tumivn.hello.configuration.DIConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class App 
{
    @Autowired
    @Qualifier("firstService1")
    private FirstService firstService;

    @Autowired
    private SecondService secondService;

    public void info(){
        System.out.println("App Info");
        firstService.info();

        secondService.info();
    }

}

Create DIConfiguration class

As you see, we need to have two FirstService beans, so we need to define a DIConfiguration class for injecting the two beans like below:

package com.tumivn.hello.configuration;

import com.tumivn.hello.FirstService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan(value={"com.tumivn.hello"})
public class DIConfiguration {

    @Bean
    public static FirstService firstService1(){
        FirstService firstService = new FirstService();
        firstService.setName("FirstService1");
        return firstService;
    }

    @Bean
    public static FirstService firstService2(){
        FirstService firstService = new FirstService();
        firstService.setName("FirstService2");
        return firstService;
    }
}

The @Configuration is to mark the DIConfiguration as a Spring configuration class and the @ComponentScan annotation is for define the root package that Spring have to scan for components and beans.

Create main method inside App class

public static void main( String[] args )
{
    AnnotationConfigApplicationContext context =
            new AnnotationConfigApplicationContext(DIConfiguration.class);
    //context.scan("com.tumivn.hello");
    //context.refresh();
    App app = context.getBean(App.class);
    app.info();

}

The app.info() calls firstService.info() and secondService.info(), there for, when we run the main method, we will see:

Result

As you see, setting up a Spring application without XML configuration files is not very hard. An this example is just for examining Configuration over annotations feature of Spring, but not a good example of Dependency Injection, because it is not based on contracts (interfaces).

I will write another article about DI with Spring.

Happy coding!

Getting Started With Spring

Preresiquites

You need to have:

  • Java installed on your machine
  • Maven istalled
  • A IDE like NetBeans, STS or IntelliJ Idea to editing the source code.
  • JDK 1.8

Generate project structure

Using the terminal ( or command line) to create a standard Java project structure:

mvn archetype:generate -DgroupId=com.tumivn.hello -DartifactId=HelloSpring 
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false 

Open the pom.xml inside the project folder to add dependencies (Spring libs):

<properties>

    ...

    <spring.version>4.2.0.RELEASE</spring.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>

    ...

</dependencies>

We use Spring version 4.2.0.RELEASE.

Create a bean

Create a new Spring Bean call Book

package com.tumivn.hello;

public class Book {
    private String title;

    public void setTitle(String title) {
        this.title = title;
    }

    public void printTitle() {
        System.out.println("Book's title: " + title);
    }
}

Create a Spring bean configuration file

To help the application create a bean for Book class, wee need to declare a Book bean in Spring bean configuration file:

<beans xmlns="http://www.springframework.org/schema/beans"
   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-4.0.xsd">

<bean id="bookBean" class="com.tumivn.hello.Book">
    <property name="title" value="The three musketeers" />
</bean>

</beans>

Create a main method for running and testing the Spring Bean configuration

package com.tumivn.hello;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App
{
    public static void main( String[] args )
    {
        ApplicationContext context = new ClassPathXmlApplicationContext(
             "SpringBeans.xml");

        Book obj = (Book) context.getBean("bookBean");
        obj.printTitle();
    }
} 

In the App.java class, we create a Context and ask it to read SpringBeans.xml configuration file for setting up beans for usage.

Now the application folder structure is as below:

Applications structure

Running the application

By running the application, the result will be:

Running the application

Congrats! You’ve just write the first Spring application. By creating this app, you’ve just learned how to setup a bean, and how to retrieve it in runtime for usage.

Happy coding!!

Applying localization to your Play! web application

Applying localization on Play Framework application is not very easy, because there is no tutorial for it, even on Play Framework official website. I think that every developer will struggle when applying localization to Play application. So I would like to share a short tutorial to make it works:

Open the conf/application.conf for setting the support languages / cultures, in my case, I would like to support English and Vietnamese by editing this below line:

play.i18n.langs = [ "en", "vi" ] 

Add your messages by languages in conf\messages (default) and conf\messages.vi

conf\messages file content:

application.name = My Application

And edit the conf\messages.vi content:

application.name = Ứng dụng của tôi

To use it in your controller and views, you must import these below when defining the controller class:

import play.api.i18n.Messages
import play.api.i18n.Messages.Implicits._
import play.api.Play.current

Now, add the implicit request to action:

def hello(name: String) = Action{ implicit request =>
    val title = Messages("application.name")
    Ok(views.html.hello(name, title))
}

And, define the view hello.scala.html

@(name: String, title: String)(implicit messages: Messages, lang: Lang)

@main(title) {
    <h1>@(Messages("application.name"))</h1>
    <h3>Hello <em>@name</em></h3>
    <h3>LANG: @lang.code</h3>
}

You should remember to add the route definition in conf\routes

GET     /hello                      controllers.Application.hello(name: String)

If the browser is set to use English as default language, you’ll see:

English

In case you set Vietnamese as the default language of the browser:

Vietnamese

Voila, now you can apply localization to your Play! website.

Happy programming!

How to fix Java language level issue in Maven project

Java 1.8 and Java 1.7 have a lot of new good syntax for usages. However, when working with a Maven project, it will use Java 1.5 to compile our source code by default. If you use new features of Java like Lambda Expression, or try-with-resource, you may see some error like this when building project with maven:

Common Error

To fix it, we should add the source and target for the maven compiler plugin:

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

And now, we can compile our project with any Java version we want.

Why I’m not a Microsoft fan anymore

From LifeHacker.com

Image from LifeHacker.com

In the past, I’m a Microsoft fan, it means that I try to use all of Microsoft softwares and devices instead of trying things from the others. But then, I found out that not all Microsoft softwares were good, and I’ve made a many changes:

From Windows 8 to Mac OS X

  • Mac OSX has better performance than Windows 8. It won’t take a lot of time and eat up all I/O + CPUs for indexing or scanning for viruses.
  • Mac OSX has better User Experience vs. Windows 8.
  • Better Bash shell vs. command line tool
  • Greater software management, I can use Brew or App Store to install apps. Uninstall apps are far more easier.
  • Better battery life, 5 hours working on Macbook Pro with Mac OSX vs. 3 hours with Windows 8
  • Great iBooks app

From Android/Windows Phone to iOS

  • Better user experience
  • Better apps, especially productivity apps
  • Faster camera
  • Better designed
  • Great iBook app (again)

From .NET to JVM

As a .NET competency lead in my company, I still learn .NET and train people using .NET, but all my personal projects will not be .NET. I’ve been waiting for something like ASP.NET vNEXT, and I can’t wait for it any more. I’ve try Nancy, Mono, and run these apps on Linux, but there were a lot of struggles. I want to host my apps everywhere and it should be scalable, but ASP.NET has many dependencies like big .NET framework, Windows Server, IIS and it cost me a lot of money for running a small comunity site like Jou.vn.

Mean while, although Java is not as modern and shiny as C#, but Java can be run everywhere, and if I feel not comfortable with Java, I can use Scala/Groovy/Closure/Jython/JRuby to program, and JVM apps have great performance. And JVM community are as great as .NET community.

With JVM, I feel freemdom. With .NET I feel comfortable with it ecosystem, but I also feel just like swimming in a pool instead of sailing a yatch on the ocean.

Maybe ASP.NET vNEXT will become stable in the next couple of year and Linux community will use it for development. And I’m waiting for having a chance to write app by using C# again and host it easily on every environment like the way I do right now with Java. Just wait!

From OneDrive to Google Drive (but I still retain OneDrive)

OneDrive subscription is great, I can have 10TB of online storage as well as Office license for my Mac/Windows. I love OneDrive, but from the last night, I felt so angry because OneDrive doesn’t allowed me to play MP4 video files. There’s no reason that Microsoft doesn’t support for playing a common video files like MP4. So I had to buy 1TB Google Drive subscription for storing my video clips.

Microsof has best office apps for me and Google has best online office apps for collaboration. So I have to use both of them.

I just wish that Microsof support online playing for common video file types. If not, for me, it’s just a file storage and just because of Office license.

Now, I’m flexible and I’m not Microsoft fan or any one’s fan anymore. I will choose which is best suite for me.

Thanks Microsoft for more than 20 years serving me from MSDOS!

JUnit cannot run tests in Maven project because of not following naming conventions

You write some unit tests, and find out that they are not run by command mvn test. It may because of you didn’t follow naming conventions.

For example, if your create a test class like below:

import org.junit.Test;
import static org.junit.Assert.*;
/**
* Created by tumivn on 1/23/15.
*/
public class AWeirdName {
    @Test
    public void testMe(){
        assertTrue(false);
    }
}

Then run mvn test, and it just doesn’t run the testMe unit.

This is because you named your class not following default naming conventions. A test class should have name:

  • Test*
  • *Test
  • *TestCase

If your test class doesn’t follow these conventions, Maven will not run the tests belong to it. If you want to use names that are follow other patterns, you have to configure Maven Surfigure Plugin to allow them.

Develop a CRUD Movie app with Django 1.7

Getting stated with Django 1.7 and implementing simple CRUD

1. Create django_movie project

We will create a Django project with Python 3.4.1 and Django 1.7 called django_movie project.

django-admin.py startproject movie_project 

Change the current cusor to project foler django_movie and use django built-in server to run the project

manage.py runserver 127.0.0.1:8000

Browse localhost:8000 you will see the result:

Run the project

Our web app doesn’t have anything to browse until now. We need to add more code for our website.

2. Create MovieLib app and the landing page

Call the below command to create MovieLib app in

manage.py startapp MovieLib

Open settings.pyand add MovieLib to INSTALLED_APPS setting:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'MovieLib',
) 

In the MovieLib/views create the index view method for handle the http://localhost:8000/ request:

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello Django!") 

On the above code, we define index method with return an HttpResponse object with content Hello Django!. But it’s not enough, we need to change urls.py inside movie_project directory by adding a new line:

from django.conf.urls import patterns, include, url
from django.contrib import admin

urlpatterns = patterns('',
    # Examples:
    # url(r'^$', 'movie_project.views.home', name='home'),
    # url(r'^blog/', include('blog.urls')),

    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', 'MovieLib.views.index'), #index method inside /MovieLib/views.py will handle the `/` request 

)

Browse http://localhost:8000/ again, and you will see the result:

Result

But, it’s just a page with a text on it. I want to have better content to deliver to users.

3. Create home page using template

I want to store all URLs related to MovieLib app in MovieLib folder, and use view class instead of view method. So I will delete the index method created in section 2 and also delete the below line in movie_project/urls.py:

url(r'^$', 'MovieLib.views.index'), #index method inside /MovieLib/views.py will handle the `/` request 

Then, I will create an IndexView class inside MovieLib/views.py:

from django.views.generic import TemplateView

# Create your views here.
class IndexView(TemplateView):
    template_name = 'index.html'

The IndexView class inherits from TemplateView class, so it will pick the index.html template (defined by the last sentence of the above code listing) to render as a HTML page.

Then create a new urls.py file inside MovieLib folder, the urls.py will contain all URLs for MovieLib app:

from django.conf.urls import patterns, url
from MovieLib import views

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view()),
)

Until now, we do not have the index.html template. We will create a templates folder inside MovieLib folder. And then create our index.html inside templates folder:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>LANDING PAGE</title>
</head>
<body>
    <h1>LANDING PAGE</h1>
</body>
</html>

And result is:

Landing page

How about a better web template by using BootStrap? Yes, we can, but its require us to have some static file like (CSS, images). I choose the starter template form BootStrap homepage. And now the index.html content is as below:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Movie Library</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">

    <!-- Custom styles for this template -->
    <link href="{% static "site.css" %}" rel="stylesheet">

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
    <div class="container">
    <div class="navbar-header">
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
      <a class="navbar-brand" href="#">MovieLib</a>
    </div>
    <div class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Index</a></li>
        <li><a href="#about">Create</a></li>
      </ul>
    </div><!--/.nav-collapse -->
    </div>
    </div>

    <div class="container">

    <div class="starter-template">
        <h1>Movie Listing</h1>
        <p class="lead">All movies should be listed here!</p>
    </div>

    </div><!-- /.container -->


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>

There are two lines you should focus:

    {% load staticfiles %}
    <link href="{% static "site.css" %}" rel="stylesheet">

The first line is for declare that we will generate some link references to static file. The second line using static directive to generate static link to site.css. Where should we store the site.css file? By default Django looks for static file in static folder inside app folder (\MovieLib), so we need to create a static folder, and add a new site.css file inside it with content:

body {
    padding-top: 50px;
}
.starter-template {
    padding: 40px 15px;
}

Now, browse homepage again:

New home page

4. Creating base template

A template for listing (landing) page is good but not enough, we will create a base template for all page in MovieLib app.

Now we create /MovieLib/templates/base_page.html:

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="">
    <meta name="author" content="">
    <link rel="icon" href="../../favicon.ico">

    <title>Movie Library - {% block title %}{% endblock %}</title>

    <!-- Latest compiled and minified CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">

    <!-- Optional theme -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">


    <!-- Custom styles for this template -->
    <link href="{% static "site.css" %}" rel="stylesheet">

    <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="#">MovieLib</a>
            </div>
            <div class="collapse navbar-collapse">
            <ul class="nav navbar-nav">
                <li class="active"><a href="#">Index</a></li>
                <li><a href="#about">Create</a></li>
            </ul>
            </div><!--/.nav-collapse -->
        </div>
    </div>

    <div class="container">

        <div class="starter-template">
        {% block content %}{% endblock %}
        </div>

    </div><!-- /.container -->


    <!-- Bootstrap core JavaScript
    ================================================== -->
    <!-- Placed at the end of the document so the pages load faster -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
    <!-- Latest compiled and minified JavaScript -->
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
</body>
</html>

There’re two lines on the above code listing are for defining two Django blocks:

<title>Movie Library - {% block title %}{% endblock %}</title>
...
{% block content %}{% endblock %}

Now, we will edit the index.html template to inherit form the base_page.html template:

{% extends "base_page.html" %}

{% block title %}Movie listing{% endblock %}

{% block content %}
    <h1>Movie Listing</h1>
    <p>Movie list goes here</p>
{% endblock %}

Now, as you can see, the index.html is smaller and it’s easier to maintain and change app UI template by just editing base_page.html rather than modifying all pages.

5. Create Movie model

Open MovieLib/models.py and add code to define Movie class:

from django.db import models


# Create your models here.
class Movie(models.Model):
    title = models.CharField(max_length=128)
    genre = models.CharField(max_length=128)
    release_date = models.DateField()
    price = models.DecimalField(max_digits=20, decimal_places=0)

I choose to use sqlite as the database to store all movie. You can easily change to MySQL or PostGreSQL if you want to without fear because Django ORM supports for MySQL, PostGreSQL and Sqlite as well.

Open the settings.py and you will see database configuration setting part:

# Database
# https://docs.djangoproject.com/en/1.7/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

The default database provider is Sqlite and the default database name is db.sqlite3. We keep using the default database configuration.

6. Create database

Create database structure is quite easy, if your DB configuration settings is correctly, just call the below command and all tables will be created inside the database:

manage.py syncdb

During executing the command, it asks you to create a super admin account:

syncdb

Actually, at this time, there’s no movie table is created in the database. We need to add some migrations.

In previous versions of Django, we need to have South to apply migration. However, from Django 1.7, it has built-in data migration functions.

Now we ask manage.py to make migration:

manage.py makemigrations

If you want to see the SQL migration query for the first migration, you can call:

manage.py slqmigrate MovieLib 0001

Sql migrate

The table name is not Movie but MovieLib_movie, because Django has put a prefix (app name) before table name.

Then, ask manage.py to execute migration:

manage.py migrate 

First migrate

Until now, there is no records in MovieLib_movie table, but you can add some records by using Django shell

manag.py shell

Add new movie record

You can see how many Move records in database as well:

Movie records

4. Change Index view to show movie listing

First thing first, we have to change the IndexView class inside MovieLib/views.py

from django.views.generic import ListView
from MovieLib.models import Movie

# Create your views here.
class IndexView(ListView):
    template_name = 'index.html'
    model = Movie

The IndexView now inherits ListView class and we set model property to Movie class so we can access to show all movies on index.html template.

Secondly, change the index.html template:

{% extends "base_page.html" %}

{% block title %}Movie Listing{% endblock %}

{% block content %}
<h1>Movie Listing</h1>
<table class="table">
    <tr>
        <th>Title</th>
        <th>Genre</th>
        <th>Price</th>
        <th>Release Date</th>
        <th></th>
    </tr>
    {% for movie in object_list %}
        <tr>
            <td>{{ movie.title }}</td>
            <td>{{ movie.genre }}</td>
            <td>{{ movie.price }}</td>
            <td>{{ movie.release_date }}</td>
            <td></td>
        </tr>
    {% endfor %}
</table>
{% endblock %}

And now try to browse http://localhost:8000 you will see:

Result

It looks great. Now we will implement CreateView class.

5. Create Movie

To implement create movie function, we can choose between multiple approaches, but I just try the easiest approach, is to create a view class that inherits from django.views.generic.CreateView class.

Firstly, we need to create create.html template:

{% extends "base_page.html" %}

{% block title %}Create Movie{% endblock %}

{% block content %}
<h1>Create Movie</h1>
<form method="post" class="form">
    {% csrf_token %}
    {% for field in form %}
        <div class="form-group">
        {{ field.errors }}
        {{ field.label_tag }}
        {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Submit" />
</form>
{% endblock %}   

By inherits CreateView, it’s very to implement our CreateView:

from django.views.generic import CreateView
from MovieLib.models import Movie

class CreateView(CreateView):
    template_name = 'create.html'
    model = Movie
    success_url = '/'

, And add into the MovieLib/urls.py:

from django.conf.urls import patterns, url
from MovieLib import views

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view()),
    url(r'^create$', views.CreateView.as_view()), #new line
)

Just some simple lines of code, you’re done for movie creation feature. Let try to browse http://localhost:8000/create and add some new movies. Our CreateView class will handle both GET and POST request. The validation rules defined in Movie model are used to validate user input but no error message was showed, I will have another article for validation topic.

6. Update Movie

To create update movie fuction, we need to create a new view inherits from django.views.generic.UpdateView:

class UpdateView(UpdateView):
    template_name = 'update.html'
    model = Movie
    success_url = '/'

Then, we need to create update.html template:

{% extends "base_page.html" %}

{% block title %}Update Movie{% endblock %}

{% block content %}
<h1>Update Movie</h1>
<form method="post" class="form">
    {% csrf_token %}
    {% for field in form %}
        <div class="form-group">
        {{ field.errors }}
        {{ field.label_tag }}
        {{ field }}
        </div>
    {% endfor %}
    <input type="submit" value="Submit" />
</form>
{% endblock %}

Add new URL to MovieLib\urls.py:

url(r'^edit/(?P<pk>\d+)$', views.UpdateView.as_view(), name='movie_edit'),

Add a new Edit link for each Movie item in index.html template:

<a href="{% url 'movie_edit' movie.id %}" class="btn">Edit</a>

7. Delete Moview

Create a new class called MovieMixin in MovieLib/forms.py:

from MovieLib.models import Movie

class MovieMixin(object):
    model = Movie
    def get_context_data(self, **kwargs):
        kwargs.update({'object_name':'Movie'})
        return kwargs

Then a new view inherits from django.views.generic.DeleteView:

class DeleteView(MovieMixin, DeleteView):
    template_name = 'delete_confirm.html'
    def get_success_url(self):
        return reverse('movie_index')

Add new URL to MovieLib\urls.py:

url(r'^delete/(?P<pk>\d+)$', views.DeleteView.as_view(), name='movie_delete'),

Add new delete link to each Movie item in index.html template:

<a href="{% url 'movie_delete' movie.id %}" class="btn">Delete</a>

8. Update create and index links on base_template.html

<li><a href="{% url 'movie_index' %}">Index</a></li>
<li><a href="{% url 'movie_create' %}">Create</a></li>

8. Conclusion

As a new bie of Python and Django, I just try to get thing done, that is the reason why I do not explain the reason why I use this class or that class, or the mechanism inside of django. I just try to make a CRUD app that works, and it really works. Hope that you can follow a make a new version of your own.

If you want copy my source code for reference, you can clone on my GitHub:

My choices: Python/Django, Groovy/Grails and Java

It’ve been 7 months from my last post on tumivn.com. In the last post, I share with everyone that I will take my free time to focus on Java. Yes, in the last 7 months, I spent all my free time to learn/re-visit Java, Spring MVC, Scala, Laravel, Python.. to find the best match languages and frameworks to me.

Spring MVC is not for me

Learning Spring MVC makes me exited but also take me a lot of time. It’s not as easy as learning ASP.NET MVC or Laravel. Spring MVC required a lot of configurations to make it works and It’s not the good solution for rapid web development. PHP guys and RoR guys will be extremelly angry when working with Spring MVC. For me, I’m not angry, but I’m confused why it needs to be so complicated. The first Spring MVC project that I worked with is in 2009, and it’s about 5 years from that time, and the complexity is still high.

Several weeks in learning Scala

Scala is a beautiful and powerful language, but after spending several weeks playing with Scala, I found out that we can’t easily build up a Scala team in a short period of time. Scala is very hard to master, and it’s very hard to get all your team on the same page.

Play for Java is a better choice when comparing with Spring MVC. I will build some POC with Play in near future. However, I don’t want to just end my journey with just Java, Scala and PHP. I want to play more with another language, and it’s Python.

One week with Python/Django

Python rocks! Python and Django simplicity make me wanna cry, I want to work with high productivty language and framewor like Python and Django. Their readability really impresses me. I’m really in love of Python and Django.

..and change the plan

And now, I have to change the plan. As an .NET technical architect, I still update my .NET/ASP.NET/SQL Server/BizTalk.. knowledge, I still conduct .NET/TDD/ASP.NET MVC courses for my company. I also put Python/Django, Groovy/Grails and Java into my plan:

  • Rebuild my blog (tumivn.com and vn.tumivn.com) by using Django to learn more about Python/Django.
  • Rebuild Jou.vn developer community using Python/Django + some Java services as well.
  • Write articles about: Django, Play Framework, Groovy/Grails for Vietnamese developers.

Thanks Python & Django, you make me want to code again. Being a manager/TA is good, but I still love programming.

Coding for happiness! ^^

Back to my developer life

Spring Boot

I’m familiar with .NET Framework and ASP.NET MVC, I did love ASP.NET MVC over Spring 2 because of its simplicity, and it was the reason that I chose .NET and ASP.NET MVC for my first startup company in the year of 2009.

Now, I’m not an entrepreneur, I’m just an employee, a technical architect in an outsourcing company and I’ve lost my habit of programming like a developer.

And when thinking of a create anything related to community, ASP.NET MVC is not my 1st choice anymore, although ASP.NET MVC is open source and free, but IIS and Windows Server is not free, and I had to pay a lot when running the Jou Developers community (a community for Vietnamese developer).

I turned to PHP and Java, but my feeling about PHP is that it’s not the language I love the best, Laravel is great, NginX is great, but I’m not in love with PHP anyway. Java is something different, I like Java, but I’m afraid of XML stuff, and I hate to configure everything by myself for a small web application. This is also the reason why I do not like Android very much, when I have to touch XML files every time.

New Spring, Spring Web MVC, Spring Boot, thymeleaf and Gradle really wake me up. I can write web application or console Java application without fear. They save my time. Especially Spring Boot, with it, we can simple call a java command to run a website without any pre-install webserver. ASP.NET is changing with OWIN and Katana, but it doesn’t mean that we will have a light weight web server instead of IIS to host a website. XPS server of Mono is good but not up-to-date, it’s very hard to configure and I give up using XPS. Why I have to waste my time when I have Apache, Tomcat, Nginx, and Jetty.

I’m a .NET technical architect, and I’m still a .NET developer. But by now, most of my personal projects will be developed by using something that are more open like Java, Scala, JavaScript and PHP.

This blog has been idle for a long time, now it’s the time to make it rise again. Back to my hobbies, I will reading-coding-writing night and day. Saigon, 24/02/2014

Getting started with Spring MVC and Gradle

Today, I would like to share an article that can help to get started with Spring MVC and Gradle.

What is Gradle?

I never use Gradle before, however, it’s easy to know what Gradle is, due to wikipedia.org:

“Gradle is a project automation tool that builds upon the concepts of Apache Ant and Apache Maven and introduces a Groovy-based DSL instead of the more traditional XML form of declaring the project configuration.”

I don’t know about Groovy, however, we can learn a lot about Gradle by visiting http://www.gradle.org/.

Install Gradle on Windows

Download the latest Gradle distributed package at http://www.gradle.org/. Current version of Gradle is 1.9.

I extract Gradle distribution to folder c:\gradle-1.9 and also add gradle root folder to system PATH variable.

To see as if Gradle is working, open command line application and try to call gradle.bat, the you see the result like below, you can now using Gradle.

I choose NetBeans 7.3 to be my IDE, but NetBeans doesn’t support Gradle officially, so we need to install a plugin named Gradle by follow the instruction from the web page http://plugins.netbeans.org/plugin/44510/gradle-support.

After installing Gradle, you need to configure Gradle plugin by open menu Tools->Options. We need to set the Gradle Installation Directory for the plugin.

Then, use NetBeans to create new Gradle project:

After choosing project type, now we have to input project name and the main class:

After clicking finish, then a project will be created with its structure like below:

You can see the build.gradle file and settings.gradle file. The build.gradle file is the most important one. You don’t need to use NetBeans to create the project, you just need create a new folder and create the two files build.gradle and settings.gradle.

The settings.gradle just contains the project name:

rootProject.name = 'gradle-simple-mvc'

The build.gradle stores all configuration needed for our project:

apply plugin: 'java'

sourceCompatibility = '1.7'
[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'

if (!hasProperty('mainClass')) {
    ext.mainClass = 'com.tumivn.mvcsample.Main'
}

repositories {
    mavenCentral()
}

dependencies {
    // TODO: Add dependencies here ...
    // You can read more about how to add dependency here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
    testCompile group: 'junit', name: 'junit', version: '4.10'
}

To enable java in the project, we need to enable java plugin:

apply plugin: 'java'

The main repository we use for loading dependencies (java libraries) is Maven so we need to declare it:

repositories {
    mavenCentral()
}

Netbeans also declare a dependency for the project, which is JUnit, for unit testing:

dependencies {
    // TODO: Add dependencies here ...
    // You can read more about how to add dependency here:
    //   http://www.gradle.org/docs/current/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
    testCompile group: 'junit', name: 'junit', version: '4.10'
}

However, we need to change the the content of the build.grade so it will be a Spring MVC application other than a Java SE application:

apply plugin: 'war'
apply plugin: 'jetty'

repositories {
    mavenCentral()
}

dependencies {
    providedCompile 'javax.servlet:servlet-api:2.5'
    compile 'org.springframework:spring-webmvc:3.2.5.RELEASE'
    testCompile 'junit:junit:[4,)'
    runtime 'javax.servlet:jstl:1.2'
}

/* Change context path (base url). otherwise defaults to name of project */
jettyRunWar.contextPath = ''

We need 'war' plugin to enable web development and when building the application a war file will be created for deployment; 'jetty' plugin for running jetty web server and deploy our website for testing. And the project need more dependencies:

dependencies {
    providedCompile 'javax.servlet:servlet-api:2.5'
    compile 'org.springframework:spring-webmvc:3.2.5.RELEASE'
    testCompile 'junit:junit:[4,)'
    runtime 'javax.servlet:jstl:1.2'
}

We need javax.servlet:servlet-api version 2.5 and spring web MVC framework version 3.2.5 for develop our website.

Then, we need add more folders to create web application structure:

You can see the web.xml file, it's the web configuration file, below is its content:

<?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">

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

in this file we need to declare an org.springframework.web.servlet.DispatcherServletDispatcherServlet instance to processing work flow. Its name is dispatcher and the configuration file will be stored at [application root]/src/webapp/WEB-INF/spring/dispatcher-servlet.xml.

The dispatcher-servlet.xml content:

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

  <context:component-scan base-package="com.tumivn.mvcsample.controller" />  
  <mvc:annotation-driven />

  <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/view/"/>
    <property name="suffix" value=".jsp"/>
  </bean>

</beans>

We declare to use annotation to configure routing instead of using XML by a declaration:

  <mvc:annotation-driven />

Beside, we have a declaration to allow dispatcher-servlet to scan through com.tumivn.mvcsample.controller package to get controllers appropriate for each request.

Now it's the time to write the first controller named HomeController:

package com.tumivn.mvcsample.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HomeController {

    @RequestMapping("/")
    public String loadIndexPage(Model model) {
        model.addAttribute("title", "Hello Spring MVC!");
        return "index";
    }
}

The loadIndexPage method is configured to response to the "/" request, and it will send the model with "title" message inside and the view "index" (WEF-INF/view/index.jsp) to front controller to merge view and model and return the result to browser. Below is the implementation of index.jsp

<!DOCTYPE HTML>
<html>
    <head>
        <title>${title}</title>
    </head>
    <body>
        <h1>${title}</h1>
    </body>
</html>

Now, it's the time to build the application. You can easily right click at the project root and choose build menu to build. Or open command line and go to the project root folder and then call "gladle.bat build" command and see build successes.

Now, it's time to run the web application by using the jettyRun task of gradle.

The Jetty server will be run and the website will be available at address http://localhost:8080/gradle-simple-mvc. Open a browser and browse the url and you will see a message "Hello Spring MVC!" on the browse. Congratulation!

To reference, source code is available at GitHub.

This is the first time I touch Java for 5 years. Many things new, and many things I almost forgot. But Java, Gradle and Spring MVC make me excited. I love to learn more about Java and PHP for my personal projects. And still use .NET and ASP.NET MVC for daily jobs.

Happy coding!