2017-06-05 43 views
1

這是我在其中接收學生對象中的JSON的Web服務。如何在Java Rest Web服務中處理錯誤的JSON數據:傑克遜JSON解析器無法識別的令牌

@PUT 
    @Path("/{stuId}") 
    @Consumes({MediaType.APPLICATION_JSON}) 
    public Response update(@PathParam("stuId") UUID stuUUID , Student updatedStudentInfo) { 
      return updateService.update(stuUUID, updatedStudentInfo); 
     } 

,這是學生類:

public class Student{ 

     private int id; 
     private String studentName; 
     private String Address; 

    @JsonProperty 
    public int getId() { 
     return id; 
    } 
    @JsonProperty 
    public void setId(int id) { 
     this.id = id; 
    } 
    @JsonProperty 
    public String getStudentName() { 
     return studentName; 
    } 

     . 
     . 
     . 
     . 
    } 

它工作正常,但我不能當我通過發送錯誤的JSON數據測試時的場景處理。例如,如果我這樣做

curl -v'https://localhost:9803/school/student/29374-345tr-44'-X PUT -H'Accept:application/json,text/plain,/'-H'My-API-Version:1'-H' Authorization:Basic'-H'Content-Type:application/json; charset = utf-8'--data'{「studentName」:「rock」,「Address」:723868764}'

它生成一個錯誤:

Unrecognized token '723868764': was expecting ('true', 'false' or 'null') 

現在,我怎麼處理這種情況,如果一些錯誤數據來那麼它不應該只是我想送一個發回任何錯誤或異常。

編輯1:

下面我們還可以看到正在由Java代碼生成的異常

Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'sdfsdfdsfdsf': was expecting ('true', 'false' or 'null') at 
[Source: org.glassfish.jersey.me[email protected]5c6d324d; line: 1, column: 59] 
+0

爲什麼你得到'true',false或null,它不是一個布爾對象 –

+0

你可以嘗試捕獲那個異常並且在那裏定義你自己定製的消息:'catch(JSONException e ){//在這裏添加custome ex消息e.getMessage()}'另外,無法識別的標記被拋出,因爲你已經聲明Address爲String並且可能試圖將它設置爲一個數字而不是一個String,用雙引號括起來這可能會導致錯誤消失! –

+0

@coolgirl是我通過數字而不是字符串的目的,這是我的問題,如果我發送一些錯誤的JSON數據,那麼我該如何解決它? 秒,我可以在這裏使用這個TRY CATCH,因爲這個異常是在方法的簽名級產生的,所以編譯器甚至不會進入這個方法。 – Freak

回答

2

我發現用於此兩個解決方案:
解決方案1:ExceptionMapper(球衣)

@Provider 
public class ClientExceptionMapper implements ExceptionMapper<Throwable> 
{ 
    @Override 
    public Response toResponse(Throwable ex) 
    { 

     return Response 
       .status(Response.Status.BAD_REQUEST) 
       .build(); 
    } 
} 

這裏最重要的是anotation

@provider

我不知道是否有必要或使用註解把掃描配置在web.xml中爲安全起見沒有後,讓這樣做

<servlet> 
    <servlet-name>my-servlet</servlet-name> 
    <servlet-class> 
     org.glassfish.jersey.servlet.ServletContainer 
    </servlet-class> 
    <init-param> 
     <param-name>jersey.config.server.provider.packages</param-name> 
     <param-value> 
     com.myrootpackgae.ws;com.anotherPackage.errorHandling; 
     </param-value> 
    </init-param> 
    <init-param> 
     <param-name>jersey.config.server.provider.scanning.recursive</param-name> 
     <param-value>true</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

您ExceptionMapper類應該是在同一個包的REST服務或包層次結構下。
最後但並非最不重要的,我在我的例子中使用的Throwable,但你可以具體到任何異常,例如

JsonParseException
JsonMappingException
UnrecognizedPropertyException etc ...



解決方案2:javax.ws.rs.container.ContainerResponseFilter

public class MyRestAppResponseFilter implements ContainerResponseFilter { 

     @Override 
     public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) 
       throws IOException { 

      // Remove StackTrace from all exceptions 
      Object entity = responseContext.getEntity(); 
    if (entity instanceof Throwable) { 
       responseContext.setEntity(null); 
       responseContext.setStatus(Response.Status.BAD_REQUEST.getStatusCode()); 
}   
      // TF-246 Prevent caching for privacy reasons 
      responseContext.getHeaders().add("Cache-Control", "no-cache, no-store, must-revalidate"); 
      responseContext.getHeaders().add("Pragma", "no-cache"); 
      responseContext.getHeaders().add("Expires", "Thu, 01 Jan 1970 01:00:00 CET"); 

      // TF-752 Enable CORS for WkWebView 
      responseContext.getHeaders().add("Access-Control-Allow-Origin", "*"); 
     } 
    } 


的事件偵聽器請求也可RequestEventListener WH ich提供onEvent(RequestEvent)方法。我傾向於使用解決方案#2