2013-08-02 4 views
8

Hier ist ein Jersey Service:Jersey. Wie json und XML-Ausgabe abhängig von url param zu erzeugen

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

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

    return response; 

} 

Ich möchte XML oder JSON Antwort zurück zu erzeugen, abhängig von url param "Format".

Meine Antwort Instanz bildet durch jaxb2

ich weiß, ich xml oder json Antwort zurück, wenn auf meinem Java Client/Funktionstest durch mit diesem Code erhalten kann:

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

oder

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

Aber ich muss es abhängig von URL Param tun.

+0

Wenn du einen 'ContentType' Parameter senden könnte,' application/json' statt 'json', dann könnten Sie' MediaType.valueOf (Format) 'bekommen die' MediaType' Instanz und benutze es mit der accept-Methode. –

+2

Ist Ihr Problem, dass Sie nicht wissen, wie Sie den Inhaltstyp der Antwort festlegen, oder ...? – DannyMo

Antwort

4

Sie den Medientyp der Antworteinheit direkt über Response#ok einstellen kann (vorausgesetzt, Sie HTTP 200 Status zurückkehren wollen) Methode

@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(); 
} 

oder durch Response.ResponseBuilder#header Methode

@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. Da wir über Dinge außerhalb des Musters reden hier lassen Sie mich etwas versuchen:

Wie wäre es mit einem Filter (suchen Sie nach com.sun.jersey.spi.container.ResourceFilterFactory) auf Ihrem Dienst und ändern (oder hinzufügen oder überschreiben) die Annahme Header auf der Grundlage Ihrer Abfrage param?

Nicht der ehrlichste Ansatz, ich gebe es zu, aber ich denke, Sie sollten es versuchen

10

Dies ist nicht die richtige Art und Weise zu tun, was Sie wan t. Sie sollten keinen Abfrageparameter verwenden, um das Ausgabeformat zu bestimmen. Sie haben deklariert, dass Ihre Ressourcenmethode sowohl XML als auch JSON erzeugt. Der standardkonforme Weg besteht darin, den Client einen korrekten HTTP-Header "Accept" senden zu lassen, der angibt, welche Medientypen er verwenden kann. Wenn sie "Accept: application/json" einsenden, sollte Ihre JAX-RS-Implementierung die Antwort Ihrer Methode als JSON formatieren. Wenn der Client "Accept: application/xml" sendet, sollte Ihre Antwort automatisch als XML formatiert werden. Wenn der Client angibt, dass er beides akzeptieren kann, steht Ihnen auch Ihre JAX-RS-Implementierung zur Verfügung, und Sie sollten sich nicht darum kümmern. Wenn der Client angibt, dass er auch keines akzeptieren kann, sollte Ihr JAX-RS einen entsprechenden HTTP-Fehlercode zurücksenden, der angibt, dass er keine Möglichkeit hat, eine ordnungsgemäße Antwort zurückzusenden.

+0

Ich vermisse vielleicht smth/aber das "das ist nicht der richtige Weg" ist nicht ganz richtig. Was, wenn er beispielsweise einen OData Service erstellen möchte? Es ist sogar innerhalb des Standards, dass es einen Abfrageparameter $ format zum Auswählen des Ausgabeformats haben muss. –

+0

Ich wusste nichts über OData, bis ich deine Antwort sah, habe sie nie benutzt. Ich habe meine Antwort darauf basiert, was ich damals über REST-Prinzipien wusste. Ich nehme dein Wort, dass OData dies tut, aber immer noch nicht richtig erscheint, da REST auf der Nutzung von HTTP-Standards basieren sollte, und das Bestimmen des Ausgabeformats aus einem Abfrageparameter ist keine Art von HTTP-Standard, den ich kenne. – user2456600

1

Hier das vollständige Beispiel, die obige Antwort ist richtig. Ich benutze auch den obigen Ansatz, habe aber Probleme mit List. Ich habe das Unternehmen wie folgt aus:

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; 
} 

Danach bin ich mit Blick auf diese Ausnahme:

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

Nach der Lektüre Jersey Dokument, ich habe die Lösung gefunden, die wir GenericEntity für unseren Kurs verwenden müssen Liste.Hier ist das Beispiel

@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; 
} 
Verwandte Themen