Archive

Posts Tagged ‘validation’

XML validation with imported/included schemas

September 2nd, 2012 2 comments

Recently, I tried to help a teammate design a WSDL file. I gently drove him toward separating the interface itself in the WSDL file and domain objects in a XML Schema file. One thing leading to another, I also made him split this XSD into two separate files, one including another for design purposes. Alas, tests were already present, and they failed miserably after my refactoring, complaining about a type in the included file not being found. The situation was extremely unpleasant, not only because I looked a little foolish in front of one of my co-worker, but also because despite my best efforts, I couldn’t achieve validation.

I finally found the solution, and I hope to spread it as much as I can in order for other developers to stop loosing time regarding this issue. The root of the problem is that the Java XML validation API cannot resolved included XML schemas (and imported ones as well), period. However, it allows for registering a (crude) resolver that can provide the content of the included/imported XSD. So, the solution is to implement your own resolver and your own content holder (there’s none provided in the JDK 6).

  1. Create a “input” implementation. This class is responsible for holding the content of the resolved schema.
    public class LSInputImpl implements LSInput {
    
        private Reader characterStream;
        private InputStream byteStream;
        private String stringData;
        private String systemId;
        private String publicId;
        private String baseURI;
        private String encoding;
        private boolean certifiedText;
    
        // Getters and setters here
    }
  2. Create a resolver implementation. This one is based on the premise that the included/imported schemas lies at the root of the classpath, and is relatively simple. More complex implementations can provide for a variety of locations (filesystem, internet, etc.).
    public class ClasspathResourceResolver implements LSResourceResolver {
    
        @Override
        public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
    
            LSInputImpl input = new LSInputImpl();
    
            InputStream stream = getClass().getClassLoader().getResourceAsStream(systemId);
    
            input.setPublicId(publicId);
            input.setSystemId(systemId);
            input.setBaseURI(baseURI);
            input.setCharacterStream(new InputStreamReader(stream));
    
            return input;
        }
    }
  3. Finally, just set the resolver on the schema factory:
    SchemaFactory schemaFactory = SchemaFactory.newInstance(W3C_XML_SCHEMA_NS_URI);
    
    schemaFactory.setResourceResolver(new ClasspathResourceResolver());

These 3 steps will go a long way toward cleanly splitting your XML schemas.

Send to Kindle
Categories: Java Tags: ,

Bean validation and JSR 303

March 22nd, 2010 14 comments

In this article, I will show you how to use the new Bean Validation Framework aka JSR-303.

The legacy

Before getting the result that is JSR 303, aka the Bean Validation framework, there were two interesting attempts at validation framework. Each came from an end of the layers and focused on its scope.

Front-end validation

Struts was the framework to learn and use on the presentation layer in 2001-2002. Struts uses the MVC model and focus on Controllers, which are represented in Struts with Action.  Views are plain JSP and Struts uses ActionForm in order to pass data from Controllers to Views and vice-versa. In short, those are POJO that the framework uses to interact with the View.

As a presentation layer framework, Struts concern is validating user input. Action forms have a nifty method called validate(). The signature of this method is the following:

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)

The developer has to check whether the form is valid then fill the ActionErrors object (basically a List) if it’s not the case. Struts then redirects the flow to an error page (the input) if the ActionErrors object is not empty. Since manual checking is boring and error-prone, it may be a good idea to automate such validation. Even at that time, declarative validation was considered to be the thing.

This is the objective of Apache Commons Validator. Its configuration is made through XML. You specify:

  • the validators you have access to. There are some built-in but you can add your own
  • the associations between beans and validators: which beans will be validated by which rules

Though Struts tightly integrates Commons Validator, you can use the latter entirely separately. However, the last stable version (1.3.1) was released late 2006. The current developed version is 1.4 but the Maven site hasn’t been updated since early 2008. It is a bit left aside for my own tatse so I rule it out for my validation needs save when I am forced to use Struts.

In this case it is mandatory for me to use it since the Struts plugin knows how to use both XML configuration files to also produce JavaScript client-side validation.

Back-end validation

