sábado, 30 de mayo de 2015

Configurar el entorno de trabajo (Spring 4.1). (Producción/Integración/Desarrollo)

La idea es ver como podemos montar en nuestro proyecto, diferentes entornos.
Esto es algo que mucha, veces no le damos mucha importancia, pero que al largo plazo nos simplifica mucho la vida y si lo tenemos claro no es muy difícil de implementar.
El proyecto de ejemplo lo puede consultar en la siguiente url https://github.com/blancoparis-tfc/SpringProfile

Antes de nada vamos a ver los diferentes tipos de entornos que podemos tener en un proyecto.

  • Desarrollo: Es el entorno con las configuraciones para el desarrollo.
  • Integración: Es el entorno donde vamos a subir todos los programadores los cambios, para poder ver si chocan, y realizar las diferentes pruebas, 
  • PreProduccion: Es un entorno equivalente al de produccion, para probar los cambios sin ir a producción.
  • Producción: Es el entorno de producción.
Esta historia se puede plantear de dos maneras:
  • Una construcción independiente por cada entorno, delegando la responsabilidad a la herramienta de build (Maven, gradle), con sus diferentes profile por cada entorno.
  • Una misma construcción que a partir de una variable de entorno establece que entorno y configuraciones vamos a trabajar.
Las dos opciones son factibles, a mi personalmente  me gusta la segunda opción. Que ademas nos proporciona las siguientes ventajas:
  • La responsabilidad del entorno la delegamos al servidor, y por lo cual un administrador de sistema puede realizar cambios sin necesidad de depender del equipo de desarrollo (En algunas cosas), seguridad, B.D etc...
  • Un desarrollador cambiando la configuración de su IDE, puede estar trabajando sobre producción (Si fuera necesario).
  • Podemos llevar el war de desarrollo directamente a producción, sin tener que realizar un montaje. Esto en algún caso de emergencia nos ahorraría algo de tiempo. 
  • Quita la responsabilidad de las configuraciones en la herramienta de build, simplificando su trabajo.
Desventajas:
  • Requiere, de unas configuraciones algo mas complejas y un nivel de abstracción mayor.
  • Es necesario que el framework nos de herramientas que nos facilite esta gestión.

Una vez expuesto, que es un entorno para mi y de que manera vamos a resolver el problema, vamos a ver con que herramientas contamos en Spring:

En el caso de spring ,  nos proporciona el concepto de profile, que nos permite tener uno o varios. Aquí se nos plantea otro dilema como vamos a utilizarlo.
  • Un solo profile: Aquí tendríamos un solo profile activo,  y un profile por cada entorno al cual vincularemos la configuración.
  • Varios profile: Aquí tendríamos varios profile activos y en cada entorno tendríamos que ir poniendo los profile que nos interesen.
En la documentación de spring nos ponen un ejemplo con un profile activo para desarrollo y otro para producción.
Un solo profile activo

El profile activo, se refiere al entorno en cuestión (dev, prod, preProd,int). Aquí la filosofía, es que hacemos una configuración a medida para el entorno.  Esto es una buena opción en un proyecto empresarial o a medida en el cual tengamos 3 o 4 configuraciones idénticas. Normalmente la norma es poner una configuración por defecto y el entorno nos active las excepciones.

Si tenemos 3 o 4 entornos nos simplifica la configuración del servidor, ya que  solo tenemos que mapear el profile con el entorno.
Esta solución no es la mejor si vamos a tener múltiples entornos de producción y queremos que nuestra herramienta, sea muy adaptable y que la configuración fuera del código.
Varios profile activos

Aquí, tendremos varios profiles activos, cada uno se refería a un aspecto de configuración, por ejemplo en el caso de la seguridad en spring podemos tener 3 tipos diferentes:

  • SeguridadMemoria: Mock en memoria (Usuarios puesto a fuego), se suele utilizar en el entorno de desarrollo.
  • SeguridadLadp: Ldap, se validan los usuarios contra un directorio activo. + Configuración del ldap en cuestión en un fichero externo. 
  • SeguridadBD: Los usuarios se valida contra la B.D. + Esquema de B.D. 
En este ejemplo, en el entorno de desarrollo y integración podemos tener los usuarios de palo, ya que no tenemos la necesidad de ir contra el directorio activo y saber las contraseñas de usuarios. Y en preproducción y producción dependiendo del entorno iremos contra un directorio activo o  la B.D.


