2011-04-05 57 views
11

原諒我,但我可能不熟悉正確提出此問題所需的所有術語。更改jax-rs REST服務中的內容類型

我正在使用jax-rs的org.apache.cxf.jaxrs.ext實現在Java中使用相當簡單的REST Web服務。方法頭是這樣的:

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

其中MessageContext是org.apache.cxf.jaxrs.ext.MessageContext

有兩件事情我想完成我似乎無法弄清楚:

  1. 更改內容類型,如果某些條件得到滿足(如錯誤)
  2. 變化響應的狀態代碼

我已經用改變由通過MessageContext的訪問它的響應嘗試:

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

但是這些變化與發送的響應沒有關係;有或沒有@Produces註解,設置方法內的內容類型不影響實際的內容類型(使用註釋,它當然返回「application/json」,沒有默認爲「text/html」)。

我正在返回一個簡單的字符串作爲正文。我喜歡嘗試返回一個javax.ws.rs.core.Response對象來做我想做的事,但我不太瞭解它。

我將如何更改此方法內的內容類型和/或狀態代碼?

回答

28

一種方法是引發一個WebApplicationException,如Pace所述,如果您要專門處理錯誤情況,它將起作用。如果您希望能夠隨時出於任何原因更改您的內容,那麼您將希望看看如何根據服務方法而不是字符串返回響應。返回響應可以最大限度地控制服務如何響應客戶端請求(它確實需要更多的代碼而不是返回簡單的字符串)。

這裏是你如何可以使用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

謝謝!我想知道如果這樣的事情會起作用,但你讓我知道如何做到這一點。 – Indigenuity 2011-04-05 19:34:01

1

我不確定這是否是最好的方法,但我已經完成以下內容來解決您的問題#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()); 
} 

編輯:我然後投擲得到的WebApplicationException

+0

這比我剛剛嘗試的另一個半解決方案更好:response.sendError(HttpServletResponse.SC_BAD_REQUEST,「message here」);這只是簡單地做出了迴應,並且在客戶已經收到迴應之後,該方法仍在運行。 – Indigenuity 2011-04-05 19:09:16

0

您可以編寫自己的響應濾波器來更改內容類型標題。

@Provider 
public class MimeAddingFilter implements ContainerResponseFilter { 

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

} 

此過濾器將添加「image/png」內容類型標頭。您也可以在JAX-RS響應過濾器中更改或刪除標頭。