Friday, December 16, 2016

Creating the Persistence Configuration

To use the entities you create, you must define a persistence unit. Doing so is simple. Create a persistence.xml file not dissimilar from a deployment descriptor, but with far fewer options to worry about. The root element of a persistence configuration file is <persistence>. This element may contain one or more <persistence-unit> elements. No other elements are within <persistence>. <persistence-unit> has two attributes: name specifies the name of the persistence unit and transaction-type indicates whether this persistence unit uses Java Transaction API (JTA) transactions or standard local transactions.
You must specify a name, which is how you locate the persistence unit in code. If not specified, transaction-type defaults to JTA in a Java EE application server and RESOURCE_LOCAL in a Java SE environment or simple Servlet container. However, to prevent unexpected behavior it’s best to always set this value explicitly instead of relying on a default value.
<persistence-unit> contains the following inner elements. None of them are required (so <persistence-unit> may be empty); however, you must specify whichever elements you use in the following order:

- <description> contains a useful description for this persistence unit. Although it makes reading the persistence file easier, it has no semantic value.

- <provider> specifies the fully qualified class name of the javax.persistence.spi.PersistenceProvider implementation used for this persistence unit. By default, when you look up the persistence unit, the API will use the first JPA provider on the classpath. You can include this element to mandate a specific JPA provider.

- You can use either <jta-data-source> or <non-jta-data-source> (but not both) to use a JNDI DataSource resource. You may use <jta-data-source> only if transaction-type is JTA; likewise you may use <non-jta-data-source> only if transaction-type is RESOURCE_LOCAL. Specifying a DataSource causes the persistence unit to use that DataSource for all entity operations.

- <mapping-file> specifies the classpath-relative path to an XML mapping file. If you don’t specify any <mapping-file>, the provider looks for orm.xml. You may specify multiple <mapping-file> elements to use multiple mapping files.

- You can use one or more <jar-file> elements to specify a JAR file or JAR files that the JPA provider should scan for mapping-annotated entities. Any @Entity, @Embeddable, @javax.persistence.MappedSuperclass, or @javax.persistence.Converter classes found are added to the persistence unit.

- You can use one or more <class> elements to indicate specific @Entity, @Embeddable, @MappedSuperclass, or @Converter classes that should be added to the persistence unit. You must annotate the class or classes with JPA annotations.

- Using <exclude-unlisted-classes /> or <exclude-unlisted-classes>true</ exclude-unlisted-classes> indicates that the provider should ignore classes not specified with <jar-file> or <class>. Omitting <exclude-unlisted-classes> or using <exclude-unlisted-classes>false</exclude-unlisted-classes> causes the JPA provider to scan the classpath location of the persistence file for JPA-annotated classes. If persistence.xml is located in a JAR file, that JAR file (and only that JAR file) is scanned for classes. If persistence.xml is located in a directory-based classpath location (such as /WEB-INF/classes), that directory (and only that directory) is scanned for classes. Prior to Hibernate 4.3.0 and Spring Framework 3.2.5, specifying this element with the value false was incorrectly interpreted as true.

- <shared-cache-mode> indicates how entities are cached in the persistence unit (if the JPA provider supports caching, which is optional). NONE disables caching, whereas ALL enables caching for all entities. ENABLE_SELECTIVE means that only entities annotated @javax.persistence.Cacheable or @Cacheable(true) (or marked as cacheable in orm.xml) are cached. DISABLE_SELECTIVE results in caching of all entities except those annotated @Cacheable(false) (or marked as non-cacheable in orm.xml). The default value, UNSPECIFIED, means that the JPA provider decides what the effective default is. Hibernate ORM defaults to ENABLE_SELECTIVE, but relying on this is not portable.

- <validation-mode> indicates if and how Bean Validation should be applied to entities. NONE means that Bean Validation is not enabled, whereas CALLBACK makes the provider validate all entities on insert, update, and delete. AUTO has an effective value of CALLBACK if a Bean Validation provider exists on the classpath and an effective value of NONE if no Bean Validation provider exists on the classpath. If you enable validation, the JPA provider configures a new Validator to validate your entities. If you have configured a special Spring Framework Validator with your custom localized error codes, the JPA provider ignores it. As such, it’s best to set the validation mode to NONE and use Bean Validation before your persistence layer is invoked.

