2013-06-19 6 views
12

私はREST APIを使用しています。悪いJSON(例えば{sdfasdfasdf})を含むPOSTメッセージを受け取ると、Springはデフォルトのサーバーページに400 Bad Request Errorを返します。私はページを返す必要はありません、カスタムJSONエラーオブジェクトを返したいと思います。Spring MVCを使用して、悪いJSONでPOST要求を受け入れると、デフォルトの400エラーコードサーバーページが返されます。

@ExceptionHandlerを使用して例外がスローされたときにこれを行うことができます。したがって、空白のリクエストまたは空のJSONオブジェクト(たとえば{})の場合、NullPointerExceptionがスローされ、ExceptionHandlerでキャッチして何でもできます。

問題は、Springが実際には無効な構文であっても実際に例外をスローしないということです。 Tomcat、Glassfishな​​ど、サーバーからデフォルトのエラーページを返すだけです。

私の質問は、Springを "傍受して"どのようにして例外ハンドラを使用するか、代わりにJSONエラーオブジェクトを表示して返しますか?ここで

は私のコードです:

@RequestMapping(value = "/trackingNumbers", method = RequestMethod.POST, consumes = "application/json") 
@ResponseBody 
public ResponseEntity<String> setTrackingNumber(@RequestBody TrackingNumber trackingNumber) { 

    HttpStatus status = null; 
    ResponseStatus responseStatus = null; 
    String result = null; 
    ObjectMapper mapper = new ObjectMapper(); 

    trackingNumbersService.setTrackingNumber(trackingNumber); 
    status = HttpStatus.CREATED; 
    result = trackingNumber.getCompany(); 


    ResponseEntity<String> response = new ResponseEntity<String>(result, status); 

    return response;  
} 

@ExceptionHandler({NullPointerException.class, EOFException.class}) 
@ResponseBody 
public ResponseEntity<String> resolveException() 
{ 
    HttpStatus status = null; 
    ResponseStatus responseStatus = null; 
    String result = null; 
    ObjectMapper mapper = new ObjectMapper(); 

    responseStatus = new ResponseStatus("400", "That is not a valid form for a TrackingNumber object " + 
      "({\"company\":\"EXAMPLE\",\"pro_bill_id\":\"EXAMPLE123\",\"tracking_num\":\"EXAMPLE123\"})"); 
    status = HttpStatus.BAD_REQUEST; 

    try { 
     result = mapper.writeValueAsString(responseStatus); 
    } catch (IOException e1) { 
     e1.printStackTrace(); 
    } 

    ResponseEntity<String> response = new ResponseEntity<String>(result, status); 

    return response; 
} 
+1

ここのスレッドは、ほとんど何が起こっているかを説明します。http://stackoverflow.com/questions/3230358/spring-3-create-exceptionhandler-for-nosuchrequesthandlingmethodexception 基本的には、exceptionHandlerの方法が唯一その中RequestMappingsに適用されます自分のクラス。あなたのケースでは、jsonが無効であるため、リクエストはそのクラスのどのマッピングにも到達していません。 Spring 3.2の場合はHandlerExceptionResolverまたはControllerAdviceのいずれかを使用してください。 – Matt

+1

あなたに役立つかもしれない別の質問をチェックしてください - http://stackoverflow.com/questions/17183102/spring3-doesnt-work-valid-when-json-request -i-got-400-bad-request-error/17185583#17185583 –

+0

@PavelHoralこれは私の答えが記述したものです - 'HttpMessageNotReadableException'を使用していますが、どのように追加されたか、 ! – andyb

答えて

15

。これは春SPR-7439の問題として提起された - JSON(ジャクソン)@RequestBodyのマーシャリングは、厄介な例外がスローされます - 春はorg.springframework.http.converter.HttpMessageNotReadableExceptionを投げることによって春3.1M2に固定されました紛失または無効なメッセージ本文の場合

コードでは抽象的なのでResponseStatusを作成することはできませんが、この例外はSpring 3.2.0.RELEASEを使ってJetty 9.0.3.v20130506上で実行するより簡単な方法でキャッチしてテストしました。

@ExceptionHandler({org.springframework.http.converter.HttpMessageNotReadableException.class}) 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
@ResponseBody 
public String resolveException() { 
    return "error"; 
} 

と400ステータス "エラー"ストリング応答を受信しました。

不具合については、this Spring forum postで議論されました。

注:私は、突堤9.0.0.M4でテストを開始したが、それは他のいくつかの内部の問題ので、完成@ExceptionHandlerを停止し、あなたのコンテナ(Jettyは、Tomcatの、他)のバージョンに応じて、あなたが新しい取得する必要があるかもしれませんがあったあなたが使用しているどのバージョンのSpringでもうまくいくバージョンです。

+1

@PavelHoralから編集されたのは、その "個人的な"性質によって侮辱されたようです。 – andyb

+0

これは私が必要としていたものです。私は例外がスローされたことを知る方法がありませんでした...これは問題を解決しました。どうもありがとう!私は上記のMattとPavelHoralのリンクも手伝ってくれたので、よりクリーンなコントローラアーキテクチャを設計することができました。 – UpAllNight

+0

あなたはそれが働いていることを聞いていいです! @ControllerAdvice'はSpring 3.2への素晴らしい追加でした – andyb

関連する問題