Implementación de formatos de entidades personalizados

Java™ API for RESTful Web Services (JAX-RS) permite que los desarrolladores añadan un proveedor de entidades personalizado a la aplicación. Utilice los proveedores de entidades personalizados cuando desee utilizar tipos Java para representar cuerpos de mensajes de solicitud entrantes así como para representar cuerpos de mensaje de respuestas de salida. Mediante la adición de un proveedor de entidades personalizado, puede deserializar los tipos Java personalizados de los cuerpos de mensajes y serializar cualquier tipo de medio como cuerpo de mensaje.

Acerca de esta tarea

Un proveedor de entidades personalizado se crea mediante la anotación de una clase con una anotación javax.ws.rs.ext.Provider. La clase debe implementar la interfaz javax.ws.rs.ext.MessageBodyReader o la interfaz javax.ws.rs.ext.MessageBodyWriter o ambas. Debe añadir la clase de proveedor a la lista de clases que se devuelve en el método javax.ws.rs.core.Application subclass getClasses().

Procedimiento

  1. Cree una clase Java nueva que sea su proveedor de entidades personalizado. En este procedimiento, el código de ejemplo crea un lector y un escritor para tipos com.ibm.json.java.JSONObject, de forma que puede utilizar el tipo com.ibm.json.java.JSONObject como un parámetro de entidades de solicitudes entrantes y como tipo de devolución que contenga la entidad de respuestas.
    public class MyEntityProvider {
    
    }
  2. Añada la anotación @javax.ws.rs.ext.Provider. Al añadir esta anotación está indicando al entorno de ejecución de JAX-RS que esta clases es un proveedor de JAX-RS. Si no se especifica esta anotación de proveedor, el entorno de ejecución no detectará que la clase es un proveedor personalizado.
    @javax.ws.rs.ext.Provider
    public class MyEntityProvider {
    }
  3. (opcional) Añada una anotación @javax.ws.rs.Consumes o @javax.ws.rs.Produces si desea limitar los tipos de medio a los que el proveedor de entidades da soporte. En el siguiente fragmento de código, el proveedor sólo se invoca cuando el tipo de contenido de entrada o de salida es application/json.
    @javax.ws.rs.ext.Provider
    @javax.ws.rs.Consumes("application/json")
    @javax.ws.rs.Produces("application/json")
    public class MyEntityProvider {
    
    }
  4. Implemente javax.ws.rs.ext.MessageBodyReader<T> si el proveedor de entidades debe deserializar un cuerpo de mensaje.

    Puede utilizar el tipo genérico <T> para limitar los tipos soportados por el proveedor de entidades.

    Al definir el lector de cuerpos de mensajes como javax.ws.rs.ext.MessageBodyReader<com.ibm.json.java.JSONObject>, el entorno de ejecución de JAX-RS sabe que sólo se pueden generar objetos com.ibm.json.java.JSONObject.

    Si un proveedor de entidades tiene que dar soporte a un conjunto complejo de tipos, considere la posibilidad de implementar javax.ws.rs.ext.MessageBodyReader<Object>.

    @javax.ws.rs.ext.Provider
    @javax.ws.rs.Consumes("application/json")
    @javax.ws.rs.Produces("application/json")
    public class MyEntityProvider implements 
        javax.ws.rs.ext.MessageBodyReader<com.ibm.json.java.JSONObject> {
    
    
    
        public boolean isReadable(Class<?> type, 
                                  Type genericType, 
                                  Annotation[] annotations, 
                                  MediaType mediaType) { 
            return com.ibm.json.java.JSONObject.class == type; 
        } 
    
    
        public com.ibm.json.java.JSONObject readFrom(Class<com.ibm.json.java.JSONObject> type, 
                               Type genericType, 
                               Annotation[] annotations, 
                               MediaType mediaType, 
                               MultivaluedMap<String, String> httpHeaders, 
                               InputStream entityStream) throws IOException, WebApplicationException {
            /* This InputStream reads from the entityStream and constructs the object. */
            com.ibm.json.java.JSONObject retObj = com.ibm.json.java.JSONObject.parse(entityStream);
            return retObj; 
        } 
    
    }
  5. Implemente javax.ws.rs.ext.MessageBodyWriter<T> si el proveedor de entidades debe deserializar un cuerpo de mensaje. Puede implementar las interfaces MessageBodyReader<T> y MessageBodyWriter<T> en la misma clase Java. En el siguiente fragmento de código, solo se muestra la implementación de MessageBodyWriter.
    @Provider 
    public class MyEntityProvider implements 
        MessageBodyWriter<Object> {
    
    
    
        public long getSize(Object t, 
                            Class<?> type, 
                            Type genericType, 
                            Annotation[] annotations, 
                            MediaType mediaType) { 
            /* return -1 if the content length cannot be determined */
    
            return -1; 
        } 
    
    
        public boolean isWriteable(Class<?> type, 
                                   Type genericType, 
                                   Annotation[] annotations, 
                                   MediaType mediaType) { 
            return MyType.class == type; 
        } 
    
    
        public void writeTo(Object t, 
                            Class<?> type, 
                            Type genericType, 
                            Annotation[] annotations, 
                            MediaType mediaType, 
                            MultivaluedMap<String, Object> httpHeaders, 
                            OutputStream entityStream) throws IOException, WebApplicationException { 
            entityStream.write(MyType.getBytes()); 
        } 
    
    }
  6. Añada el proveedor de entidades personalizado a la subclase de javax.ws.rs.core.Application y añada el proveedor al conjunto de clases devuelto por el método getClasses(). Puede añadir varios proveedores de entidades personalizados para el conjunto de clases devuelto.
    public class MyApplication extends javax.ws.rs.core.Application {
        public Set<Class<?>> getClasses() {
            Set<Class<?>> classes = new HashSet<Class<?>>();
            classes.add(MyEntityProvider.class);
            return classes;
        }
    }  