Y esta operación la podríamos realizar por cada aspecto de la configuración que lo precisara.

Como podemos ver esta configuración le da mas libertad al administrador en el servidor para activar las diferentes configuraciones. En cada entorno, Pero también complica esa configuración.
 Esto tiene sentido si tenemos muchos entornos diferentes al que llevar nuestra aplicación.

Conclusión:

Con que configuración nos vamos a quedar, pues en este caso dependiendo de nuestras circunstancias, como aquí estamos planteando como realizar una separación de un proyecto en 4 entornos de trabajo, nos sale mas a cuenta la primera opción.

Profile

Ahora que ya tenemos claro que vamos a configurar 4 entorno de trabajo, con una misma construcción y que vamos a trabajar con un solo entorno activo, vamos a ver que herramientas nos proporciona spring, para facilitarnos la tarea. Desde la versión 3 de spring mas o menos permite utilizar el concepto de profile.

Profile: Es un grupo lógico de las definiciones de configuración que se activan y beans.
 En los ejemplo de la documentación oficial de spring, nos ponen un ejemplo de dev(desarrollo) y prod (Producción). Mas o menos tenemos que saber 2 cosas de los profile en spring:
  • Como se activa, ya que por defecto no tiene ninguno.
  • Como indicas a una configuración o beans de spring que esta asociado a un profile.

¿Como se activa un profile?

Aquí tenemos diferentes maneras, que utilizaremos según nuestras necesidades, 
  • Programáticamente a través del WebApllicationInitializer
@Configuration
public class MyWebApplicationInitializer implements WebApplicationInitializer {
 
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.setInitParameter("spring.profiles.active", "dev");
    }
}

  • Programáticamente a través de ConfigurableEnviroment.
@Autowired
private ConfigurableEnvironment env;
...
env.setActiveProfiles("someProfile");

  • Parametro de contexto en web.xml
<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>/WEB-INF/app-config.xml</param-value>

</context-param>

<context-param>

    <param-name>spring.profiles.active</param-name>

    <param-value>dev</param-value>

</context-param>


  • JVM parámetro del sistema
-Dspring.profiles.active=dev

  • Variable de entorno.
export spring_profiles_active=dev

El tema de activación lo he sacado del siguiente articulo http://www.baeldung.com/spring-profiles

Una vez hemos visto algunas formas, como podemos plantear en nuestro proyecto la activación de un profile, esto es un poco a gusto del consumidor y de las necesidades del proyecto. Yo por ejemplo me gusta que siempre haya una configuración por defecto activa, si no configuro nada y claro esta en su defecto para evitar desgracias mayores siempre es el entorno de desarrollo (Sobra explicar por que no poner producción por defecto xd). 

Como podemos conseguir ese comportamiento que hemos explicado en el párrafo anterior, pues muy fácil, utilizaremos por un lado la configuración programáticamente del WebAplicationInitializer, que seguirá el siguiente algoritmo, si no tenemos activo ningún profile, activa pragmáticamente "dev".  Y para activar el entorno que nos interesa usaremos la configuración de JVM parámetro del sistema esto nos permite que la elección del entorno estar fuera de nuestro código y podremos configurar-lo en el servidor web, que lo contendrá y de esta manera tendremos el mismo paquete para cualquier entorno. 
package org.dbp.conf;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;

import org.apache.commons.lang3.StringUtils;
import org.dbp.conf.profiles.ProfilesAplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.WebApplicationInitializer;

@Configuration
public class MiWebApplicationInitializer implements WebApplicationInitializer {
 
 @Override
 public void onStartup(ServletContext servletContext)
   throws ServletException {
  String entornoActivo=System.getProperty("spring.profiles.active");
  if(StringUtils.isBlank(entornoActivo)){
   entornoActivo=ProfilesAplication.dev;
  }
  servletContext.setInitParameter("spring.profiles.active",entornoActivo);  
 }

}

¿Como indicar que configuración se asocia a un profile?