- <properties> provides a way to specify other JPA properties, including standard JPA properties (such as JDBC connection string, username, and password, or schema generation settings) as well as provider-specific properties (such as Hibernate settings). You specify one or more properties using nested <property> elements, each with a name and value attribute.

Wednesday, December 14, 2016

Creating a Connection Resource in Tomcat

MySQL, like most other relational database vendors, supplies a JDBC driver for connecting to MySQL databases from Java. You need to download this driver (a JAR file) and place it in your Tomcat installation so that you can use it from your applications. This may strike you as odd because other JAR files you use are simply packaged with your applications in /WEB-INF/lib. You must never do this with a JDBC driver for two reasons:

- Most important, doing so can cause a memory leak. JDBC drivers automatically register themselves with the java.sql.DriverManager, which is part of the Java SE core libraries. If your application includes a JDBC driver in /WEB-INF/lib, the DriverManager holds on to the driver classes forever, even if your application is undeployed. The application server then cannot fully undeploy your application, resulting in a memory leak.

- It’s a best practice to have the application server manage your JDBC DataSources. Application servers have built-in systems for managing connection pools, improving the performance of database connections in your applications. For the application server to be able to manage these connections, you must load the JDBC driver in the application server class loader instead of the web application class loader.

Installing the MySQL JDBC driver in Tomcat is extremely easy. On the MySQL download website locate the Connector/J product. This is the JDBC driver. It is platform-independent, so all you need to do is download the ZIP or TAR archive (whichever is easiest for you to use on your computer). Extract the JAR file from the archive, and copy it to C:\Program Files\Apache Software Foundation\Tomcat 8.0\lib (or the equivalent directory for your Tomcat installation).
That’s all there is to it. The next time Tomcat starts, the MySQL JDBC driver becomes available to all web applications.


Creating a Connection Resource in Tomcat


Creating a pooled connection DataSource in Tomcat is quite straightforward and takes only a few minutes. Instead of creating a brand new resource every time and having dozens of resources by the end, it is also acceptable to simply create one resource and change it every time you need to.

1. To create a connection resource, open C:\Program Files\Apache Software Foundation\Tomcat 8.0\conf\context.xml (or the equivalent in your Tomcat installation) in your favorite text editor.

2. Add the following <Resource> element between the beginning and end <Context> elements:
     <Resource name="jdbc/DataSourceName" type="javax.sql.DataSource"
          maxActive="20" maxIdle="5" maxWait="10000"
          username="mysqluser" password="mysqlpassword"
          driverClassName="com.mysql.jdbc.Driver"
          url="jdbc:mysql://localhost:3306/databaseName" />

3. For each example you must replace jdbc/DataSourceName with the appropriate data source name (which should always start with jdbc/) and databaseName with the correct database name. mysqluser and mysqlpassword should be replaced with the user and password that you previously created to access MySQL.

This <Resource> definition causes Tomcat to expose the connection pool DataSource as a JNDI resource so that it can be looked up via JNDI by any application.

Schema-less Database Systems

