2011-04-05 5 views
11

Pardonnez-moi, mais je ne connais peut-être pas tout le jargon nécessaire pour poser correctement cette question.Changer le type de contenu dans le service REST jax-rs

Je travaille sur un service web REST assez simple en Java en utilisant l'implémentation org.apache.cxf.jaxrs.ext de jax-rs. L'en-tête de la méthode est comme ceci:

@GET 
@Path("json/{fullAlias}") 
@Produces({"application/json"}) 
public String json(@PathParam("fullAlias") String fullAlias, @Context MessageContext req) 

où MessageContext est org.apache.cxf.jaxrs.ext.MessageContext.

Il y a deux choses que je suis en train d'accomplir que je ne peux pas sembler comprendre:

  1. Modifier le type de contenu si certaines conditions sont remplies (par exemple pour une erreur)
  2. changement le code d'état de la réponse

J'ai essayé d'utiliser changer la réponse en y accédant par le MessageContext:

HttpServletResponse response = req.getHttpServletResponse(); 
response.setContentType("text/plain") 
response.setStatus("HttpServletResponse.SC_BAD_REQUEST); 

Mais ces changements n'ont aucune incidence sur la réponse envoyée; avec ou sans l'annotation @Produces, la définition du type de contenu dans la méthode n'affecte pas le type de contenu réel (avec l'annotation, il renvoie bien sûr "application/json", sans "text/html" par défaut). Je renvoie une corde simple comme le corps. Je me suis amusé à essayer de retourner un objet javax.ws.rs.core.Response pour faire ce que je veux, mais je ne sais pas trop à ce sujet.

Comment changer le type de contenu et/ou les codes d'état à l'intérieur de cette méthode?

Répondre

28

Une approche consiste à lancer une exception WebApplicationException, telle que décrite par Pace, qui fonctionnera si vous souhaitez gérer spécifiquement une condition d'erreur. Si vous cherchez à modifier votre contenu à tout moment et pour quelque raison que ce soit, vous devriez jeter un coup d'œil sur le retour d'une réponse à la suite de votre méthode de service plutôt que sur une chaîne. Renvoyer une réponse vous donne le plus de contrôle sur la façon dont votre service répond à la demande du client (il nécessite plus de code que de renvoyer une chaîne simple).

Voici un exemple de la façon dont vous pouvez utiliser l'objet Response:

@GET 
@Path("json/{fullAlias}") 
public Response json(@PathParam("fullAlias") String fullAlias, @Context MessageContext req) { 
    ... 
    if (success) { 
     ResponseBuilder rBuild = Response.ok(responseData, MediaType.APPLICATION_JSON); 
     return rBuild.build(); 
    } 
    else { 
     ResponseBuilder rBuild = Response.status(Response.Status.BAD_REQUEST); 
     return rBuild.type(MediaType.TEXT_PLAIN) 
        .entity("error message") 
        .build(); 
    }  
} 
+0

Merci!Je me demandais si quelque chose comme ça fonctionnerait, mais vous me laissez savoir comment le faire. – Indigenuity

1

Je ne sais pas si c'est la meilleure approche, mais j'ai fait ce qui suit pour résoudre votre question # 1.

public WebApplicationException createStatusException(String statusMessage) { 
    ResponseBuilder rb = Response.noContent(); 
    rb = rb.type(MediaType.TEXT_PLAIN); 
    rb = rb.status(Status.BAD_REQUEST); 
    rb = rb.entity(statusMessage); 
    return new WebApplicationException(rb.build()); 
} 

EDIT: Je puis jeté le WebApplicationException résultant.

+0

Cela fonctionne mieux qu'une autre demi-solution que je viens d'essayer: response.sendError (HttpServletResponse.SC_BAD_REQUEST, "message here"); Ceci a simplement commis une réponse, et la méthode a été laissée en fonctionnement après que le client ait déjà reçu une réponse. – Indigenuity

0

Vous pouvez écrire votre propre filtre de réponse à changer l'en-tête de type de contenu.

@Provider 
public class MimeAddingFilter implements ContainerResponseFilter { 

    @Override 
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) 
     throws IOException { 
     responseContext.getHeaders().add("Content-Type", "image/png"); 
    } 

} 

Ce filtre ajoute l'en-tête de type de contenu "image/png". Vous pouvez également modifier ou supprimer des en-têtes dans les filtres de réponse JAX-RS.

Questions connexes