3
votes

If I understand the spirit of JSR-303 correctly, it is intended to allow the application of Bean (data) Validation at multiple layers of an application architecture.

Whilst I have seen some discussion around JPA / Hibernate applications of JSR-303, I am struggling to find whether there are any working implementations that may be applied to Web Services / JAXB unmarshalling (ie. closer to the presentation-layer).

Here is a fairly contrived example of something I would like to fail due to Bean Validation:

Square.class

@XmlAccessorType(XmlAccessType.PUBLIC_MEMBER)
@XmlRootElement(name = "square")
public class Square {

   @Size(min = 4, max = 4)
   private int numberOfSides;

   public void setNumberOfSides(int numSides) {
       this.numberOfSides = numSides;
   }

   public int getNumberOfSides() {
      return this.numberOfSides;
   }
}

Test class

@RunWith(JUnit4.class)
public class BeanValidationTest {

   @Test
   public void Should_not_unmarshal_invalid_numberOfSides_value() throws JAXBException    {
     String xml = "<square>" +
                 "  <numberOfSides>3</numberOfSides>" +
                 "</square>";

     JAXBContext context = org.eclipse.persistence.jaxb.JAXBContext.newInstance(Square.class);

     Unmarshaller unmarshaller = context.createUnmarshaller();

     Square result = (Square) unmarshaller.unmarshal(new StringReader(xml));

     assertThat(result.getNumberOfSides(), equalTo(4));
   }
}

NOTE: The test will fail due to the expected number of sides constraint, it fails with this:

java.lang.AssertionError: 
Expected: <4>
 but: was <3>

I would re-write to expect the Bean Validation exception, except that I do not know what to expect because Bean Validation does not fire.

My confusion is that I think that I should not even reach the assertion in the test above, and that the 3 value was successfully deserialised without either:

  1. Throwing an exception
  2. Ignoring the mapping because the property is invalid (I really hope JSR-303 implementations won't do this - that would be unexpected behaviour unless I explicitly ask for it)

So, in summary, I think that leaves me a choice of questions, either:

A. How do I instruct EclipseLink MOXy to apply Bean Validations, or should it at least warn me if it cannot find a JSR-303 implementation in the class path?

B. Or, is there another (better?) way to implement what I have asked for?

(assume that I know I can manually validate and/or implement an @XmlJavaTypeAdapter if necessary - they are just not my preferred elegant solutions)

Versions (if relevant):

  • Java 7
  • EclipseLink 2.5.2
2

2 Answers

2
votes

The only available solution for you is using MOXy version 2.6+ as JAXB provider. What you want will then be done automatically for you in default configuration (this BV support can be turned off). MOXy is currently tied to EclipseLink project, so you would have to use EclipseLink (it also implements JPA, SDO, JSON).

At the moment, there is version 2.6.0-M3 of EclipseLink available at: sonatype or maven.

Release is expected in Q1-2015.

1
votes

I think what you are asking for is coming with Eclipse Link 2.6.0. See also https://bugs.eclipse.org/bugs/show_bug.cgi?id=431803 and https://wiki.eclipse.org/EclipseLink/Development/2.6.0