Previously, we saw that the first validation framework came from user input. At the other end of the specter, inserting/updating data does not require such validation since constraints are enforced in the database. For example, trying to insert a 50 characters length string into a VARCHAR(20) column will fail.

However, letting the database handle validation has two main drawbacks:

  • it has a performance cost since you need to connect to the database, send the request and handle the error
  • such error cannot be easily mapped to a Java exception and if possible, to a particular attribute in error

In the end, it is better to validate the domain model in the Java world, before sending data to the database. Such was the scope of Hibernate Validator. Whereas Commons Validator configuration is based on XML, Hibernate Validator is based on Java 5 annotations.

Even if Hibernate Validator was designed to validate the domain model, you could use it to validate any bean.

JSR 303 Bean Validation

Finally, JSR 303 came to fruitition. Two important facts: it is end-agnostic, meaning you can use it anywhere you like (front-end, back-end, even DTO if you follow this pattern) and its reference implementation is Hibernate Validator v4.

JSR 303 features include:

  • validation on two different levels: attribute or entire bean. That was not possible with Hibernate Validator (since it was database oriented) and only possible with much limitations with Commons Validator
  • i18n ready and message are parameterized
  • extensible with your own validators
  • configurable with annotations or XML. In the following, only the annotation configuration will be shown

In JSR 303, validation is the result of the interaction between:

  • the annotation itself. Some come with JSR 303, but you can build your own
  • the class that will validate the annotated bean

Simplest example

The simplest example possible consist of setting a not-null constraint on an attribute of a class. This is done simply so:

public class Person {

  private String firstName;

  @NotNull
  public String getFirstName() {

    return firstName;
  }

  // setter
}

Note that the @NotNull annotation can be placed on the attribute or on the getter (just like in JPA). If you use Hibernate, it can also use your JSR 303 annotations in order to create/update the database schema.

Now, in order to validate an instance of this bean, all you have to do is:

Set<ConstraintViolation<Person>> violations = validator.validate(person);

If the set is empty, the validation succeeded, it not, it failed: the principle is very similar to both previous frameworks.

Interestingly enough, the specs enforce that constraints be inherited. So, if a User class inherits from Person, its firstName attribute will have a not-null constraint too.

Constraints groups

On the presentation tier, it may happen that you have to use the same form bean in two different contexts, such as create and update. In both contexts you have different constraints. For example, when creating your profile, the username is mandatory. When updating, it cannot be changed so there’s no need to validate it.

Struts (and its faithful ally Commons Validator) solve this problem by associating the validation rules not with the Java class but with the mapping since its scope is the front-end. This is not possible when using annotations. In order to ease bean reuse, JSR 303 introduce constraint grouping. If you do not specify anything, like previously, your constraint is assigned to the default group, and, when validating, you do so in the default group.

You can also specify groups on a constraint like so:

public class Person {

  private String firstName;

  @NotNull(groups = DummyGroup)
  public String getFirstName() {

    return firstName;
  }

  // setter
}

So, this will validate:

Person person = new Person();

// Empty set
Set<Constraintviolation<Person>> violations = validator.validate(person);

This will also:

Person person = new Person();

// Empty set
Set<Constraintviolation<Person>> violations = validator.validate(person, Default.class);

And this won’t:

Person person = new Person();

// Size 1 set
Set<Constraintviolation<Person>> violations = validator.validate(person, DummyGroup.class);

Custom constraint

When done playing with the built-in constraints (and the Hibernate extensions), you will probably need to develop your own. It is very easy: constraints are annotations that are themselves annotated with @Constraint. Let’s create a constraint that check for uncapitalized strings:

@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = CapitalizedValidator.class)
public @interface Capitalized {

  String message() default "{ch.frankel.blog.validation.constraints.capitalized}";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};
}

The 3 elements are respectively for internationalization, grouping (see above) and passing meta-data. These are all mandatory: if not defined, the framework will not work! It is also possible to add more elements, for example to parameterize the validation: the @Min and @Max constraints use this.

