Page tree
Skip to end of metadata
Go to start of metadata

Gradle Configuration 

Add the following to your build.gradle script 

repositories {
   // add our maven repository url to your repositories
   maven { url  "http://rabbytes.bintray.com/maven" }
   
}
 
dependencies {
    compile "com.rabbtor:rabbtor-web:1.0.0"
}

Note that, to use Rabbtor tags, you need to import the JSP api and implementation if your application server does not provide it.

 

Spring Beans Configuration

To use the MetaData API or just display data bound form labels as described here you only need to register two Rabbtor beans. Below is a sample SpringBoot application configuration.

import com.rabbtor.model.DefaultModelMetadataAccessorFactory
import com.rabbtor.model.DefaultModelMetadataRegistry
import com.rabbtor.model.ModelMetadataAccessorFactory
import com.rabbtor.model.ModelMetadataRegistry
import com.rabbtor.validation.RabbtorOptionalValidatorFactoryBean
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.validation.Validator

@SpringBootApplication
class Application
{
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    

    @Bean
    ModelMetadataAccessorFactory modelMetadataAccessorFactory() {
        DefaultModelMetadataAccessorFactory factory = new DefaultModelMetadataAccessorFactory()
        factory.setModelMetadataRegistry(modelMetadataRegistry())
        return factory
    }

    

    @Bean
    ModelMetadataRegistry modelMetadataRegistry() {
        return new DefaultModelMetadataRegistry()
    }
}

 

If you also want property display names to be displayed correctly in JSR 303 validation errors, you need to change the default validator with RabbtorValidatorFactoryBean. To achieve this, you extend  WebMvcConfigurerAdapter#getValidator method. 

By default, Spring framework registers its OptionalValidatorFactoryBean if you use @EnableWebMvc annotation or Spring boot web mvc auto configuration. 

So you need to override it with Rabbtor's corresponding bean. 

Below is an example using the above class but this time, extending WebMvcConfigurerAdapter

import com.rabbtor.model.DefaultModelMetadataAccessorFactory
import com.rabbtor.model.DefaultModelMetadataRegistry
import com.rabbtor.model.ModelMetadataAccessorFactory
import com.rabbtor.model.ModelMetadataRegistry
import com.rabbtor.validation.RabbtorOptionalValidatorFactoryBean
import org.springframework.boot.SpringApplication
import org.springframework.boot.autoconfigure.EnableAutoConfiguration
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.validation.Validator
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
 
@SpringBootApplication
class Application extends WebMvcConfigurerAdapter
{
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    ModelMetadataAccessorFactory modelMetadataAccessorFactory() {
        DefaultModelMetadataAccessorFactory factory = new DefaultModelMetadataAccessorFactory()
        factory.setModelMetadataRegistry(modelMetadataRegistry())
        return factory
    }

    @Override
    Validator getValidator() {
        RabbtorOptionalValidatorFactoryBean validatorFactoryBean =  new RabbtorOptionalValidatorFactoryBean()
        validatorFactoryBean.setModelMetadataAccessorFactory(modelMetadataAccessorFactory())
        return validatorFactoryBean
    }

    @Bean
    ModelMetadataRegistry modelMetadataRegistry() {
        return new DefaultModelMetadataRegistry()
    }
}

Note that, you need to import Hibernate validator in your gradle script to use annotated model validation.

Configuration for the Web Data Binder Binding Errors

All previous examples show how model metadata is used when generating configurable labels for model properties in JSR 303 validation errors. However, this is not the only way our model objects are validated. Another place where validation of model objects occur is during data binding. Most common errors we see is type mismatch errors which occur when the input data can not be converted to the model property's data type. 

For instance, if you try to send a non-date String for a Date field, Spring generates a few "typeMismatch" error codes for the model property and adds them to your Errors (or BindingResult) object. Here, as we discussed earlier in this chapter, Spring does not generate useful label message codes for the bound property.

For Model Metadata aware binding error labels, Rabbtor provides the MetadataAwareBindingErrorProcessor class. This class is an extension of the Spring's DefaultBindingErrorProcessor class. To make use of this class, you should set it to the data binder using the @InitBinder annotation.

Below example injects a ModelMetadataAccessorFactory to our controller and customizes the WebDataBinder to use our binding error processor instead of the default one provided by Spring. 

 

@Controller 
public class MyController {
	@Autowired
	ModelMetadataAccessorFactory modelMetadataAccessorFactory;

	@InitBinder
	public void binder(WebDataBinder binder) {
    		binder.setBindingErrorProcessor( new MetadataAwareBindingErrorProcessor(modelMetadataAccessorFactory));
	}
}

If you want all your controllers to support this feature, you can do this configuration in a controller advice class which should be annotated with @ControllerAdvice as shown in the next example:

@ControllerAdvice
public class GlobalInitBinder
{
    @Autowired
    ModelMetadataAccessorFactory modelMetadataAccessorFactory;

    @InitBinder
    public void binder(WebDataBinder binder) {
        binder.setBindingErrorProcessor( new MetadataAwareBindingErrorProcessor(modelMetadataAccessorFactory));
    }
}
  • No labels