A schema-less database is, naturally, a database that lacks a strict schema. The term NoSQL, coined in 1998, is typically used to describe such databases. NoSQL databases solve a lot of problems not easily solved in relational databases, such as flexible fields and object inheritance. There are a number of different types of NoSQL databases, the most common of which are document-oriented databases.
Even though it lacks a strict structure, a document database encodes data in a consistent and well-known format, such as XML or JSON (or BSON, the compact, binary version of JSON). A document is roughly synonymous with a record in a relational database, and a collection is roughly synonymous with a table. Documents in a collection, though they must not adhere to a particular schema, are generally similar to each other. When two documents in a collection contain a property with the same name, best practices dictate that those properties are the same type and have the same semantic meaning.
Most document databases tend to have extremely fast insertion times, sometimes orders of magnitude better than relational databases. They are sometimes not quite as fast for indexed lookups as relational databases, but they can store data on much larger scales than can relational databases. Some document databases can store many hundreds of gigabytes or even terabytes of data without sacrificing insertion performance. This makes document databases ideal for storing logging- and auditing-related data. Some of the more popular document databases include MongoDB, Apache CouchDB, and Couchbase Server.
Another popular type of NoSQL database is a key-value store. It is much like it sounds, storing key-value pairs in a very flat manner. This can be likened to a Java Map<String, String>, though some key-value stores are multivalue and can store data more like a Map<String, List<String>>. Some popular key-value stores include Apache Cassandra, Freebase, Amazon DynamoDB, memcache, Redis, Apache River, Couchbase, and MongoDB. (Yes, some document databases double as key-value stores.)
Graph databases are NoSQL databases that focus on object relationships. In a graph database objects have attributes (properties), objects have relationships to other objects, and those relationships have attributes. Data is stored and represented as a graph, with relationships between entities existing naturally, not in the contrived manner created with foreign keys. This makes it easy, for example, to solve the degrees of separation problem, finding relationships between entities that might not have been realized at insertion time. Perhaps the most popular graph database is Neo4j. Though Neo4j is written in Java and despite its name, it can work on any platform. It is, however, very well suited for Java applications.
NoSQL databases do not operate on any type of standard like ANSI SQL. As such, there is no common way (like JDBC) to access any two NoSQL databases. This, of course, is a natural downside to using NoSQL databases, but there is an upside as well. Each NoSQL database comes with its own client library, and most of these client libraries can take Java objects and store them directly in the database in whatever format the database requires. This eliminates the task of mapping POJOs to “tables” and properties to “columns,” and thus makes NoSQL an attractive alternative to relational databases for entity storage.

Sunday, December 11, 2016

Understanding Distributable Java EE Applications

Strictly speaking, a Java EE web application is considered distributable as long as the <distributable/> tag is present in its deployment descriptor and in all /META-INF/web-fragment.xml descriptors in any JAR files packaged in its /WEB-INF/lib directory. If a JAR file does not contain a web-fragment.xml file, it is not considered a web fragment, so it doesn’t count. If a single JAR with a web-fragment.xml lacking <distributable/> is present in an application, or if the deployment descriptor is lacking <distributable/>, the application is considered non-distributable.
This doesn’t mean anything without understanding what, precisely, a distributable Java EE application is. The <distributable/> element indicates that the web application was written to deploy to multiple JVMs running on the same host or on different hosts. In almost all cases, this means that all attributes written to HttpSessions are Serializable. Containers are allowed to support non-Serializable session attributes in distributable applications, but they are not required to, and most simple Servlet containers do not. Tomcat, for example, throws an IllegalArgumentException if a <distributable/> application adds a non-Serializable attribute to a session. The point of using Serializable session attributes is that it permits HttpSessions to be shared among servers in a cluster, which is perhaps the most important reason for using <distributable/>. If two or more containers are configured to work in a cluster, they may share HttpSession data across the cluster only for distributable applications.


Understanding HTTP Sessions, Stickiness, and Serialization


Why would you want to have HttpSession data shared across servers in a cluster? The answer to that is quite simple and boils down to the reasons you use a cluster to begin with: scalability and availability. A single server cannot service an infinitely increasing number of users. When a server fails, you want your users transparently shuffled to other servers. Because the majority of applications interact with users using sessions, it’s important for that session data to be shareable across a cluster. This can serve two purposes:

- If a server fails, a user can be sent to a different server and that server will have all the same session data for the user that the failed server had.

- In an ideal world, consecutive user requests can be handled independently of which server receives the request, so a user’s requests can conceivably be handled on different servers every time without losing session information.

