<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Viral Patel</title>
    <description>The latest articles on DEV Community by Viral Patel (@viralpatel).</description>
    <link>https://dev.to/viralpatel</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F94121%2F06e71aa6-e032-4e5f-b3c2-f1869babf4e3.png</url>
      <title>DEV Community: Viral Patel</title>
      <link>https://dev.to/viralpatel</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/viralpatel"/>
    <language>en</language>
    <item>
      <title>Spring Boot FreeMarker Tutorial with Example</title>
      <dc:creator>Viral Patel</dc:creator>
      <pubDate>Mon, 15 Jul 2019 01:12:00 +0000</pubDate>
      <link>https://dev.to/viralpatel/spring-boot-freemarker-tutorial-with-example-1752</link>
      <guid>https://dev.to/viralpatel/spring-boot-freemarker-tutorial-with-example-1752</guid>
      <description>&lt;p&gt;&lt;strong&gt;Spring Boot FreeMarker Hello World Tutorial&lt;/strong&gt; – Getting started with FreeMarker templates in Spring Boot is super easy. Spring Boot’s auto-configuration (spring starters) speeds up integrating any new tech in any Spring based project. In this tutorial we will learn Spring Boot and FreeMarker integration and create a hello world app.&lt;/p&gt;

&lt;p&gt;This Spring Boot app will show a form to capture user input (name, email and date of birth). Show some default values in the table using Freemarker and allow the user to delete the entries from the table. Nothing fancy, the basic stuff.&lt;/p&gt;

&lt;p&gt;For this project we will use following technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Spring Boot 2.1.6&lt;/li&gt;
&lt;li&gt;Java 8 (Can also be compiled with Java 11)&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmr2yhsdu3u9gq3w6yr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flmr2yhsdu3u9gq3w6yr2.png" alt="spring boot freemarker example project structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Maven dependencies for Spring Boot with FreeMarker
&lt;/h2&gt;

&lt;p&gt;The directory structure is like that of standard Spring Boot project. You could generate this using Spring Initializer (&lt;a href="https://start.spring.io/" rel="noopener noreferrer"&gt;start.spring.io&lt;/a&gt;) or just clone this repository. Note that we include the &lt;code&gt;spring-boot-starter-freemarker&lt;/code&gt; to auto configure Freemarker view for Spring Boot web project.&lt;/p&gt;

&lt;p&gt;pom.xml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;
&amp;lt;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"&amp;gt;
    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;

    &amp;lt;groupId&amp;gt;net.viralpatel&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-freemarker-example&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.0.1-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;packaging&amp;gt;jar&amp;lt;/packaging&amp;gt;

    &amp;lt;name&amp;gt;spring-boot-freemarker-example&amp;lt;/name&amp;gt;
    &amp;lt;description&amp;gt;Spring Boot FreeMarker (FTL) Hello World example&amp;lt;/description&amp;gt;

    &amp;lt;parent&amp;gt;
        &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;spring-boot-starter-parent&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;2.1.6.RELEASE&amp;lt;/version&amp;gt;
        &amp;lt;relativePath/&amp;gt; &amp;lt;!-- lookup parent from repository --&amp;gt;
    &amp;lt;/parent&amp;gt;

    &amp;lt;properties&amp;gt;
        &amp;lt;java.version&amp;gt;1.8&amp;lt;/java.version&amp;gt;
    &amp;lt;/properties&amp;gt;

    &amp;lt;dependencies&amp;gt;
        &amp;lt;!-- Compile --&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-freemarker&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/dependency&amp;gt;

        &amp;lt;!-- Test --&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-boot-starter-test&amp;lt;/artifactId&amp;gt;
            &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;

    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Spring Boot Application Class
&lt;/h2&gt;

&lt;p&gt;The Spring Boot application class is the standard one. The Spring Boot Jar project to bootstrap the server and configure default beans. The &lt;code&gt;@SpringBootApplication&lt;/code&gt; is a convenient annotation that wraps &lt;code&gt;@Configuration&lt;/code&gt;, &lt;code&gt;@EnableAutoConfiguration&lt;/code&gt; and &lt;code&gt;@ComponentScan&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;SpringBootFreemarkerExampleApplication.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package net.viralpatel.springbootfreemarkerexample;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootFreemarkerExampleApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootFreemarkerExampleApplication.class, args);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Model and Controller – Spring Boot with FreeMarker
&lt;/h2&gt;

&lt;p&gt;Let’s start with a simple Customer pojo class which contains attributes customerId, customerName, dateOfBirth and email. Also let us add constructor, getter and setter methods.&lt;/p&gt;