Esto es fácil, solo tenemos que utilizar, la anotación @Profile("<entorno>) y esto activara la configuración o bean asociado.

Otra forma es recuperar del entorno los contextos activos y actuar en consecuencia, en nuestro ejemplo de momento vamos a definir los recursos estáticos distintos para cada contexto como ejemplo:
 @Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
  String entorno=env.getActiveProfiles()[0];
  registry
       .addResourceHandler("/resources/**")
       .addResourceLocations("/resources/")
       .setCachePeriod(3600)
       .resourceChain(true)
       .addResolver(new PathResourceResolver());
  registry
       .addResourceHandler("/env/**")
       .addResourceLocations("/resources/env/"+entorno+"/")
       .setCachePeriod(3600)
       .resourceChain(true)
       .addResolver(new PathResourceResolver());  
 }


Como podéis observar en este articulo, es bastante fácil de usar y nos da muchas opciones por lo cual es algo que al final tenemos que ajustar el traje a nuestras necesidades.





martes, 5 de mayo de 2015

Configurar los contenidos estáticos en un proyecto de spring 4.1

Vamos a ver como definir los contenidos estáticos, en un proyecto de Spring. En este caso en concreto, vamos a cargar la librería de bootstrap, para la maquetación.

ResourceHttpRequestHandler

Este clase es la utilizar spring, para trabajar con los recursos estáticos, en el siguiente diagrama vamos a ver como funciona.
Esta implementación sigue las directivas (page Speed, Yslow). Para lo cual gestiona la cache del navegador.

 
Como podemos ver, en el ciclo de vida se diferencia, en dos operaciones:
  • Resolver la operación (Encontrar el recurso segun un path, u otros criterios).
  • Transformar el recurso.
Esta clase ademas se encarga de gestionar la cache del navegador, y actualizar los recursos cuando sea necesario, para lo cual gestionara el (expire y control-cache), de esta manera evitaremos la sobrecarga de la red, con el código 304 y asi no sobrecargar el sevidor.



Para mas información podéis mirar el javadoc de la clase: http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.html
Para configurar esta clase utilizaremos ResourceHandlerRegistry, Usaremos los siguientes métodos:

  • addResourceHandler: Indicamos como vamos a localizar el recursos desde la petición de http.  
  • addResourceLocations: Indicamos donde se van a encontrar los recursos, para un mismo recurso podemos tener varios sitios donde buscarlo. (Nota: También puede buscar dentro de los classpath). 
  • setCachePeriod: Establecemos el valor max-age en segundos, en la cabecera de Http destinada para las caches. http://tools.ietf.org/html/draft-ietf-httpbis-p6-cache-12
  • resourceChain: Los usaremos para establecer una cadena de resolute y transformadores. Se recomienda establecerlo solo en producción. (Por defecto si no establecemos, nada se configurara PathResourceResolver)
  • addResolver: Le indicamos el resolver que nos interesa entre (PathResourceResolver ,GzipResourceResolver...)
  • addTransformer: Le podemos indicar los transformadores que nos interesan.

Configurar los recursos estáticos:

Ahora que hemos visto un poco, como funciona en spring, la gestión de los recursos estáticos vamos a ver como podemos configurar los en nuestro proyecto. En nuestro caso en cuestión vamos a marcar que los contenidos estáticos, se van a encontrar en el path /resources/ y físicamente lo vamos a dejar en la carpeta resources (Coincide en mi caso para facilitar la búsqueda de los recursos). Entonces que ventaja nos da el utilizar este mecanismo, pues la gestión que hace de la cache spring de esos recursos. Vamos a crear una cadena de resolver y transformer, aunque va a ser igual a que utiliza por defecto (me gusta dejar estas configuraciones declarativas, ya que no todo el mundo se tiene que acordar de la configuración por defecto).

 @Override
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
   registry
       .addResourceHandler("/resources/**")
       .addResourceLocations("/resources/")
       .setCachePeriod(3600)
       .resourceChain(true)
       .addResolver(new PathResourceResolver());
 }

Bootstrap

Ya que tenemos configurados en spring los recursos estáticos, vamos a empezar por configurar la librería bootstrap,  copiaremos en resources la carpeta de bootstrap.


Lo siguiente sera crear la hoja de estilo del proyecto css/app.css
body {
 padding-top: 50px;
}

.starter-template {
 padding: 40px 15px;
 text-align: center;
}

Maquetamos la pagina de inicio