For either of these scenarios to work properly, you must make your session attributes Serializable. Because Java objects cannot live beyond the confines of a single Java Virtual Machine, HttpSessions must be serialized before being sent to other servers in the cluster whether over shared memory, a file system, or a network connection. This pattern presents two interesting challenges with solutions for both.
First, sometimes session attributes simply cannot be 100 percent Serializable. This is especially true for legacy applications that are upgraded and refactored. For example, a session attribute may (for whatever reason, however bad) hold on to a database connection or open file handle. These attributes obviously cannot be serialized and shared across the cluster or can they? The javax.servlet.http.HttpSessionActivationListener interface specifies a special type of attribute that knows when it is about to be serialized and sent to other servers in a cluster or has just been deserialized on a server. Any session attribute that implements this interface is notified when it is about to be sent to other servers (via the sessionWillPassivate method) and when it has just been received from another server (via the sessionDidActivate method). In the aforementioned examples, a session attribute could re-open a database connection marked transient in sessionDidActivate.
A more common problem with clustered sessions is performance. For complete server independence to be possible, the server must serialize and share an HttpSession every time you update a session attribute as well as on every request (so that the lastAccessTime property stays up-to-date). This can present a real performance issue in some cases. (Although it still has a net benefit over using only one server.)
For this reason and others, the concept of session stickiness is an important consideration whenever you deploy a distributable application. How session stickiness is configured varies from one container and load balancer to the next, but the concept is the same: Within a single session, all that session’s requests are handled in the same JVM. Sessions are serialized and shared across the cluster only periodically, as often as is practical by the performance standards set by the deployment team.
Sharing sessions less often can cause problems: Imagine having added several items to your shopping cart, and on the next request, the items are no longer in your shopping cart. With sticky sessions, you are always sent to the same server unless your session ends or the server fails, and the problem of session state inconsistency is mitigated. This is not without its downside. Server failures are not predictable, and sessions are rarely left in a consistent state when a failure occurs. When possible, it is always best to maintain session state across the cluster every time a session is updated.

Using Spring Framework’s Application Events and Listeners

Without any special configuration, Spring Framework automatically acts as a message broker in a pub/sub environment. To publish messages, you call the publishEvent method on an instance of org.springframework.context.ApplicationEventPublisher and pass it an instance of org.springframework.context.ApplicationEvent. You can obtain an ApplicationEventPublisher in a Spring-managed bean either through dependency injection or by implementing org.springframework.context.ApplicationEventPublisherAware. With an ApplicationEventPublisher instance, you can publish as many events as you want as often as you need to.
Subscribing to events is equally easy. Given an event FooEvent extends ApplicationEvent, a Spring bean needs only to implement org.springframework.context.ApplicationListener<FooEvent> to subscribe to FooEvent messages. To subscribe to BarEvent, implement ApplicationListener<BarEvent>. You can create and subscribe to a hierarchy of events, too. For example, consider the following event definitions:

public class TopEvent extends ApplicationEvent { }
public class MiddleEvent extends TopEvent { }
public class CenterEvent extends TopEvent { }
public class BottomEvent extends MiddleEvent { }

Given this, a bean that implements:

- ApplicationListener<ApplicationEvent> subscribes to all events
- ApplicationListener<TopEvent> subscribes to TopEvent, MiddleEvent, CenterEvent, and BottomEvent
- ApplicationListener<MiddleEvent> subscribes to MiddleEvent and BottomEvent
- ApplicationListener<CenterEvent> subscribes only to CenterEvent
- ApplicationListener<BottomEvent> subscribes only to BottomEvent

Saturday, December 10, 2016

Using URLs, HTTP Methods, and HTTP Status Codes

RESTful web services use request URLs to identify the requested resource and HTTP methods to ascertain the action wanted. They also use HTTP status codes to reveal the result of a request. Different status codes apply to different types of requests. However, there are a few status codes that are universal and apply to all types of requests:

400 Bad Request indicates that the request made by the client was unsupported or unrecognized. This is usually because the proper request syntax was not followed. For example, if a required field of a resource were left blank on a POST or PUT, that would result in a 400 Bad Request response. The response body should include information about why the request was bad in the representation format agreed upon or in the default representation in absence of agreement.

401 Unauthorized signals that authentication and authorization are required before accessing the resource or performing the requested state transition. The content of the response varies based on the authentication protocol in use (such as OAuth).

403 Forbidden indicates that the client, though authenticated, does not have permission to access the resource or perform the requested state transition. Depending on the authentication protocol in use, it’s possible that re-authenticating with more requested privileges could resolve this condition.

404 Not Found, quite simply, tells the client that the requested resource does not exist. It should never be used to indicate that a resource exists but the state transition is simply not supported or allowed. That is what 405 Method Not Allowed and 403 Forbidden are for.

405 Method Not Allowed means that the state transition (HTTP method) requested is not supported. This should never be used to indicate that the client does not have permission to perform the state transition; 403 Forbidden is reserved for that.

