2014-06-30 16 views
5

È possibile che si stia interpretando erroneamente la specifica di Jersey per il tipo di supporto di una risposta quando un metodo può produrre uno di diversi. Secondo lo https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e1785, penso che quando due tipi di media elencati in un'annotazione @Produces(..) corrispondano all'intestazione-in arrivo, Jersey onorerà tutti i pesi associati a tali tipi nell'annotazione o sceglierà la prima se i pesi non decideranno un vincitore.Jersey che non rispetta le regole del tipo di media di risposta da @Produces

Il codice seguente mostra come questo non sia il comportamento nella pratica. Negli ultimi due casi, mi aspetto una risposta JSON quando la richiesta è ambigua, ma ottengo invece XML. La mia comprensione della documentazione è errata? O forse questo è un difetto in Jersey?

cose che ho provato:

  1. Rimuovere il @XmlRootElement annotazioni dal modello. Gli ultimi passano due casi ma il secondo caso diverge perché non esiste uno scrittore adatto.
  2. Restituisce Object dalla risorsa metodo. Il risultato non è un cambiamento nello stato pass/fail dei casi.
  3. Rimuovere i pesi dall'annotazione @Produces(..) della classe di risorsa (il tipo di supporto JSON è ancora elencato per primo). Il risultato non modifica lo stato di pass/fail dei casi.

Questo esempio viene creato utilizzando Jersey 2.10 e Java 1.8_05 su Ubuntu 14.04.

package demo; 

import java.net.URI; 
import java.util.Arrays; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ThreadFactory; 

import javax.ws.rs.GET; 
import javax.ws.rs.Path; 
import javax.ws.rs.Produces; 
import javax.ws.rs.client.ClientBuilder; 
import javax.ws.rs.core.MediaType; 
import javax.ws.rs.core.Response; 
import javax.xml.bind.annotation.XmlRootElement; 

import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory; 
import org.glassfish.jersey.server.ResourceConfig; 

import com.sun.net.httpserver.HttpServer; 

public class DemonstrateAmbiguousMediaType { 

    private static final String BASE_URI = "http://localhost:8092/"; 

    public static void main(final String[] args) { 

     final HttpServer server = startServer(); 

     try { 

      /* 
      * These cases work fine. 
      */ 
      check("application/json", "application/json"); 
      check("application/xml", "application/xml"); 

      /* 
      * These cases should pass according to Jersey 
      * documentation for @Produces 
      * https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e1785 
      * but they do not. 
      */ 
      check("application/json", "application/*"); 
      check("application/json", "*/*"); 

     } finally { 
      server.stop(0); 
     } 

    } 

    private static void check(final String expected, final String... acceptTypes) { 

     final MediaType atype = fetchAs(acceptTypes).getMediaType(); 
     final String actual = atype.getType() + "/" + atype.getSubtype(); 

     System.out.println(Arrays.asList(acceptTypes) + ":" 
      + (expected.equals(actual) ? "pass" : "fail")); 

    } 

    private static Response fetchAs(final String[] acceptable) { 

     return ClientBuilder.newClient() 
          .target(BASE_URI) 
          .path("model") 
          .request() 
          .accept(acceptable) 
          .get(); 

    } 

    private static HttpServer startServer() { 
     final ResourceConfig config = new ResourceConfig(Resource.class); 
     final HttpServer rval = JdkHttpServerFactory.createHttpServer(
       URI.create(BASE_URI), config, false); 
     rval.setExecutor(Executors.newCachedThreadPool(new ThreadFactory() { 

      @Override 
      public Thread newThread(Runnable r) { 
       final Thread rval = new Thread(r); 
       rval.setDaemon(true); 
       return rval; 
      } 
     })); 
     rval.start(); 
     return rval; 
    } 

    @XmlRootElement 
    public static class Model { 

     public int a = 10; 
     public String b = "Bbb"; 

    } 

    @Path("/model") 
    @Produces({ "application/json; q=0.9", "application/xml; q=0.5" }) 
    public static class Resource { 

     @GET 
     public Model getModel() { 
      return new Model(); 
     } 

    } 

} 
+0

Sono abbastanza convinto ora che si tratta di un problema con il codice o la documentazione di Jersey, quindi [archiviato un rapporto sul problema] (https://java.net/jira/browse/JERSEY-2564). – aztecrex

risposta

2

Ho letto male le specifiche. Nelle annotazioni @Produces(..), il nome del parametro di qualità è qs non q. Quando i parametri di qualità sono specificati correttamente, tutti i casi sopra passano.

Quando i parametri di qualità vengono rimossi, tuttavia, i casi finali non passano. Secondo la stessa documentazione di Jersey, dovrebbe essere scelto il primo elenco, ma non lo è.

Problemi correlati