INTRODUCTION
In current post I am going to explain how to implement and register a custom Spring MVC HttpMessageConverter object. Specifically a converter that binds objects to Yaml protocol. As starting point I am going to use the Rest application I implemented in previous post. That application is a simple Restful application where XML and JSON (Spring MVC already support them) are used. Because Spring MVC does not implement YamlMessageConverter, I am going to explain how to transform previous application from supporting XML and JSON to support Yaml.
Yaml is a human-readable data serialization format that takes concepts from programming languages such as C, Perl, and Python, and ideas from XML and the data format of electronic mail (RFC 2822).
SnakeYAML is a YAML parser and emitter for the Java programming language, and will be used to implement our message converter.
DESIGN
Let's start with a UML class diagram of HttpMessageConverter that are going to be implemented.
HttpMessageConverter is a base interface that must be implemented. It is a strategy interface that specifies methods to convert objects from and to HTTP requests and responses. AbstractHttpMessageConverter is the abstract base class for most HttpMessageConverter implementation (both provided by springframework), and is our base class.
First developed class is an abstract class called AbstractYamlHttpMessageConverter. This class is responsible of generic operations that "should" be required by all Yaml parsers/emitters. In my case it deals with charset options, and transforms HttpInputMessage and HttpOutputMessage to java.io.InputStreamWriter and java.io.OutputStreamWriter. In fact it acts as a Template Pattern to read and write operations (readInternal and writeInternal methods).
Next abstract class is AbstractSnakeYamlHttpMessageConverter. This class is a base class for HttpMessageConverters that use SnakeYaml as Yaml binder. This class gets an instance of Yaml class (central class of SnakeYaml project).
And finally JavaBeanSnakeYamlHttpMessageConverter. This class uses SnakeYaml JavaBeans features for converting from object to Yaml and viceversa. SnakeYaml does not support annotations like Jackson (JSON) or Jaxb (XML), but if some day this feature is implemented, we should create a new class extending from AbstractSnakeYamlHttpMessageConverter with required change.
CODE
First of all is adding a new dependency to pom. In this case SnakeYaml.
Then three classes previously exposed should be developed.
First class is a generic Yaml converter where we are setting accepted media type, in this case application/yaml, and creating a Reader and Writer with required Charset. We are leaving to children classes the responsibility of implementing read and write code.
Next class is specific of API that will be used to bind classes to messages, in this case SnakeYaml. This class will be responsible of creating an instance of Yaml class (from SnakeYaml). As is warned in http://snakeyamlrepo.appspot.com/releases/1.9/site/apidocs/index.html each thread must have its own instance; for this reason a ThreadLocal is used to carry out this restriction.
Final class is an implementation of read/write methods using SnakeYaml. As I have explained previously this class has a meaning because allows us changing SnakeYaml binding strategy (for example to annotation approach) and only worries to rewrite read/write operations.
Now it is time to register created message converter to AnnotationMethodHandlerAdapter. First thing you should do is not to use <mvc:annotation-driven>. This annotation registers default message converters and you are not able to modify them. So first step is comment or remove annotation-driven. Next step is declare DefaultAnnotationHandlerMapping bean and AnnotationMethodHandlerAdapter which registers http message converters. In our case only Yaml http message converter is added.
RUNNING
And now you can try application. Deploy it on a server, and using for example Rest Client, try http://localhost:8080/RestServer/characters/1 and you will receive a response like:
If you want you can use POST instead of GET to insert a new Character to our Map.
As you can see developing a Spring MVC HTTP Message Converter is so easy, in fact you must implement two basic operations, when a resource can be read or written and resource conversion.
Hope you found this post useful.
No hay comentarios:
Publicar un comentario