web services - services - GET Solicitar con Content-Type y aceptar encabezado con JAX-RS Jersey 2.2
restful services java example (3)
El encabezado Accept
le dice al servidor qué quiere tu cliente en la respuesta . El encabezado Content-Type
le dice al servidor lo que el cliente envía en la solicitud . Entonces los dos no son lo mismo.
Si el servidor solo acepta application/json
, debe enviar una solicitud que especifique el contenido de la solicitud:
Content-Type: application/json
Es por eso que tu código editado funciona.
Editar
En su primer código, utiliza WebTarget.request(MediaType... acceptedResponseTypes)
. Los parámetros de este método
definir los tipos de medios de respuesta aceptados.
Está utilizando Innvocation.Builder.accept(MediaType... mediaTypes)
en el resultado de esta llamada a método. Pero accept()
no agrega un nuevo encabezado, no es necesario en su primer código.
Nunca especifica el tipo de contenido de su solicitud. Como el servidor espera un encabezado Content-Type
, responde con 415
.
Intento acceder a un servicio web de datos abiertos que me proporciona infos de tráfico. La documentación dice que las solicitudes deben ser GET
y deben contener Accept: application/json
y Content-Type: application/json
. No entiendo por qué necesitan el tipo de Content-Type
pero está bien:
Traté de recuperar datos solo con el encabezado Accept:
pero siempre obtengo un 415 Unsupported Media Type
. Ahora lo estoy intentando de esta manera (pero no estoy seguro de si realmente estoy configurando ambos encabezados correctamente):
String entity = ClientBuilder.newClient().target(liveDataURI)
.path(liveDataPath)
.request(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.get(String.class);
Como ve, estoy usando Jersey 2.2 y sigo recibiendo un tipo de medio 415 Unsupported Media Type
.
EDITAR
Así que lo hice funcionar, pero no entiendo por qué. ¿No es igual accept(MediaType.APPLICATION_JSON)
y el header("Content-type","application/json")
?
String responseEntity = ClientBuilder.newClient()
.target(liveDataURI)
.path(liveDataPath)
.request(MediaType.APPLICATION_JSON)
.header("Content-type", "application/json")
.get(String.class);
¿No es igual
accept(MediaType.APPLICATION_JSON)
y elheader("Content-type","application/json")
?
No, ellos son diferentes.
Así es como están relacionados:
Client Server
(header) (class/method annotation)
====================================================
Accept <---> @Produces
Content-Type <---> @Consumes
El servidor consume lo que recibe del cliente en el cuerpo (su formato se especifica en Content-Type
) y produce lo que el cliente acepta (su formato se especifica en Accept
).
Ejemplo :
- el cliente envía los siguientes encabezados:
-
Content-Type
=text/xml
(envía un XML en el cuerpo) -
Accept
=application/json
(espera obtener un JSON como respuesta)
-
- el servidor necesita tener al menos las siguientes anotaciones para el método correspondiente (las anotaciones se toman del nivel de clase, si no se mencionan explícitamente para ese método):
-
@Consumes(MediaType.TEXT_XML)
(recibe un XML del cliente) -
@Produces(MediaType.APPLICATION_JSON)
(envía un JSON al cliente)
-
Obs :
El servidor puede ser más flexible, configurándose para obtener / producir múltiples formatos posibles.
Por ejemplo: un cliente puede enviar un XML mientras que otro puede enviar un JSON al mismo método si tiene la siguiente anotación:
@Consumes({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
.Los valores de
MediaType
son solo constantes deString
:public final static String APPLICATION_JSON = "application/json"; public final static String TEXT_XML = "text/xml";
Puede usar ContainerResponseFilter
para establecer el encabezado Accept predeterminado si no se proporciona en la solicitud de entrada.
@Provider
public class EntityResponseFilter implements ContainerResponseFilter {
private MediaType getExternalMediaType(){
MediaType mediaType = new MediaType("application", "vnd.xxx.resource+json")
return mediaType;
}
@Override
public void filter( ContainerRequestContext reqc , ContainerResponseContext resc ) throws IOException {
MediaType mediaType = getExternalMediaType();
List<MediaType> mediaTypes = reqc.getAcceptableMediaTypes();
if( mediaTypes.contains(mediaType) ) {
resc.setEntity( resc.getEntity(), new Annotation[0], mediaType );
}
// ...
}
}