406 Not Acceptable indicates that the representation format requested in the Accept header is not supported by the server. For example, the client may have requested application/xml, but the server can generate only application/json. In these cases, the server may simply return the default supported representation instead of 406 Not Acceptable, and that is what most vendors do.

415 Unsupported Media Type is very similar to 406 Not Acceptable. It indicates that the Content-Type header in the request (the representation of the request entity) is a type that is not supported by the server. The server may also include an Accept response header indicating which media types the server supports. It’s possible that both the Accept request header value and the Content-Type request header value can be unsupported media types.
In such a case, the 415 Unsupported Media Type response takes precedence because 406 Not Acceptable is an optional response.

500 Internal Server Error signals that an error occurred while processing the request.
The response content should include as much information about the error as is safe and possible in the representation format agreed upon or in the default representation in absence of agreement.


HTTP Methods


OPTIONS is one of the few standardized discovery mechanisms available. When a request is made to a resource URL with the OPTIONS method, the server must return a 200 OK response containing an Allow header whose contents is a comma-separated list of the HTTP methods supported for the resource. If the client is authenticated, the Allow header may instead contain the HTTP methods that the client is authorized to invoke for the resource.
Optionally, the server may also return a response body describing how to use each HTTP method for that resource. The response body should be in the representation form agreed upon or in the default representation in the absence of any agreement. If the PATCH method is one of the supported methods, the response should also contain the Allow-Patch header, which specifies a comma-separated list of the representations (media types) permitted for PATCH requests, which may differ for other types of requests.

There are some exceptions to these requirements:
- If the resource does not exist, the server should return 404 Not Found instead of 200 OK with the Allow header.
- If no methods are permitted on a resource without authentication, the server should return 401 Unauthorized.
- If the client is authenticated but does not have permission to invoke any actions on the resource, the server should return 403 Forbidden.

OPTIONS requests are considered nullipotent (safe); that is, they should never, under any circumstances, result in modification of any resources.

N.B. Some web services enable Cross-Origin Resource Sharing (CORS). This special, relatively new protocol enables authorized browser applications to bypass the AJAX same-origin policy using a set of specialized headers. If you want your web services to be directly accessible from JavaScript applications, you need to enable CORS support.
CORS-enabled web services must support OPTIONS requests for all resources and, when responding to OPTIONS requests, must include the Access-Control-Allow-Methods response header, whose contents are identical to the Allow header.

Whenever GET is supported and allowed on a resource, HEAD must also be supported and allowed.
The only difference between GET and HEAD is that a HEAD response must have no response body.
The HEAD response must have headers identical to what would be in a GET response. GET requests are used to obtain a resource or resources. A URL such as /services/Rest/account indicates that the client wants to obtain all accounts or a filtered list of accounts. Typically, filter, order, and pagination instructions are included in query string parameters.
A request URL such as /services/Rest/account/1075 indicates that the client wants to obtain a single account with the unique identifier 1075. Some vendors also support relational URLs such as /services/Rest/account/1075/order and /services/Rest/account/1075/order/1522, signaling requests for a (possibly filtered) list of orders for account 1075 and for order 1522 belonging to account 1075, respectively. This recursion can, theoretically, continue as far as the limits on URL length will permit. /services/Rest/account/1075/order/1522/item/12 could return a particular line item from an order for an account.
The server should respond 200 OK for successful GET and HEAD requests and include the resource or resources requested in the agreed-upon (or default) representation in the response body for GET requests.
GET and HEAD requests are also nullipotent and should not have any side effects for resources on the server.

POST requests are used to create new resources on the server. A POST request should always be directed at a collection URI (/services/Rest/account), but it can also be directed at a subordinate collection URI (/services/Rest/account/1075/order). A POST request to an individual element URI (/services/Rest/account/1075) should result in a 405 Method Not Allowed response. In a successful POST request, the server creates the requested resource and returns 201 Created. The response should include a Location header with the URL for the newly created resource.
For example, a POST request to /services/Rest/account to create a new account might return http://www.example.com/services/Rest/account/9156 in the Location header. The response body should be the created resource because it would be returned with a GET request to the URL in the Location header.
A POST request is non-nullipotent (non-safe : the request does result in modification of one or more resources) and non-idempotent (making multiple identical POST requests results in multiple created resources).

