JSR-380 defines a metadata model and API for Java Bean validation. It can be used an “architectural-agnostic” way and it is particularly useful when it comes to validating the RESTful APIs (syntactic validation).

The default metadata source is @Annotations, with the ability to override and extend the metadata through the use of XML validation descriptors or custom code:

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

// source: http://www.baeldung.com/javax-validation

publicclassUser{

@NotNull(message="Name cannot be null")

privateStringname;

@AssertTrue

privatebooleanworking;

@Size(min=10,max=200,message="About Me must be between 10 and 200 characters")

privateStringaboutMe;

@Min(value=18,message="Age should not be less than 18")

@Max(value=150,message="Age should not be greater than 150")

privateintage;

@Email(message="Email should be valid")

privateStringemail;

// standard setters and getters

}

JSR-380 was finished in August, 2017 and it’s now a Java EE 8 standard. It’s also included by default in Spring Boot through the only available implementation – Hibernate Validator.

By default, JSR-380 doesn’t standardise a big list of validating @Annotations. Hibernate Validator adds a few extra, and enhances the existing ones, but it’s still not enough. As a developer working for a real world application you will probably need to write custom constraints.

That’s why i’ve compiled myself a library of common annotations (that are not in the standard or in Hibernate Validator). The library and code can be found on github under the name JBVExt (Java Bean Validation Extensions).

The project setup

The “example” project is a simple Spring Boot project. The main dependencies are:

1

2

3

4

5

dependencies{

compile("org.springframework.boot:spring-boot-starter-web")

compile'net.andreinc.jbvext:jbvext:0.0.6'

compileOnly('org.projectlombok:lombok')

}

By default the spring-boot-starter-web includes Hibernate Validator, so there’s no need to explicitly define it as a dependency.

Decorating the RESTful API

The API we are going to validate is composed by two REST web-services:

So instead of having to repeat all the try/catch code in each controller, we can define this unified strategy in a separate class, that will threat each exception (of type BeanValidationException) in the same way.

Running the code

The code is available on git:

1

git clonehttps://github.com/nomemory/spring-boot-jbvext-example

The Spring Boot application will run by default on port 8080.

If we try to POST http://localhost:8080 with an invalid bodyRequest (as described by the JSR380 validation):

RAFs, Random Access Files permit asynchronous (random) access to a file contents. To access a file randomly we open the file, seek a particular position, and then we read or write to that file.

Java NIO.2 introduces a new interface – SeekableByteChannel for working with Random Access Files. Also improves the well-known FileChannel class by implementing this interface.

Before we start to talk about about FileChannel and SeekableByteChannel it is advisable to first talk a little bit about ByteBuffers and Channels.

ByteBuffers

A byte-buffer is an in-memory array of bytes. It usually contains data that was recently read, or that will be written from/to a destination.

A buffer has three important properties:

The buffer’s capacity represents the “maximum amount of information” that can be stored in the buffer.

The buffer’s position represents how much data has been read or written. The position is an index in the buffer’s array, and cannot have a negative value or a value bigger than the buffer’s capacity.

The buffer’s limit is the difference between buffer’s capacity and the buffer’s position.

Channels

Channels are in a way similar with the classical I/O streams, the difference is that while streams are one-way directed (read or write), channels can support both operations in the same time. Also Channels allow you to write and read asynchronously.

StandardWatchEventKinds.ENTRY_MODIFY: This event is pretty-platform dependent. Usually is triggered when the contents of a file is modified. But on some file systems it can also trigger when the attributes of that particular file are modified.

Putting all the code togheter

Please take in consideration that in our particular case we are only going to watch the Home folder, and not the whole sub-tree of folders. If you wish to watch the whole sub-tree for modifications you will need to register a watch service for every folder in the tree.

visitFile(): The method is invoked for a file. The method should return a FileVisitResult.CONTINUE result or a FileVisitResult.TERMINATE result. The method receive a reference to the file (a Path object) and to the BasicFileAttributes object associated with the Path.

preVisitDirectory(): This method is invoked for a directory before visiting its children. The method returns FileVisitResult.CONTINUE if we want it’s children to be visited or FileVisitResult.SKIP_SUBTREE if we want the process to stop. If we want to skip visiting the siblings of the directory we need to return FileVisitResult.SKIP_SIBLINGS .

postVisitDirectory(): This method is invoked after we visit all the children of a directory (including other folders and their descendants).

visitFileFailed(): This method is invoked if a file (or folder) cannot be accessed.

In practice it is also possible to use the SimpleFileVisitor class if we want to traverse only the directories.