Aquí vamos a crear una plantilla básica con bootstrap (He adaptado uno de las plantillas que nos propone).
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core"%>
<c:url value="/" var="contexto" />
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Proyecto de ejemplo">
<meta name="author" content="Arquitectura de ejemplo">
<title>Inicio</title>
<!-- Bootstrap core CSS -->

<link href="${contexto}resources/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="${contexto}resources/bootstrap/css/bootstrap-theme.min.css" rel="stylesheet">
<link href="${contexto}resources/css/app.css" rel="stylesheet">
</head>
<body>
 <nav class="navbar navbar-inverse navbar-fixed-top">
  <div class="container">
   <div class="navbar-header">
    <button type="button" class="navbar-toggle collapsed"
     data-toggle="collapse" data-target="#navbar" aria-expanded="false"
     aria-controls="navbar">
     <span class="sr-only">Toggle navigation</span> <span
      class="icon-bar"></span> <span class="icon-bar"></span> <span
      class="icon-bar"></span>
    </button>
    <a class="navbar-brand" href="#">Spring estatico</a>
   </div>
   <div id="navbar" class="collapse navbar-collapse">
    <ul class="nav navbar-nav">
     <li class="active"><a href="#">Inicio</a></li>
     <li><a href="#about">Acerca de</a></li>
     <li><a href="#contact">Contacto</a></li>
    </ul>
   </div>
  </div>
 </nav>
 <div class="container">
  <div class="starter-template">
   <h1>Inicio</h1>
   <p class="lead">
    Proyecto de ejemplo de los contenidos estaticos.
   </p>
  </div>
 </div>
</body>
</html>
Se tiene que ver algo tal que así:

sábado, 2 de mayo de 2015

Integrar Jackson en Spring 4.1

Vamos a ver como podemos integrar la librería Jackson,
En la siguiente url encontraremos un proyecto con la configuración que hemos puesto en este blog https://github.com/blancoparis-tfc/SpringJson
La anotación @DpbLog es una anotación para poder trazear las llamadas al método, viene explicado en el articulo anterior. 
Apartados:

  • Configurar jackson en spring.
  • Funcionamiento de las vistas de un json en spring.
  • Soporte de jackson a XML
  • Personalizar jackson en spring.
  • Configurar JSR-330 y como establecer los formateo de las fechas.

Configurar jackson 2 con spring 4.1

Esta parte es bastante fácil, ya que simplemente tenemos que poner las librerías y estas automáticamente se integran en spring, con una configuración por defecto.


  • Añadimos la dependencia de jackson core.
  • Añadimos la dependencia de jackson databind
Es importante que estén las dos dependencias para que funcione correctamente.
 compile 'com.fasterxml.jackson.core:jackson-core:2.5.3'
 compile 'com.fasterxml.jackson.core:jackson-databind:2.5.3'

Objeto que vamos a serializar:
package org.dbp.controller.json;

import java.io.Serializable;

public class EjemploJson implements Serializable{

 

 private Long numero;
 private String cadena;
 public Long getNumero() {
  return numero;
 }
 public void setNumero(Long numero) {
  this.numero = numero;
 }
 public String getCadena() {
  return cadena;
 }
 public void setCadena(String cadena) {
  this.cadena = cadena;
 }
 @Override
 public String toString() {
  return "EjemploJson [numero=" + numero + ", cadena=" + cadena + "]";
 }
 
 
}


Ejemplo de uso en el controlador.
 @DbpLog
 @RequestMapping("ejemploJson")
 public @ResponseBody EjemploJson ejemploJson(){
  EjemploJson valdev=new EjemploJson();
  valdev.setNumero(1L);
  valdev.setCadena("cadena");
  return valdev;
 }
Este controlador nos devolverá el siguiente resultado:
{"numero":1,"cadena":"cadena"}

Vistas Json

Spring ahora nos proporciona un mecanismos que nos permite filtrar que partes de un objeto:

La idea es parecida a la de los grupos que se utilizan en el estándar de java para las validaciones. 
En el siguiente enlace encontrara la documentación del Json View  http://wiki.fasterxml.com/JacksonJsonViews
  • Para clasificar usaremos interfaces definidos.
  • Y luego los campos que nos interesa filtrar usaremos la anotación  @JsonView.
Ejemplo de objeto que vamos a serializar filtrado:

package org.dbp.controller.json;

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonView;

public class EjemploJson implements Serializable{

 public interface Resumen{};