Notice there’s nothing that prevents constraints from being applied to instances rather than attributes, this is defined by the @Target and is a design choice.

Next comes the validation class. It must implement ConstraintValidator<?,?>:

public class CapitalizedValidator implements ConstraintValidator<Capitalized, String> {

  public void initialize(Capitalized capitalized) {} 

  public boolean isValid(String value, ConstraintValidatorContext context) {

    return value == null || value.equals(WordUtils.capitalizeFully(value));
  }
}

That’s all! All you have to do now is annotate attributes with @Capitalized and validate instances with the framework. There’s no need to register the freshly created validator.

Constraints composition

It is encouraged to create simple constraints then compose them to create more complex validation rules. In order to do that, create a new constraint and annotate it with the constraints you want to compose. Let’s create a constraint that will validate that a String is neither null nor uncapitalized:

@NotNull
@Capitalized
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = {})
public @interface CapitalizedNotNull {

  String message() default "{ch.frankel.blog.validation.constraints.capitalized}";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};
}

Now, annotate your attributes with it and watch the magic happen!

Of course, if you want to prevent constraint composition, you’ll have to restrain the @Target values to exclude ANNOTATION_TYPE.

Conclusion

This article only brushed the surface of JSR 303. Nevertheless, I hoped it was a nice introduction to its features and gave you the desire to look into it further.

You can find here the sources (and more) for this article in Eclipse/Maven format.

To go further:

Send to Kindle
Categories: Java Tags: ,

Discover Spring authoring

December 29th, 2009 No comments

In this article, I will describe a useful but much underused feature of Spring, the definition of custom tags in the Spring beans definition files.

Spring namespaces

I will begin with a simple example taken from Spring’s documentation. Before version 2.0, only a single XML schema was available. So, in order to make a constant available as a bean, and thus inject it in other beans, you had to define the following:

<bean id="java.sql.Connection.TRANSACTION_SERIALIZABLE"
    class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean" />

Spring made it possible, but realize it’s only a trick to expose the constant as a bean. However, since Spring 2.0, the framework let you use the util namespace so that the previous example becomes:

<util:constant static-field="java.sql.Connection.TRANSACTION_SERIALIZABLE"/>

In fact, there are many namespaces now available:

Prefix Namespace Description
bean http://www.springframework.org/schema/bean Original bean schema
util http://www.springframework.org/schema/util Utilities: constants, property paths and collections
util http://www.springframework.org/schema/jee JNDI lookup
lang http://www.springframework.org/schema/lang Use of other languages
tx http://www.springframework.org/schema/tx Transactions
aop http://www.springframework.org/schema/aop AOP
context http://www.springframework.org/schema/context ApplicationContext manipulation

Each of these is meant to reduce verbosity and increase readibility like the first example showed.

Authoring

What is still unknown by many is that this feature is extensible that is Spring API provides you with the mean to write your own. In fact, many framework providers should take advantage of this and provide their own namespaces so that integrating thier product with Spring should be easier. Some already do: CXF with its many namespaces comes to mind but there should be others I don’t know of.

Creating you own namespace is a 4 steps process: 2 steps about the XML validation, the other two for creating the bean itself. In order to illustrate the process, I will use a simple example: I will create a schema for EhCache, the Hibernate’s default caching engine.

The underlying bean factory will be the existing EhCacheFactoryBean. As such, it won’t be as useful as a real feature but it will let us focus on the true authoring plumbing rather than EhCache implementation details.

Creating the schema

Creating the schema is about describing XML syntax and more importantly restrictions. I want my XML to look something like the following:

<ehcache:cache id="myCache" eternal="true" cacheName="foo"
maxElementsInMemory="5" maxElementsOnDisk="2" overflowToDisk="false"
diskExpiryThreadIntervalSeconds="18" diskPersistent="true" timeToIdle="25" timeToLive="50"
memoryStoreEvictionPolicy="FIFO">
  <ehcache:manager ref="someManagerRef" />
</ehcache:echcache>