Resultados

Ha definido un proveedor de entidades personalizado y ha añadido este proveedor a la aplicación web JAX-RS.

Avoid trouble Avoid trouble:

Utilice las sugerencias siguientes para solucionar errores comunes durante la implementación de formatos de entidades personalizados:

No se encuentran los proveedores personalizados.
Para resolver este problema, emprenda las acciones siguientes:
  • Compruebe que el proveedor esté anotado con @javax.ws.rs.ext.Provider. Una anotación a la que le falte una clase no se registrará como proveedor.
  • Compruebe que el proveedor se añade al conjunto de clases devueltas por el método getClasses() para las subclases de la clase javax.ws.rs.core.Application.
  • Compruebe que el valor @javax.ws.rs.Produces o @javax.ws.rs.Consumes en la clase del proveedor sea correcto.
  • Compruebe que el método javax.ws.rs.ext.MessageBodyReader#isReadable o javax.ws.rs.ext.MessageBodyWriter#isWritable se haya implementado correctamente y que devuelven un valor de true cuando se utilizan estos métodos.
Las cabeceras del proveedor de entidades personalizado MessageBodyWriter o la salida no es correcto.
Para resolver este problema, emprenda las acciones siguientes:
  • Verifique que el tamaño de la respuesta en javax.ws.rs.ext.MessageBodyWriter#getSize se establece en -1 si el tamaño es desconocido o que el valor está establecido en el tamaño correcto cuando se conoce el tamaño. Los clientes pueden truncar la respuesta si el valor del tamaño es inexacto.
  • Si las cabeceras HTTP se establecen en el método javax.ws.rs.ext.MessageBodyWriter#writeTo, debe establecer las cabeceras antes de enviar el resto de respuestas HTTP. Las cabeceras HTTP se envían al principio de una respuesta. Por lo tanto, si establece las cabeceras después que se haya comenzado a enviar al cliente el cuerpo del mensaje de respuesta principal, será demasiado tarde para enviar cabeceras de respuesta.
gotcha

Icon that indicates the type of topic Task topic



Timestamp icon Last updated: last_date
http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=twbs_jaxrs_customentityformats_impl
File name: twbs_jaxrs_customentityformats_impl.html