 @JsonView(Resumen.class)
 private Long numero;
 
 private String cadena;
 
 public Long getNumero() {
  return numero;
 }
 public void setNumero(Long numero) {
  this.numero = numero;
 }
 public String getCadena() {
  return cadena;
 }
 public void setCadena(String cadena) {
  this.cadena = cadena;
 }
 @Override
 public String toString() {
  return "EjemploJson [numero=" + numero + ", cadena=" + cadena + "]";
 }
 
}

Ahora vamos a ver como decirle al controlador  que nos pinte los campos de la vista , poniendo la misma anotación:
 @JsonView(Resumen.class)
 @DbpLog
 @RequestMapping("resumenJson")
 public @ResponseBody EjemploJson resumenJson(){
  return mockEjemplo();
 }

 private EjemploJson mockEjemplo() {
  EjemploJson valdev=new EjemploJson();
  valdev.setNumero(1L);
  valdev.setCadena("cadena");
  return valdev;
 }

Si no ponemos la anotación nos pone todos los campos.

Y nos devolverá el siguiente json como resultado:

{"numero":1}

Vamos a ver como utilizar estas vistas de manera conjunta, como la anotación @JsonView solo se puede poner una utilizaremos las herencias para asociar dos. De esta manera si ponemos la herencia hija, en el controlador activara todas las vistas que hereden.

Ejemplo de objeto que vamos a serializar filtrado:
package org.dbp.controller.json;

import java.io.Serializable;

import com.fasterxml.jackson.annotation.JsonView;

public class EjemploJson implements Serializable{

 public interface Resumen{};

 public interface Resumen2 extends Resumen{}
 @JsonView(Resumen.class)
 private Long numero;
 
 private String cadena;
 @JsonView(Resumen2.class)
 private String descripcion;
 
 
 public String getDescripcion() {
  return descripcion;
 }
 public void setDescripcion(String descripcion) {
  this.descripcion = descripcion;
 }
 public Long getNumero() {
  return numero;
 }
 public void setNumero(Long numero) {
  this.numero = numero;
 }
 public String getCadena() {
  return cadena;
 }
 public void setCadena(String cadena) {
  this.cadena = cadena;
 }
 @Override
 public String toString() {
  return "EjemploJson [numero=" + numero + ", cadena=" + cadena + "]";
 }
 
}

Ahora vemos como utilizarlo en el controlador

 @JsonView(Resumen2.class)
 @DbpLog
 @RequestMapping("resumen2Json")
 public @ResponseBody EjemploJson resumen2Json(){
  return mockEjemplo();
 }

 private EjemploJson mockEjemplo() {
  EjemploJson valdev=new EjemploJson();
  valdev.setNumero(1L);
  valdev.setCadena("cadena");
  valdev.setDescripcion("descripcion");
  return valdev;
 }

Y nos devolverá el siguiente json como resultado:
{"numero":1,"descripcion":"descripcion"}

SpringMVC tiene configurado por defecto a true la siguiente propiedad  MapperFeature.DEFAULT_VIEW_INCLUSION  , esto significa que los campos que no tengan la anotación se agregaran automáticamente

 Soporte xml

Aquí vamos a ver como la librería Jackson nos da soporte de xml:

Ventajas de activar la parte de xml de la librería de Jackson:
  • Nos permite utilizar las anotaciones de jackson y las de JAXB.
  • Podemos utilizar el mismo objeto para configurar un xml y json, sin tener que tener dos objetos o configuraciones separadas.
  • Es capaz de generar un xml, sin las anotaciones de jaxb.
Al activar la librería spring, al activar esta parte en jackson sustituirá a jaxb.
 Ahora vamos a ver los pasos que tenemos que dar para poder configurar-lo en el proyecto, simplemente al igual que jackson al incluir la librería se configurara por defecto.

 // Jackson soporte xml
 compile 'com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.5.3'
Como podemos indicarle a un controlador, que vamos a devolver un xml, esto es fácil, ya que solo le indicamos en el mapeo que vamos a producir un xml.
 @DbpLog
 @RequestMapping(value="ejemploXml",produces = "application/xml")
 public @ResponseBody EjemploJson ejemploXml(){
  return mockEjemplo();
 }