A PUT request results in the replacement of a resource on the server. For this reason, PUT requests are used to update existing resources. PUT requests, unlike POST requests, are never made to collection URIs. Instead, they are made to individual element URIs and subordinate element URIs (/services/Rest/account/1075, /services/Rest/account/1075/order/5122). A PUT request to a collection URI or subordinate collection URI should result in a 405 Method Not Allowed response. The response to a successful PUT request should be 204 No Content and its body should be empty.
PUT requests are, obviously, non-nullipotent. They should, however, be idempotent. Two or more successive, identical PUT requests should have no side effects other than those in the first PUT request.
One area that this can be a challenge is if the resource being updated includes a “last modified” timestamp or a version number. To abide by the restriction of idempotence, the service should update the resource timestamp and/or version number for PUT requests only if the underlying entity truly changed. Such a requirement can actually be quite challenging to implement, so many vendors implement PUT in a partially idempotent manner, documenting that the timestamp and version number will still be updated in identical PUT requests.

PATCH requests are very similar to PUT requests in both purpose and semantics. PATCH is a relatively new HTTP method, added only in the last several years. It is not part of the original HTTP/1.1 specification. PATCH requests, like PUT requests, are also intended to update resources at individual element URIs. However, a PATCH request indicates only a partial update of a resource, not a complete replacement of the resource.
For example, if a PATCH request to /service/Rest/account/1075/order/5122 contains only the shippingAddress property, then only the shippingAddress on the order will be updated. Other properties will remain unchanged (except, possibly, timestamps and version numbers). This is an extremely powerful request method, but it is also quite challenging to implement. To support PATCH, your application must accept a very flexible set of properties in the request entity, and then update only those resource properties that are present in the request. You cannot merely use a check for null because the PATCH may be intentionally setting a property value to null.
The response to a successful PATCH request should be either 200 OK or 204 No Content. It’s your choice whether to return the full, updated entity or no content in the response body. If PATCH is supported, the requested media type is supported, and the PATCH request content is understood and parsed successfully, but the server still cannot apply the patch (for example, because the patch would make the entity invalid), the server should respond with 422 Unprocessable Entity. If the client uses the If-Match request header or If-Unmodified-Since request header to define a precondition for the patch and that precondition fails, the server should return 412 Precondition Failed. If multiple requests attempt to patch a resource simultaneously and that is not permitted, the server should return 409 Conflict.
PATCH requests, like PUT requests, are non-nullipotent and should be idempotent.

A DELETE request, naturally, is used to delete a resource. A DELETE request may be made against an individual element URI in which case that single resource is deleted or it may be made against a (possibly filtered) collection URI in which case all the matching resources are deleted. Allowing the deletion of multiple resources is often not desirable, so this capability is usually not supported. Upon successful deletion of a resource, the server should respond 200 OK with the deleted resource in the response body or 204 No Content with no content in the response body. If for some reason the server accepts the delete command but cannot execute it immediately (perhaps the resource is in use), it may return 202 Accepted. In this case, the response body should contain a resource URL that the client can use to follow up on the request and check on its status at a later time.
DELETE requests are obviously non-nullipotent, but their idempotence is an interesting topic. Deleting a resource may result in setting a flag on that resource but retaining its data (a soft delete), or it may result in actually permanently and irrevocably eliminating the resource’s data (a hard delete). When employing soft deletes, multiple identical DELETE requests always return the same response and have no additional side effects, making DELETE idempotent. However, when using hard deletes a second identical DELETE request always results in 404 Not Found because the resource no longer exists. Technically this is considered non-idempotent because the response differs, but it doesn’t actually have different side effects and is still the best practice when accepting DELETE requests for hard deletes.

Friday, December 9, 2016

Creating a Constraint Validator

In Bean Validation, constraints can inherit from one another. Of course, this is not the same thing as one class inheriting from another because you cannot extend annotations. However, per convention, constraint annotations usually include a target of ElementType.ANNOTATION_TYPE.
When a constraint annotation is located, the Validator determines if the annotation definition is annotated with any other constraints. If so, it combines all the additional constraints with the logic defined by the original constraint (if any) into a single, composite constraint. In this sense, the constraint inherits all the constraints with which it is annotated. If for some reason you need to create a constraint that cannot be inherited, you simply omit ElementType.ANNOTATION_TYPE from the definition. With all this in mind, take a look at the @Email definition.

