2013-08-02 8 views
8

Oto Jersey usługa:Jersey. Jak wygenerować json i wyjściowe xml w zależności od url param

@GET 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public Response service(@QueryParam("format") String format) { 

    if (format.equals("json")) {...} 

    return response; 

} 

Chcę, aby wygenerować XML lub JSON odpowiedź z powrotem w zależności od url param "format".

Moja odpowiedź instancja jest formowanie przez jaxb2

wiem, czy mogę dostać xml lub json odpowiedź z powrotem, jeśli na mój klient Java/testu funkcjonalnego za pomocą tego kodu:

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_XML).get(String.class); 

lub

String content = service.path("").queryParam("myparam", "myvalue").accept(MediaType.APPLICATION_JSON).get(String.class); 

Ale muszę to zrobić w zależności od adresu URL.

+0

Jeśli można wysłać odpowiedni parametr ',' ContentType' application/json' zamiast 'json', następnie można użyć' MediaType.valueOf (format) '' uzyskać MediaType' instancji i użyj go z metodą akceptacji. –

+2

Czy Twój problem polega na tym, że nie wiesz, jak ustawić typ treści odpowiedzi lub ...? – DannyMo

Odpowiedz

4

Można ustawić typ nośnika podmiotu odpowiedzi bezpośrednio poprzez Response#ok (zakładając, że chcesz wrócić HTTP 200 status) metodę

@GET 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public Response service(@QueryParam("format") String format) { 
    return Response 
      // Set the status, entity and media type of the response. 
      .ok(entity, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML) 
      .build(); 
} 

lub za pomocą Response.ResponseBuilder#header metodę

@GET 
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) 
public Response service(@QueryParam("format") String format) { 
    return Response 
      // Set the status and Put your entity here. 
      .ok(entity) 
      // Add the Content-Type header to tell Jersey which format it should marshall the entity into. 
      .header(HttpHeaders.CONTENT_TYPE, "json".equals(format) ? MediaType.APPLICATION_JSON : MediaType.APPLICATION_XML) 
      .build(); 
} 
0

Ok. Ponieważ mówimy o rzeczach spoza schematu, pozwól mi spróbować czegoś:

Co powiesz na filtr (poszukaj com.sun.jersey.spi.container.ResourceFilterFactory) w swojej usłudze i zmień (lub dodaj lub nadpisz) nagłówek accept na podstawie twojego zapytania?

Nie najbardziej uczciwy podejście, przyznaję, ale myślę, że warto spróbować

10

to nie jest właściwy sposób, aby robić to, co wan t. Nie powinieneś używać parametru zapytania do określenia formatu wyjściowego. Zadeklarowałeś, że twoja metoda zasobów generuje zarówno XML, jak i JSON, w standardowym, zgodnym ze sposobem sposobem, aby klient wysłał prawidłowy nagłówek HTTP "Accept", który deklaruje rodzaje mediów, które mogą spożywać. Jeśli wyślą "Accept: application/json", twoja implementacja JAX-RS powinna sformatować odpowiedź twojej metody jako JSON, jeśli klient wyśle ​​"Accept: application/xml", powinien automatycznie sformatować twoją odpowiedź jako XML. Jeśli klient wskazuje, że może zaakceptować, twoja implementacja JAX-RS może wybierać dowolnie i nie powinno Cię to obchodzić. Jeśli klient zaznaczy, że nie może zaakceptować, Twój JAX-RS powinien odesłać odpowiedni kod błędu HTTP, wskazując, że nie ma sposobu na wysłanie prawidłowej odpowiedzi.

+0

Mogę ominąć coś, ale "to nie jest właściwa droga" nie jest całkowicie poprawne. Co, jeśli chce na przykład utworzyć usługę OData? Nawet w zakresie standardowym musi to być parametr zapytania formatu $ do wyboru formatu wyjściowego. –

+0

Nie wiedziałem nic o OData, dopóki nie zobaczyłem twojej odpowiedzi, nigdy jej nie używałem. Oparłem swoją odpowiedź na tym, co wiedziałem o zasadach REST w tamtym czasie. Przyjmę twoje słowo, że OData to robi, ale nadal nie wydaje się słuszne, ponieważ REST ma opierać się na wykorzystaniu standardów HTTP, a określenie formatu wyjściowego z parametru zapytania nie jest żadnym standardem HTTP, który znam. – user2456600

1

Oto pełny przykład, powyższa odpowiedź jest właściwa. Używam również powyższego podejścia, ale napotykając problem podczas pracy z List. Ustawić jednostkę takiego:

public Response getCoursesJSONOrXML(@QueryParam("type") String type){ 
    //Here we get list 
    List<Course> entity= courseService.getAllCourses(); 
    Response response = Response 
      .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON) 
      .build(); 
    return response; 
} 

Po tym ja w obliczu tego wyjątek:

MessageBodyWriter not found for media type=application/json, type=class java.util.Arrays$ArrayList, genericType=class java.util.Arrays$ArrayList 

Po przeczytaniu dokumentu Jersey, znalazłem rozwiązanie, które musimy użyć GenericEntity dla naszego kursu lista.Oto przykład

@GET 
@Produces({MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML}) 
public Response getCoursesJSONOrXML(@QueryParam("type") String type){ 
    //Here we get list 
    List<Course> list = courseService.getAllCourses(); 
    GenericEntity<List<Course>> entity = new GenericEntity<List<Course>>(list) {}; 
    Response response = Response 
      .ok(entity, "xml".equals(type) ? MediaType.APPLICATION_XML : MediaType.APPLICATION_JSON) 
      .build(); 
    return response; 
} 
Powiązane problemy