Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot and FreeMarker

I'm trying to work through a simple example of Spring Boot and FreeMarker integration (based on tutorials I've found on the web). For some reason my view is not being resolved to the FreeMarker template (I think that's the issue).

The result when launched in a browser is simply to return the name of the TFL view file i.e. "index". So the controller is being called and returning the string "index", but there seems to be no trigger to pull in the FTL file itself. Any help would be appreciated...

I have the following configuration class where I define the view resolver and the Free Maker config.

@Configuration
public class MvcConfigurer extends WebMvcConfigurerAdapter {
    @Bean
    public ViewResolver viewResolver() {
        FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
        resolver.setCache(true);
        resolver.setPrefix("");
        resolver.setSuffix(".ftl");
        resolver.setContentType("text/html; charset=UTF-8");
        return resolver;
    }

    @Bean
    public FreeMarkerConfigurer freemarkerConfig() throws IOException, TemplateException {
        FreeMarkerConfigurationFactory factory = new FreeMarkerConfigurationFactory();
        factory.setTemplateLoaderPaths("classpath:templates", "src/main/resource/templates");
        factory.setDefaultEncoding("UTF-8");
        FreeMarkerConfigurer result = new FreeMarkerConfigurer();
        result.setConfiguration(factory.createConfiguration());
        return result;
    }
}

Then I have the following controller:

@RestController
public class HelloController {

    /**
     * Static list of users to simulate Database
     */
    private static List<User> userList = new ArrayList<User>();

    //Initialize the list with some data for index screen
    static {
        userList.add(new User("Bill", "Gates"));
        userList.add(new User("Steve", "Jobs"));
        userList.add(new User("Larry", "Page"));
        userList.add(new User("Sergey", "Brin"));
        userList.add(new User("Larry", "Ellison"));
    }

    /**
     * Saves the static list of users in model and renders it 
     * via freemarker template.
     * 
     * @param model 
     * @return The index view (FTL)
     */
    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public String index(@ModelAttribute("model") ModelMap model) {

        model.addAttribute("userList", userList);

        return "index";
    }

    /**
     * Add a new user into static user lists and display the 
     * same into FTL via redirect 
     * 
     * @param user
     * @return Redirect to /index page to display user list
     */
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(@ModelAttribute("user") User user) {

        if (null != user && null != user.getFirstname()
                && null != user.getLastname() && !user.getFirstname().isEmpty()
                && !user.getLastname().isEmpty()) {

            synchronized (userList) {
                userList.add(user);
            }
        }
        return "redirect:index.html";
    }
}

Then finally I have the following FTL file stored in "src/main/resource/templates"

<html>
<head><title>ViralPatel.net - FreeMarker Spring MVC Hello World</title>
<body>
<div id="header">
<H2>
    <a href="http://viralpatel.net"><img height="37" width="236" border="0px" src="http://viralpatel.net/blogs/wp-content/themes/vp/images/logo.png" align="left"/></a>
    FreeMarker Spring MVC Hello World
</H2>
</div>

<div id="content">

  <fieldset>
    <legend>Add User</legend>
  <form name="user" action="add.html" method="post">
    Firstname: <input type="text" name="firstname" /> <br/>
    Lastname: <input type="text" name="lastname" />   <br/>
    <input type="submit" value="   Save   " />
  </form>
  </fieldset>
  <br/>
  <table class="datatable">
    <tr>
        <th>Firstname</th>  <th>Lastname</th>
    </tr>
    <#list model["userList"] as user>
    <tr>
        <td>${user.firstname}</td> <td>${user.lastname}</td>
    </tr>
    </#list>
  </table>

</div>  
</body>
</html> 
like image 591
Hugh Lacey Avatar asked Jul 07 '15 09:07

Hugh Lacey


People also ask

What is spring boot FreeMarker?

FreeMarker is a server-side Java template engine for both web and standalone environments. Templates are written in the FreeMarker Template Language (FTL), which is a simple, specialized language. Note: Spring Boot recently changed the default extension from . ftl to .

What is FreeMarker used for?

Apache FreeMarker is a free Java-based template engine, originally focusing on dynamic web page generation with MVC software architecture. However, it is a general purpose template engine, with no dependency on servlets or HTTP or HTML, and is thus often used for generating source code, configuration files or e-mails.

Which is better FreeMarker or Thymeleaf?

In the pursuit of comparison between FreeMarker , Thymeleaf, Groovy and Mustache, FreeMarker has the upper hand in performance.

Is FreeMarker a programming language?

Templates are written in the FreeMarker Template Language (FTL), which is a simple, specialized language (not a full-blown programming language like PHP). Usually, a general-purpose programming language (like Java) is used to prepare the data (issue database queries, do business calculations).


2 Answers

The problem is that your controller has the wrong annotation. You should use @Controller instead of @RestController

@RestController is used to tell that the response sent from your controller should be sent to the browser, usually an object mapped to json. It is the same as adding @ResponseBody.

like image 125
Paulo Santos Avatar answered Dec 21 '22 07:12

Paulo Santos


Although you just got the answer. However, your post has two points.

Firstly, configure Freemarker template in Spring Boot quite easy. No need to use WebMvcConfigurerAdapter. You just need to place your properties on your class path with the content below

spring.freemarker.template-loader-path: /templates
spring.freemarker.suffix: .ftl

Secondly, @Controller is used to annotated classes as Spring MVC Controller. @RestController annotated classes are the same as @Controller but the @ResponseBody on the handler methods are implied. So you must use @Controller in your case.

Found this from the post Spring Boot FreeMarker Hello World Example

like image 42
David Pham Avatar answered Dec 21 '22 08:12

David Pham