@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {})
@Pattern(regexp = "^[a-z0-9`!#$%^&*'{}?/+=|_~-]+(\\.[a-z0-9`!#$%^&*'{}?/+=|"
+ "_~-]+)*@([a-z0-9]([a-z0-9-]*[a-z0-9])?)+(\\.[a-z0-9]" + "([a-z0-9-]*[a-z0-9])?)*$", flags =
{ Pattern.Flag.CASE_INSENSITIVE })
@ReportAsSingleViolation
public @interface Email
{
String message() default "{ml.javasopenblog.site.validation.Email.message}";

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

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

@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
static @interface List
{
Email[] value();
}
}

There’s a lot going on here, so take a look at it line by line, starting with the annotations:

@Target : This annotation indicates which language features this annotation can be placed on. The values listed are pretty standard and should be used for most constraints.

@Retention : Indicates that the annotation must be retained at run time. If not, Bean Validation will not detect it.

@Documented : This means that the Javadoc of targets marked with this annotation should indicate the annotation’s presence. This is especially useful when programming in an IDE because it makes the contract more visible.

@Constraint : This is a must: It’s what indicates that this annotation represents a Bean Validation constraint, so all constraint definitions have to be annotated with this. Without this, your constraint is ignored. @Constraint also indicates which ConstraintValidator implementation or implementations are responsible for validating your constraint. However, in this case no ConstraintValidator is necessary.

@Pattern : This is another constraint, indicating that this constraint inherits the constraint declared with @Pattern. This is the same regular expression seen earlier, but now you won’t have to duplicate the regular expression every time you use it. You can just use the @Email annotation, instead.

@ReportAsSingleViolation : Indicates that the composite constraint should be considered one constraint and use @Email’s message instead of @Pattern’s message. It is very rare that you should ever create a constraint that inherits other constraints without using @ReportAsSingleViolation.

Within the annotation are three attributes: messagegroups, and payload. These are the standard attributes that must be present in all constraints. Without one or more of these, use of @Email would result in a ConstraintDefinitionException. The @Email.List inner annotation, like all the bean validation list annotations, defines a way to specify multiple @Email constraints on a target.


The @NotBlank constraint looks nearly identical to @Email. For the most part, it has the same annotations, attributes, and features. Instead of being annotated with @Pattern, it’s annotated with @NotNull. In this case @NotBlank should imply non-null, so you inherit the @NotNull constraint to accomplish this. (If you anticipate needing to define targets that can be null but cannot be blank strings, you would simply remove @NotNull from this annotation.)

