2014-06-30 3 views
5

메소드가 여러 가지 중 하나를 생성 할 수있을 때 응답의 미디어 유형에 대한 저지 사양을 잘못 해석했을 수 있습니다. https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e1785에 따르면, @Produces(..) 주석에 나열된 두 미디어 유형이 들어오는 Accept 헤더와 일치 할 때 Jersey는 주석에서 해당 유형과 관련된 가중치를 존중하며, 가중치로 승자를 결정하지 않으면 첫 번째 것을 선택합니다.저지가 @Produces의 응답 미디어 유형 규칙을 따르지 않습니다.

아래 코드는 이것이 실제로 어떻게 작동하지 않는지를 보여줍니다. 마지막 두 경우에는 요청이 모호 할 때 JSON 응답을 기대하지만 대신 XML을 얻습니다. 내 설명서에 대한 이해가 잘못 되었습니까? 또는 아마도 Jersey의 결함일까요?

상황은 내가 시도 :

  1. 모델에서 @XmlRootElement 주석을 제거합니다. 마지막으로 두 사례가 전달되지만 두 번째 사례가 분기됩니다. 적절한 작성자가 없기 때문입니다.
  2. 메서드에서 Object을 반환하십시오. 결과는 사례의 합격/불합격 상태에 변화가 없습니다.
  3. 리소스 클래스의 @Produces(..) 주석 (JSON 미디어 유형이 계속 나열 됨)의 가중치를 제거하십시오. 결과 은 사례의 합격/불합격 상태가 변경되지 않습니다.

이 예제는 Ubuntu 14.04에서 Jersey 2.10 및 Java 1.8_05를 사용하여 작성되었습니다.

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

저지 코드 또는 문서의 문제점이므로 [https://java.net/jira/browse/JERSEY-2564]에 문제 신고서를 제출 했으니까요. – aztecrex

답변

2

사양을 잘못 읽었습니다. @Produces(..) 주석에서 품질 매개 변수 이름은 qs이 아니고 q이 아닙니다. 품질 매개 변수가 올바르게 지정되면 위의 모든 사례가 통과합니다.

그러나 품질 매개 변수를 제거하면 최종 사례가 전달되지 않습니다. 동일한 저지 문서에 따르면 첫 번째 목록은 선택해야하지만 그렇지 않습니다.

관련 문제