J'apprécie la négociation automatique du contenu HTTP de JAX-RS (spécifiquement Jersey), c'est-à-dire sa capacité à acheminer mes ressources par les en-têtes "Accept" et/ou "Content-Type". Mais je trouve que parfois cela ne me donne pas assez de contrôle lorsqu'il y a un conflit.
Par exemple, considérons les points d'extrémité suivants :
@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);
}
}
J'obtiendrai des résultats différents entre Firefox et Chrome. Firefox établira une correspondance avec le point de terminaison HTML, tandis que Chrome déclenchera le point de terminaison XML lorsque je naviguerai chacun vers l'URL du point de terminaison. La différence entre les deux est l'ordre des types MIME énumérés dans leurs en-têtes Accept. Chrome envoie ce qui suit :
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
Alors que dans Firefox, le HTML apparaît en premier :
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
Il semble logique qu'elle corresponde à la première entrée lorsque toutes les entrées ont la même pondération. Mais dans mon cas, j'obtiens des résultats différents de ceux que je souhaite. Il serait donc intéressant de déterminer une meilleure méthode pour départager les ex-aequo.
Ma question : À moins d'injecter des informations d'en-tête dans ces méthodes et d'effectuer moi-même le traitement du type de média, existe-t-il un moyen de "modifier les poids", pour ainsi dire, en cas d'égalité ? Par exemple, puis-je lui dire de toujours privilégier le XML par rapport au HTML ? Mes clients RESTful sont très explicites quant au type qu'ils veulent récupérer, mais les navigateurs sont notoirement négligents avec les en-têtes Accept. (Personnellement, je pense qu'ils devraient pondérer le HTML légèrement au-dessus du XML car c'est ce que les utilisateurs attendent, mais il est un peu tard pour cela).
Par ailleurs, puis-je effectuer ma propre négociation de contenu personnalisé une seule fois dans un endroit centralisé ? Je ne suis pas opposé à l'écriture manuelle de cette logique, mais pas si cela implique de l'appliquer à chaque instance de mes ressources. JAX-RS dispose-t-il d'un concept permettant d'ajouter un filtre au pipeline afin de modifier les demandes avant qu'elles ne soient acheminées ?