@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy =
{ NotBlankValidator.class })
@NotNull
@ReportAsSingleViolation
public @interface NotBlank
{
String message() default "{ml.javasopenblog.site.validation.NotBlank.message}";

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

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

@Target(
{ ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR,
ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Documented
static @interface List
{
NotBlank[] value();
}
}

However, unlike @Email, it can’t inherit all its functionality. It needs a ConstraintValidator to test whether the value is blank. The following NotBlankValidator class, declared in the @Constraint annotation on the @NotBlank annotation, accomplishes this.

public class NotBlankValidator implements ConstraintValidator<NotBlank, CharSequence>
{
@Override
public void initialize(NotBlank annotation)
{

}

@Override
public boolean isValid(CharSequence value, ConstraintValidatorContext context)
{
if (value instanceof String)
return ((String) value).trim().length() > 0;
return value.toString().trim().length() > 0;
}
}

Thursday, December 8, 2016

Adding Constraint Validation Annotations to Your Beans

Although you can create your own constraint annotations any time you like, the Bean Validation API comes with several built-in annotations that satisfy the most common validation requirements.
These are all very simple constraints, but in many cases they are all you need to use. All these
constraints are in the package javax.validation.constraints.

@Null : You can apply this to any type, and it ensures that the annotated target is null.

@NotNull : You can also apply this to any type. It ensures that the target is not null.

@AssertTrue and @AssertFalse : These ensure that their annotated targets are true and false, respectively. As such, the field, parameter, or method (return value) that they annotate must be of the type boolean or Boolean. A null Boolean is considered valid for either constraint, so combine these with @NotNull if you do not accept null values.

@DecimalMax : This defines an upper limit for a numeric type, specified with the value attribute. It may annotate fields, parameters, and methods (return values) of type BigDecimal, BigInteger, CharSequence (String), byte, Byte, short, Short, int, Integer, long, and Long. The primitives double, Double, float, and Float are not supported due to precision concerns. CharSequences are converted to a decimal before validation, and null values are considered valid. The optional inclusive attribute specifies whether the test should be inclusive (less than or equal to) or exclusive (less than), and defaults to inclusive (true).

@DecimalMin : This is the counterpart to @DecimalMax. It applies to all the same types with the same rules. It also contains an inclusive attribute.

@Digits : You can use this to ensure that the annotated target is a parseable number (if it’s a CharSequence) and then tests the limits of that number’s parts (whether it’s a CharSequence, BigDecimal, BigInteger, byte, Byte, short, Short, int, Int, long, or Long). The mandatory integer attribute specifies the maximum number of integral digits (before the decimal point) allowed, whereas the required fraction attribute specifies the maximum number of fractional digits (after the decimal point) allowed. As always, null values are considered valid.

@Future : Ensures that the Date or Calendar field, parameter, or method (return value) is at some point in the future, however near or distant. As of Bean Validation 1.1, there is no support for Java 8 Date and Time API types. null values are considered valid.

@Past : Ensures that Date and Calendar targets are at some point in the past.

@Max and @Min : These are similar to @DecimalMax and @DecimalMin, but they do not support CharSequence targets, and they do not host an inclusive attribute; they are always inclusive. Targets that are null are considered valid.

@Pattern : This defines a regular expression regexp that the target CharSequence (String) must match, and it considers null values to be valid. It hosts an optional flags attribute that supports an array of any of Pattern.Flag enum values. Supported flags are:
     CANON_EQ : Enables canonical equivalence
     CASE_INSENSITIVE : Enables case-insensitive matching
     COMMENTS : Enables white space and comments in the pattern
     DOTALL : Turns dotall mode on
     MULTILINE : Turns multiline mode on
     UNICODE_CASE : Enables Unicode case folding
     UNIX_LINES : Turns Unix lines mode on

@Size : This defines inclusive max and min limits for the length of a CharSequence (String), the number of values in a Collection, the number of entries in a Map, or the number of elements in an array of any type.

Wednesday, December 7, 2016

Configuring Validation in the Spring Framework Container

At its simplest, configuring Spring Framework’s LocalValidatorFactoryBean is as simple as instantiating it and returning it in a @Bean method in the RootContextConfiguration class:

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
     return new LocalValidatorFactoryBean();
}

The LocalValidatorFactoryBean automatically detects the Bean Validation implementation on the classpath, whether that’s Hibernate Validator or some other implementation, and uses its default javax.validation.ValidatorFactory as the backing factory. There’s no need to set up the META-INF/validation.xml file usually required to take advantage of Bean Validation in your application. However, sometimes there is more than one Bean Validation Provider on the classpath (for example, when running within a full Java EE application server such as GlassFish or WebSphere).
In these cases, which provider Spring selects is unpredictable (it might even change each time!), so you should set the provider class manually if you prefer the provider to be predictable.

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
{
     LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
     validator.setProviderClass(HibernateValidator.class);
     return validator;
}

The only downside to doing this is that it requires Hibernate Validator to be a compile-time dependency instead of a runtime dependency. This pollutes your compile time classpath, meaning your IDE will sometimes make code suggestions that you don’t want. You can avoid this by loading the class dynamically, which of course has its own downside in that any mistakes in the name will not be caught at compile time.

@Bean
public LocalValidatorFactoryBean localValidatorFactoryBean()
          throws ClassNotFoundException
{
     LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
     validator.setProviderClass(Class.forName(
          "org.hibernate.validator.HibernateValidator"
     ));
     return validator;
}

N.B. Setting the provider class manually is not necessary when using Tomcat.