Spring Boot and FreeMarker

16,790

Solution 1

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.

Solution 2

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

Share:
16,790

Related videos on Youtube

Hugh Lacey
Author by

Hugh Lacey

Updated on September 14, 2022

Comments

  • Hugh Lacey
    Hugh Lacey almost 2 years

    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> 
    
  • Hugh Lacey
    Hugh Lacey almost 9 years
    Thanks! that was it... changed now and working fine. Well spotted.