Y nos devolvera el siguiente xml como resultado:
<EjemploJson xmlns="">
<numero>1</numero>
<cadena>cadena</cadena>
<descripcion>descripcion</descripcion>
</EjemploJson>
Una vez indicado esto tenemos que indicar en todas las configuraciones si va a devolver un Json o un xml.

Como personalizar Jackson en Spring:

Para poder personalizar Jackson en spring, ahora podemos utilizar el objeto Jackson2ObjectMapperBuilder 
Vamos a establecer el formateo de las fechas al formato español 'dd-MM-yyyy' y identamos el json que devuelve el servidor. Ahora vamos a ver como activar la configuración de jackson:

  • identiOutput: Tabulamos la salida del json.
  • dateFormat: Le pondremos la fecha "dd-MM-yyyy"
Tenemos que pasarle los converts de jackson a spring, para que lo sepa esto siempre que tengamos que realizar la configuración.


 @Override
 public void configureMessageConverters(
   List> converters) {
  super.configureMessageConverters(converters);
  Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
     builder.indentOutput(true).dateFormat(new SimpleDateFormat("dd-MM-yyyy"));
     converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
     converters.add(new MappingJackson2XmlHttpMessageConverter(builder.createXmlMapper(true).build()));
 }
...

Configurar el JSR-330, un formato de fecha determinado

Ahora vamos a ver como poner por defecto un formato de fecha concreto, esto es muy tipico en cualquier proyecto, en España ya que el formato es distinto al ingles.

En este caso, vamos a seguir los siguientes pasos, para el caso LocalDate:
  • Crearemos una clase para deserializar.
  • Crearemos una clase para serializar.
  • Tendremos que crear un modulo propio, ya que el modulo de JSR330 no tiene ningún mecanismos para escalarlo.
  • Por ultimo lo tendremos que registrar.
Ojo, a la hora registrarlo tenemos que hacerlo después del build, ya que la operación de build lo que hace es volver a cargar los deserealizadores y serializadores  del JSR330 y el valido es el ultimo que llega.

 private  class LocalDateDeserializerEs  extends LocalDateDeserializer{
  private LocalDateDeserializerEs(){
   super(DateTimeFormatter.ofPattern("dd/MM/yyyy"));
  }
 }
 
 private class LocalDateSerializerEs extends LocalDateSerializer{
  private  LocalDateSerializerEs(){
   super(false,DateTimeFormatter.ofPattern("dd/MM/yyyy"));
  }
 }
 
 private class JSR310ModuleEs extends SimpleModule{
  public JSR310ModuleEs() {
   super(PackageVersion.VERSION);
         addDeserializer(LocalDate.class,new LocalDateDeserializerEs());
         addSerializer(LocalDate.class, new LocalDateSerializerEs());
  }
 }

 @Override
 public void configureMessageConverters(
   List> converters) {
  super.configureMessageConverters(converters);
  Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
     builder
      .indentOutput(true)
      .dateFormat(new SimpleDateFormat("dd-MM-yyyy")
      );
     converters.add(new MappingJackson2HttpMessageConverter(
         builder
          .build()
          .registerModule(new JSR310ModuleEs())));
     converters.add(new MappingJackson2XmlHttpMessageConverter(
         builder.createXmlMapper(true)
          .build()
          .registerModule(new JSR310ModuleEs())));
 }
El resultado de esta configuración:

En JSON
 {
  "numero" : 1,
  "cadena" : "cadena",
  "descripcion" : "descripcion",
  "fecha" : "01-05-2015",
  "fechaLocal" : "01/05/2015",
  "fechaTime" : "2015-05-01T21:38:45.748"
}
En Xml

<EjemploJson>
<numero>1</numero>
<cadena>cadena</cadena>
<descripcion>descripcion</descripcion>
<fecha>02-05-2015</fecha>
<fechaLocal>02/05/2015</fechaLocal>
<fechaTime>2015-05-02T10:40:21.485</fechaTime>
</EjemploJson>
Podemos ver que la fecha que es un date, se formatea con los guiones la fechaLocal es un LocalDate y se formatea con los /. y el LocalDateTime, no lo hemos puesto un formateo y por eso sale asi. (Si seguimos los mismos pasos que al anterior podemos poner el que nos interese).
Nota: Al registrar un serializador mas de una vez sobre la misma clase, la ultima es la que prevalece, pero hay  que tener en cuenta que los de JSR330 se registran cuando se realiza el Build.