&lt;p&gt;Customer.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package net.viralpatel.springbootfreemarkerexample;

import java.time.LocalDate;

import org.springframework.format.annotation.DateTimeFormat;

public class Customer {

    private int customerId;
    private String customerName;

    @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
    private LocalDate dateOfBirth;
    private String email;

    public Customer() {
        super();
    }

    public Customer(int customerId, String customerName, String email, LocalDate dateOfBirth) {
        super();
        this.customerId = customerId;
        this.customerName = customerName;
        this.dateOfBirth = dateOfBirth;
        this.email = email;
    }

    // Getter and setters
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let us check the CustomerController class. Again, its the standard Spring MVC Controller defined using &lt;code&gt;@Controller&lt;/code&gt; annotation. This class defines methods &lt;code&gt;index()&lt;/code&gt;, &lt;code&gt;add()&lt;/code&gt; and &lt;code&gt;delete()&lt;/code&gt; which are mapped to /, /add and /delete urls respectively. Note that we are using &lt;code&gt;@GetMapping&lt;/code&gt; annotation to map these urls.&lt;/p&gt;

&lt;p&gt;Note that in index() method, we return the “index” string. This would render index.ftl freemarker template which we will soon create. Also the @ModelAttribute annotation in index() method binds the modelmap which we can use to pass back the values to freemarker template.&lt;/p&gt;

&lt;p&gt;CustomerController.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package net.viralpatel.springbootfreemarkerexample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class CustomerController {

    private CustomerService customerService;

    public CustomerController(CustomerService customerService) {
        this.customerService = customerService;
    }

    @GetMapping("/")
    public String index(@ModelAttribute("model") ModelMap model) {
        model.addAttribute("customers", customerService.findAll());
        return "index";
    }

    @PostMapping("/add")
    public String add(Customer customer) {
        customerService.add(customer);
        return "redirect:/";
    }

    @GetMapping("/delete/{customerId}")
    public String delete(@PathVariable int customerId) {
        customerService.remove(customerId);
        return "redirect:/";
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Services – Spring Boot with FreeMarker
&lt;/h2&gt;

&lt;p&gt;The CustomerService is again standard Spring &lt;code&gt;@Service&lt;/code&gt; class. We defined a static List of customers. This is just a temporary local data store to keep list of customers. Ideally we would use a database or an in-memory database. However let us keep things simple for now.&lt;/p&gt;

&lt;p&gt;CustomerService.java&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package net.viralpatel.springbootfreemarkerexample;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;

import org.springframework.stereotype.Service;

@Service
public class CustomerService {

    private static List&amp;lt;Customer&amp;gt; customers = new ArrayList&amp;lt;&amp;gt;();
    static {
        customers.add(new Customer(101, "Steve", "steve@apple.com", LocalDate.of(1955, 2, 24)));
        customers.add(new Customer(201, "Bill", "bill@microsoft.com", LocalDate.of(1955, 10, 28)));
        customers.add(new Customer(301, "Larry", "larry@gmail.com", LocalDate.of(1973, 8, 21)));
        customers.add(new Customer(401, "Sergey", "sergey@abc.xyz", LocalDate.of(1973, 3, 26)));
    }

    public List&amp;lt;Customer&amp;gt; findAll() {
        return customers;
    }

    public void add(Customer customer) {
        customer.setCustomerId(generateRandomId());
        customers.add(customer);
    }

    private int generateRandomId() {
        return new Random().nextInt(1000);
    }

    public List&amp;lt;Customer&amp;gt; remove(int customerId) {
        customers.removeIf(c -&amp;gt; c.getCustomerId() == customerId);
        return findAll();
    }

    public Optional&amp;lt;Customer&amp;gt; find(int customerId) {
        return customers.stream().filter(c -&amp;gt; c.getCustomerId() == customerId).findFirst();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  FreeMarker Template or .ftl file
&lt;/h2&gt;

&lt;p&gt;Finally let us create the freemarker template file to render our view. Create index.ftl file under src/resources folder. This view will render list of customers and a form to add new customer. Note we are using freemarker templates tags &lt;code&gt;&amp;lt;#list&amp;gt;&lt;/code&gt; to loop through customers and render them onto our view.&lt;/p&gt;

&lt;p&gt;index.ftl&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;title&amp;gt;Spring Boot FreeMarker example - viralpatel.net&amp;lt;/title&amp;gt;

&amp;lt;link href="/bootstrap/4.0.0-beta/css/bootstrap.min.css"
    rel="stylesheet"&amp;gt;
&amp;lt;style&amp;gt;
.container {
    margin-top: 80px;
}
.bg-dark {
    background-color: #3b8dbd !important;
}
&amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top"&amp;gt;
        &amp;lt;a class="navbar-brand" href="https://www.viralpatel.net"&amp;gt;Spring Boot
            FreeMarker example - viralpatel.net&amp;lt;/a&amp;gt;
        &amp;lt;button class="navbar-toggler" type="button" data-toggle="collapse"
            data-target="#navbarsExampleDefault"
            aria-controls="navbarsExampleDefault" aria-expanded="false"
            aria-label="Toggle navigation"&amp;gt;
            &amp;lt;span class="navbar-toggler-icon"&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;/button&amp;gt;
    &amp;lt;/nav&amp;gt;
    &amp;lt;div class="container"&amp;gt;

        &amp;lt;form class="form-inline" method="post" action="/add"&amp;gt;
            &amp;lt;input
                type="text" class="form-control mb-2 mr-sm-2 mb-sm-0"
                id="customerName" name="customerName" placeholder="Customer name" /&amp;gt;
            &amp;lt;input
                type="text" class="form-control mb-2 mr-sm-2 mb-sm-0" id="email"
                placeholder="Email" name="email" /&amp;gt; 


            &amp;lt;input type="date"
                 class="form-control mb-2 mr-sm-2 mb-sm-0" id="dateOfBirth"
                placeholder="Birthdate" name="dateOfBirth" /&amp;gt;
            &amp;lt;button type="submit" class="btn btn-primary"&amp;gt;Add&amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
        &amp;lt;br/&amp;gt;
        &amp;lt;table class="table"&amp;gt;
            &amp;lt;thead&amp;gt;
                &amp;lt;tr&amp;gt;
                    &amp;lt;th&amp;gt;#&amp;lt;/th&amp;gt;
                    &amp;lt;th&amp;gt;Customer name&amp;lt;/th&amp;gt;
                    &amp;lt;th&amp;gt;Email&amp;lt;/th&amp;gt;
                    &amp;lt;th&amp;gt;Birthdate&amp;lt;/th&amp;gt;
                    &amp;lt;th&amp;gt;&amp;lt;/th&amp;gt;
                &amp;lt;/tr&amp;gt;
            &amp;lt;/thead&amp;gt;
            &amp;lt;tbody&amp;gt;
                &amp;lt;#list model["customers"] as customer&amp;gt;
                &amp;lt;tr&amp;gt;
                    &amp;lt;th scope="row"&amp;gt;${customer.customerId}&amp;lt;/th&amp;gt;
                    &amp;lt;td&amp;gt;${customer.customerName}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;${customer.email}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;${customer.dateOfBirth}&amp;lt;/td&amp;gt;
                    &amp;lt;td&amp;gt;&amp;lt;a class="btn btn-sm btn-warning" role="button"
                        href="/delete/${customer.customerId}"&amp;gt;Delete&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt;
                &amp;lt;/tr&amp;gt;
                &amp;lt;/#list&amp;gt;
            &amp;lt;/tbody&amp;gt;
        &amp;lt;/table&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That’s all folks
&lt;/h2&gt;

&lt;p&gt;Run the Spring Boot Freemarker example project by running Spring Boot Application class as Java class or using maven &lt;code&gt;.\mvnw.cmd spring-boot:run&lt;/code&gt; command in Windows or &lt;code&gt;./mvnw spring-boot:run&lt;/code&gt; in Mac and Linux. Once the application starts, launch the browser and open: &lt;code&gt;http://localhost:8080/&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp4u9xdwtt7e2otcdlog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp4u9xdwtt7e2otcdlog.png" alt="spring boot freemarker tutorial example demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Download Source Code – Spring Boot FreeMarker example
&lt;/h2&gt;

&lt;p&gt;Source code of this Spring Boot FreeMarker Hello World tutorial is available on Github.&lt;/p&gt;

&lt;p&gt;Github – &lt;a href="https://github.com/viralpatel/spring-boot-tutorials/tree/master/spring-boot-freemarker-example" rel="noopener noreferrer"&gt;spring-boot-freemarker-example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Also read:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.viralpatel.net/introduction-to-freemarker-template-ftl/" rel="noopener noreferrer"&gt;Getting started with Freemarker&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.viralpatel.net/spring-boot-jsp-hello-world-example/" rel="noopener noreferrer"&gt;Spring Boot – Getting started&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>spring</category>
      <category>springboot</category>
      <category>freemarker</category>
      <category>springmvc</category>
    </item>
  </channel>
</rss>