Since I won’t presume to teach anyone about XML, here’s the schema. Just notice the namespace declaration:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  targetNamespace="http://blog.frankel.ch/spring/ehcache" xmlns="http://blog.frankel.ch/spring/ehcache"
  elementFormDefault="qualified">
  <xsd:complexType name="cacheType">
    <xsd:sequence maxOccurs="1" minOccurs="0">
      <xsd:element name="manager" type="managerType" />
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:string" />
    <xsd:attribute name="cacheName" type="xsd:string" />
    <xsd:attribute name="diskExpiryThreadIntervalSeconds" type="xsd:int" />
    <xsd:attribute name="diskPersistent" type="xsd:boolean" />
    <xsd:attribute name="eternal" type="xsd:boolean" />
    <xsd:attribute name="maxElementsInMemory" type="xsd:int" />
    <xsd:attribute name="maxElementsOnDisk" type="xsd:int" />
    <xsd:attribute name="overflowToDisk" type="xsd:boolean" />
    <xsd:attribute name="timeToLive" type="xsd:int" />
    <xsd:attribute name="timeToIdle" type="xsd:int" />
    <xsd:attribute name="memoryStoreEvictionPolicy" type="memoryStoreEvictionPolicyType" />
  </xsd:complexType>
  <xsd:simpleType name="memoryStoreEvictionPolicyType">
    <xsd:restriction base="xsd:string">
      <xsd:enumeration value="LRU" />
      <xsd:enumeration value="LFU" />
      <xsd:enumeration value="FIFO" />
    </xsd:restriction>
  </xsd:simpleType>
  <xsd:complexType name="managerType">
    <xsd:attribute name="ref" type="xsd:string" />
  </xsd:complexType>
  <xsd:element name="cache" type="cacheType" />
</xsd:schema>

And for those, like me, that prefer a graphic display:

Mapping the schema

The schema creation is only the first part. Now, we have to make Spring aware of it. Create the file META-INF/spring.schemas and write in the following line is enough:

http\://blog.frankel.ch/spring/schema/custom.xsd=ch/frankel/blog/spring/authoring/custom.xsd

Just take care to insert the backslash, otherwise it won’t work. It maps the schema declaration in the XML to the real file that will be used from the jar!

Before going further, and for the more curious, just notice that in spring-beans.jar (v3.0), there’s such a file. Here is it’s content:

http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/beans/spring-beans.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.0.xsd=org/springframework/beans/factory/xml/spring-tool-2.0.xsd
http\://www.springframework.org/schema/tool/spring-tool-2.5.xsd=org/springframework/beans/factory/xml/spring-tool-2.5.xsd
http\://www.springframework.org/schema/tool/spring-tool-3.0.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/tool/spring-tool.xsd=org/springframework/beans/factory/xml/spring-tool-3.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.0.xsd=org/springframework/beans/factory/xml/spring-util-2.0.xsd
http\://www.springframework.org/schema/util/spring-util-2.5.xsd=org/springframework/beans/factory/xml/spring-util-2.5.xsd
http\://www.springframework.org/schema/util/spring-util-3.0.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd
http\://www.springframework.org/schema/util/spring-util.xsd=org/springframework/beans/factory/xml/spring-util-3.0.xsd

It brings some remarks:

  • Spring eat their own dogfood (that’s nice to know)
  • I didn’t look into the code but I think that’s why XML validation of Spring’s bean files never complain about not finding the schema over the Internet (a real pain in production environment because of firewall security issues). That’s because the XSD are looked inside the jar
  • If you don’t specify the version of the Spring schema you use (2.0, 2.5, 3.0, etc.), Spring will automatically upgrade it for you with each major/minor version of the jar. If you want this behaviour, fine, if not, you’ll have to specify version

Creating the parser

The previous steps are only meant to validate the XML so that the eternal attribute will take a boolean value, for example. We still did not wire our namespace into Spring factory. This is the goal of this step.

The first thing to do is create a class that implement org.springframework.beans.factory.xml.BeanDefinitionParser. Looking at its hierarchy, it seems that the org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser is a good entry point since:

  • the XML is not overly complex
  • there will be a single bean definition

Here’s the code:

public class EhCacheBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser {

  private static final List&amp;amp;amp;amp;amp;amp;lt;String&amp;amp;amp;amp;amp;amp;gt; PROP_TAG_NAMES;

  static {

  PROP_TAG_NAMES = new ArrayList();

    PROP_TAG_NAMES.add("eternal");
    PROP_TAG_NAMES.add("cacheName");
    PROP_TAG_NAMES.add("maxElementsInMemory");
    PROP_TAG_NAMES.add("maxElementsOnDisk");
    PROP_TAG_NAMES.add("overflowToDisk");
    PROP_TAG_NAMES.add("diskExpiryThreadIntervalSeconds");
    PROP_TAG_NAMES.add("diskPersistent");
    PROP_TAG_NAMES.add("timeToLive");
    PROP_TAG_NAMES.add("timeToIdle");
  }

  @Override
  protected Class getBeanClass(Element element) {

    return EhCacheFactoryBean.class;
  }

  @Override
  protected boolean shouldGenerateIdAsFallback() {

    return true;
  }

  @Override
  protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {

    for (String name : PROP_TAG_NAMES) {

      String value = element.getAttribute(name);

      if (StringUtils.hasText(value)) {

        builder.addPropertyValue(name, value);
      }
    }

    NodeList nodes = element.getElementsByTagNameNS("http://blog.frankel.ch/spring/ehcache", "manager");

    if (nodes.getLength() &amp;amp;amp;amp;amp;amp;gt; 0) {

      builder.addPropertyReference("cacheManager",
        nodes.item(0).getAttributes().getNamedItem("ref").getNodeValue());
    }

    String msep = element.getAttribute("memoryStoreEvictionPolicy");

    if (StringUtils.hasText(msep)) {

      MemoryStoreEvictionPolicy policy = MemoryStoreEvictionPolicy.fromString(msep);

      builder.addPropertyValue("memoryStoreEvictionPolicy", policy);
    }
  }
}

That deserves some explanations. The static block fills in what attributes are valid. The getBeanClass() method returns what class will be used, either directly as a bean or as a factory. The shouldGenerateIdAsFallback() method is used to tell Spring that when no id is supplied in the XML, it should generate one. That makes it possible to create pseudo-anonymous beans (no bean is really anonymous in the Spring factory).

The real magic happen in the doParse() method: it just adds every simple property it finds in the builder. There are two interesting properties though: cacheManager and memoryStoreEvictionPolicy.

The former, should it exist, is a reference on another bean. Therefore, it should be added to the builder not as a value but as a reference. Of course, the code doesn’t check if the developer declared the cache manager as an anonymous bean inside the ehcache but the schema validation took already care of that.

The latter just uses the string value to get the real object behind and add it as a property to the builder. Likewise, since the value was enumerated on the schema, exceptions caused by a bad syntax cannot happen.

Registering the parser

The last step is to register the parser in Spring. First, you just have to create a class that extends org.springframework.beans.factory.xml.NamespaceHandlerSupport and register the handler under the XML tag name in its init() method:

public class EhCacheNamespaceHandler extends NamespaceHandlerSupport {

  public void init() {

    registerBeanDefinitionParser("cache", new EhCacheBeanDefinitionParser());
  }
}

Should you have more parsers, just register them in the same method under each tag name.

Second, just map the formerly created namespace to the newly created handler in a file META-INF/spring.handlers:

http\://blog.frankel.ch/spring/ehcache=ch.frankel.blog.spring.authoring.ehcache.EhCacheNamespaceHandler

Notice that you map the declared schema file to the real schema but the namespace to the handler.

Conclusion

Now, when faced by overly verbose bean configuration, you have the option to use this nifty 4-steps techniques to simplify it. This technique is of course more oriented toward product providers but can be used by projects, provided the time taken to author a namespace is a real time gain over normal bean definitions.

You will find the sources for this article here in Maven/Eclipse format.

To go further

  • Spring authoring: version 2.0 is enough since nothing changed much (at all?) with following versions
  • Spring’s Javadoc relative to authoring
Send to Kindle