Fork me on GitHub

Spring Integration

Integration with Spring

Example

There is a fully working example project located on github which can be used as a reference. It is a very simple and bare-bones project designed to only portray the basics. To build the project, simply run mvn install and then deploy the resulting war file to a an application container.

Setup

Pebble has integration for both versions 3.x, 4.x and 5.x of the Spring Framework, provided by three separate libraries called pebble-spring3, pebble-spring4 and pebble-spring5.

First of all, make sure your project includes the pebble-spring3, pebble-spring4 or pebble-spring5 dependency. This will provide the necessary ViewResolver and View classes.

<dependency>
	<groupId>io.pebbletemplates</groupId>
	<artifactId>pebble-spring{version}</artifactId>
	<version>3.0.6</version>
</dependency>

Secondly, make sure your templates are on the classpath (ex. /WEB-INF/templates/). Now you want to define a PebbleEngine bean and a PebbleViewResolver in your configuration.

@Configuration
@ComponentScan(basePackages = { "com.example.controller", "com.example.service" })
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private ServletContext servletContext;

    @Bean
    public Loader templateLoader(){
        return new ServletLoader(servletContext);
    }
    
    @Bean
    public SpringExtension springExtension() {
        return new SpringExtension();
    }

    @Bean 
    public PebbleEngine pebbleEngine() {
         return new PebbleEngine.Builder()
                .loader(this.templateLoader())
                .extension(springExtension())
                .build();
    }

    @Bean
    public ViewResolver viewResolver() {
        PebbleViewResolver viewResolver = new PebbleViewResolver();
        viewResolver.setPrefix("/WEB-INF/templates/");
        viewResolver.setSuffix(".html");
        viewResolver.setPebbleEngine(pebbleEngine());
        return viewResolver;
    }

}

Now the methods in your @Controller annotated classes can simply return the name of the template as you normally would if using JSPs:

@Controller
@RequestMapping(value = "/profile")
public class ProfileController {

	@Autowired
	private UserService userService;

	@RequestMapping
	public ModelAndView getUserProfile(@RequestParam("id") long id) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("user", userService.getUser(id));
		mav.setViewName("profile");
		return mav;
	}

}

The above example will render \WEB-INF\templates\profile.html and the "user" object will be available in the evaluation context.

Features

Access to Spring beans

Spring beans are now available to the template.

{{ beans.beanName }}

Access to http request

HttpServletRequest object is available to the template.

{{ request.contextPath }}

Access to http response

HttpServletResponse is available to the template.

{{ response.contentType }}

Access to http session

HttpSession is available to the template.

{{ session.maxInactiveInterval }}

Spring extension

This extension has many functions for spring validation and the use of message bundle.

Href function

Function to automatically add the context path to a given url

<a href="{{ href('/foobar') }}">Example</a>

Message function

It achieves the same thing as the i18n function, but instead, it uses the configured spring messageSource, typically the ResourceBundleMessageSource.

Label = {{ message('label.test') }}
Label with params = {{ message('label.test.params', 'params1', 'params2') }}

Spring validations and error messages

6 validations methods and error messages are exposed using spring BindingResult. It needs as a parameter the form name and for a particular field, the field name.

To check if there's any error:

{{ hasErrors('formName' }}

{{ hasGlobalErrors('formName' }}

{{ hasFieldErrors('formName', 'fieldName' }}

To output any error:

{% for err in getAllErrors('formName') %}
    <p>{{ err }}</p>
{% endfor %}

{% for err in getGlobalErrors('formName') %}
    <p>{{ err }}</p>
{% endfor %}

{% for err in getFieldErrors('formName', 'fieldName') %}
    <p>{{ err }}</p>
{% endfor %}

Timer

A timer in PebbleView is available to output the time taken to process a template. Just add the following config to your log4j.xml

<Logger name="com.mitchellbosecke.pebble.spring.PebbleView.timer" level="DEBUG" additivity="false">
      <AppenderRef ref="STDOUT" />
</Logger>