Estoy disfrutando de la negociación automática de contenido HTTP de JAX-RS (específicamente Jersey), es decir, su capacidad para enrutar mis recursos por encabezados "Aceptar" y/o "Tipo de contenido". Pero estoy descubriendo que a veces no me da suficiente control cuando hay un conflicto.Conflictos de negociación de contenido HTTP en JAX-RS/Jersey?
Por ejemplo, considere los siguientes criterios de valoración:
@Path("/order")
public class OrderController {
@GET
@Path("{orderID: \\d+}")
@Produces("text/html")
public View getOrderView(@PathParam("orderID") long id) {
Order order = this.getOrderData(id);
return new OrderView(order);
}
@GET
@Path("{orderID: \\d+}")
@Produces({"application/json", "application/xml"})
public Order getOrderData(@PathParam("orderID") long id) {
return new OrderService.findOrder(id);
}
}
voy a obtener resultados diferentes entre Firefox y Chrome. Firefox se correlacionará con el punto final HTML, mientras que Chrome activará el punto final XML cuando navegue hacia la URL del punto final. La diferencia entre ellos es el orden de los tipos MIME enumerados en sus encabezados Aceptar. Chrome envía el siguiente:
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.107 Safari/534.13
Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Versus en Firefox que las listas HTML primera:
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
parece lógico que se correspondería con la primera entrada cuando todo se ponderan de la misma. Pero en mi caso obtengo los resultados diferentes de los que quiero, por lo que sería bueno determinar un método mejor para desempatar.
Mi pregunta: corta de la inyección de la información de cabecera en estos métodos y realizar el tipo de medio de procesamiento a mí mismo, ¿hay una manera de "ajustar los pesos" por así decirlo, en caso de empate? Por ejemplo, ¿puedo decir que siempre prevalece XML con HTML? Mis clientes RESTful son muy explícitos sobre el tipo que quieren volver, pero los navegadores son notoriamente descuidados con los encabezados Aceptar. (En lo personal creo que deberían ponderar HTML ligeramente por encima de XML ya que esto es lo que esperan los usuarios, pero es un poco tarde para eso.)
Alternativamente, puedo realizar mi propia negociación de contenido personalizado sólo una vez en algún lugar centralizado? No me opongo a escribir esta lógica de forma manual, pero no si eso significa aplicarlo a cada instancia de mis recursos. ¿JAX-RS tiene algún concepto de agregar un filtro a la canalización para modificar las solicitudes antes de que se enruten?
Gracias, el filtro de servlet parece funcionar muy bien. Curiosamente, encontré un chico que combina tus dos sugerencias; está escribiendo un filtro de servlet para poder reemplazar la extensión de archivo con un encabezado Accept. Sin embargo, hay un error tipográfico en su código, ya que su comprobación de encabezado distingue entre mayúsculas y minúsculas. Interesante sin embargo: http://www.zienit.nl/blog/2010/01/rest/control-jax-rs-content-negotiation-with-filters – mckamey
Aquí hay un filtro de servlet modificado que agrega soporte para extensiones de archivos y corrige el WebKit Aceptar el orden del encabezado. https://gist.github.com/865216 – mckamey
@mckamey estas adiciones en los comentarios que escribió deben convertirse en una respuesta porque los comentarios no están destinados a sobrevivir para siempre – hiergiltdiestfu