2011-06-29 45 views
15

使用我非常簡單的JAX-RS服務,我使用Tomcat和JDBC領域進行身份驗證,因此我正在使用JSR 250註釋。使用JAX-RS(Jersey)和@RolesAllowed自定義HTTP狀態響應

問題是我想在HTTP狀態響應中返回一個自定義消息正文。狀態碼(403)應該保持不變。例如,我的服務如下所示:

@RolesAllowed({ "ADMIN" }) 
@Path("/users") 
public class UsersService { 

    @GET 
    @Produces(MediaType.TEXT_PLAIN) 
    @Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) 
    public String getUsers() { 
     // get users ... 
     return ...; 
    } 
} 

如果不是以「ADMIN」不同角色的用戶訪問該服務,我想改變的響應消息,類似的東西(根據媒體類型[ XML/JSON):

<error id="100"> 
    <message>Not allowed.</message> 
</error> 

目前新澤西返回了以下機身:

HTTP Status 403 - Forbidden 

type Status report 
message Forbidden 
description Access to the specified resource (Forbidden) has been forbidden. 
Apache Tomcat/7.0.12 

如何更改默認的郵件正文?有沒有辦法來處理(也許拋出)異常來建立我自己的HTTP狀態響應?

+0

完整的示例:https://www.bhaveshthaker.com/25/customize-handling-server-side-exceptions-with-error-codes-using-exceptionmapper-with-jersey-jax-rs-in-java/ – RAS

回答

17

處理這類事情的最簡單方法是拋出一個異常並註冊一個異常映射器,將其轉換爲這種情況下要發送的消息類型。因此,假設你拋出一個AccessDeniedException,那麼你將有(其中爲了清楚地均設有完整的類名)這樣的處理程序:

@javax.ws.rs.ext.Provider 
public class AccessDeniedHandler 
     implements javax.ws.rs.ext.ExceptionMapper<AccessDeniedException> { 
    public javax.ws.rs.core.Response toResponse(AccessDeniedException exn) { 
     // Construct+return the response here... 
     return Response.status(403).type("text/plain") 
       .entity("get lost, loser!").build(); 
    } 
} 

在您註冊的異常映射方式而異根據框架你」重新使用,但對於澤西島,您只需使用@Provider即可。我會讓你自己弄清楚如何生成你想要的那種錯誤文檔,但是我建議把錯誤代碼作爲某種HTTP錯誤代碼來處理(這更加RESTful ...)

+0

事情是澤西返回它的自定義403響應。由於@RolesAllowed可以處理這個問題,所以我不能拋出'AccessDeniedException'來進行授權。 HTTP錯誤代碼應該是我只想更改正文消息的一些代碼。 – Stefan

+0

我以爲你可以在Jersey中用ExceptionMapper來做到這一點;我知道你可以使用Apache CXF(儘管由於我已經認識到的原因,配置不同),所以我相信至少在測試中它是合理的,因爲它們都是JAX-RS引擎,並且這只是使用JAX-RS API ,但是我對澤西沒有直接的經驗,所以也許會有一些意想不到的事情發生。 –

9

隨着創建

@Provider 
public class MyExceptionMapper implements ExceptionMapper<WebApplicationException> { 

    @Override 
    public Response toResponse(WebApplicationException weException) { 

     // get initial response 
     Response response = weException.getResponse(); 

     // create custom error 
     MyError error = ...; 

     // return the custom error 
     return Response.status(response.getStatus()).entity(error).build(); 
    } 
} 

你還需要將包添加到您的應用程序的web.xml登記的供應商:

有可能「趕」應用程序拋出一些例外的 ExceptionMapper(的 WebApplicationException映射例外)
<init-param> 
    <param-name>com.sun.jersey.config.property.packages</param-name> 
    <param-value> 
     com.myapp.userservice; // semi-colon seperated 
     com.myapp.mappedexception 
    </param-value> 
</init-param> 
+0

我面臨同樣的問題,在我的情況下,這是一個完美的答案。謝謝Stefan! – Lars

1

REST基於HTTP構建,因此您不必更改身份驗證失敗的默認行爲。訪問資源時出現403錯誤足以讓客戶清楚地瞭解附加內容。

您的資源越符合HTTP,其他人就越能理解它。

+2

問題是可能會出現單個http錯誤的各種情況。一個可以是由AS管理的會話超時(結果在403)。另一個可以是未經授權嘗試休息資源(403)。如果您必須以不同的方式對這些錯誤進行編程式反應,那麼可以自定義這些錯誤。 – Lars

相關問題