web-dev-qa-db-ja.com

Spring MVCまたはSpring-Bootでさまざまな種類のResponseEntityを返す最良の方法は何ですか

Spring MVC 4(またはSpring-Boot)を使用して簡単な休憩アプリケーションを作成しました。コントローラー内でResponseEntityを返します。しかし、場合によっては成功したJSONを提供したいのですが、検証エラーがある場合はエラーJSONを提供したいです。現在、成功とエラーの応答はまったく異なるため、エラーと成功の2つのクラスを作成しました。コントローラー内で、内部ロジックに問題がない場合はResponseEntity<Success>を返します。それ以外の場合は、ResponseEntity<Error>を返します。それを行う方法はありますか。

SuccessおよびErrorは、成功およびエラー応答を表すために使用する2つのクラスです。

31

検証エラーを処理するには、Springの@ControllerAdviceを使用することをお勧めします。 このガイド を読んで、「Spring Boot Error Handling」というセクションから始めて、良い紹介をしてください。詳細な議論については、2018年4月に更新されたSpring.ioブログに 記事 があります。

この仕組みの簡単な概要:

  • コントローラーメソッドはResponseEntity<Success>のみを返す必要があります。エラーまたは例外応答を返す責任はありません。
  • すべてのコントローラーの例外を処理するクラスを実装します。このクラスには@ControllerAdviceの注釈が付けられます
  • このコントローラアドバイスクラスには、@ExceptionHandlerアノテーションが付けられたメソッドが含まれます
  • 各例外ハンドラーメソッドは、1つ以上の例外タイプを処理するように構成されます。これらのメソッドは、エラーの応答タイプを指定する場所です
  • 例では、検証エラーの例外ハンドラーメソッドを(コントローラーアドバイスクラスで)宣言します。戻り型はResponseEntity<Error>になります

このアプローチを使用すると、APIのすべてのエンドポイントに対して1か所でコントローラー例外処理を実装するだけで済みます。また、APIがすべてのエンドポイントにわたって均一な例外応答構造を持つことを容易にします。これにより、クライアントの例外処理が簡素化されます。

47
Mark Norman

汎用のワイルドカード<?>を返して、同じリクエストマッピングメソッドでSuccessErrorを返すことができます

public ResponseEntity<?> method() {
    boolean b = // some logic
    if (b)
        return new ResponseEntity<Success>(HttpStatus.OK);
    else
        return new ResponseEntity<Error>(HttpStatus.CONFLICT); //appropriate error code
}

@ Mark Normanの答えは正しいアプローチです

33
Saravana

わかりませんが、@ResponseEntity@ResponseBodyを使用して、2つの異なる1つを成功、2つ目を次のようなエラーメッセージを送信できます。

@RequestMapping(value ="/book2", produces =MediaType.APPLICATION_JSON_VALUE )
@ResponseBody
Book bookInfo2() {
    Book book = new Book();
    book.setBookName("Ramcharitmanas");
    book.setWriter("TulasiDas");
    return book;
}

@RequestMapping(value ="/book3", produces =MediaType.APPLICATION_JSON_VALUE )
public ResponseEntity<Book> bookInfo3() {
    Book book = new Book();
    book.setBookName("Ramayan");
    book.setWriter("Valmiki");
    return ResponseEntity.accepted().body(book);
}

詳細については、これを参照してください: http://www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity

5
km8295

次のようなジェネリックを使用せずにResponseEntityを返すことが可能です。

public ResponseEntity method() {
    boolean isValid = // some logic
    if (isValid){
        return new ResponseEntity(new Success(), HttpStatus.OK);
    }
    else{
        return new ResponseEntity(new Error(), HttpStatus.BAD_REQUEST);
    }
}
3

以下のようなオブジェクトまたは文字列でマップを使用できます。

@RequestMapping(value = "/path", 
        method = RequestMethod.GET, 
        produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public ResponseEntity<Map<String,String>> getData(){

    Map<String,String> response = new HashMap<String, String>();

    boolean isValid = // some logic
    if (isValid){
        response.put("ok", "success saving data");
        return ResponseEntity.accepted().body(response);
    }
    else{
        response.put("error", "an error expected on processing file");
        return ResponseEntity.badRequest().body(response);
    }

}
3
Ridha10

ここに私がそれをする方法があります:

public ResponseEntity < ? extends BaseResponse > message(@PathVariable String player) { //REST Endpoint.

 try {
  Integer.parseInt(player);
  return new ResponseEntity < ErrorResponse > (new ErrorResponse("111", "player is not found"), HttpStatus.BAD_REQUEST);
 } catch (Exception e) {


 }
 Message msg = new Message(player, "Hello " + player);
 return new ResponseEntity < Message > (msg, HttpStatus.OK);

}

@RequestMapping(value = "/getAll/{player}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity < List < ? extends BaseResponse >> messageAll(@PathVariable String player) { //REST Endpoint.

 try {
  Integer.parseInt(player);
  List < ErrorResponse > errs = new ArrayList < ErrorResponse > ();
  errs.add(new ErrorResponse("111", "player is not found"));
  return new ResponseEntity < List < ? extends BaseResponse >> (errs, HttpStatus.BAD_REQUEST);
 } catch (Exception e) {


 }
 Message msg = new Message(player, "Hello " + player);
 List < Message > msgList = new ArrayList < Message > ();
 msgList.add(msg);
 return new ResponseEntity < List < ? extends BaseResponse >> (msgList, HttpStatus.OK);

}
2
sharath

このように実装して、同じリクエストマッピングメソッドで成功とエラーを返すことができます。オブジェクトクラス(Javaのすべてのクラスの親クラス)を使用してください:-

public ResponseEntity< Object> method() {                                                                                                                                                                                                                                                                                                                                                                                  
    boolean b = //  logic  here   
      if (b)  
        return new ResponseEntity< Object>(HttpStatus.OK);      
    else      
        return new ResponseEntity< Object>(HttpStatus.CONFLICT); //appropriate error code   
}
1
NeeruSingh

以前はこのようなクラスを使用していました。 statusCodeは、messageに設定されたエラーメッセージにエラーがある場合に設定されます。データは、必要に応じて、マップまたはリストに保存されます。

/**
* 
*/
package com.test.presentation.response;

import Java.util.Collection;
import Java.util.Map;

/**
 * A simple POJO to send JSON response to ajax requests. This POJO enables  us to
 * send messages and error codes with the actual objects in the application.
 * 
 * 
 */
@SuppressWarnings("rawtypes")
public class GenericResponse {

/**
 * An array that contains the actual objects
 */
private Collection rows;

/**
 * An Map that contains the actual objects
 */
private Map mapData;

/**
 * A String containing error code. Set to 1 if there is an error
 */
private int statusCode = 0;

/**
 * A String containing error message.
 */
private String message;

/**
 * An array that contains the actual objects
 * 
 * @return the rows
 */
public Collection getRows() {
    return rows;
}

/**
 * An array that contains the actual objects
 * 
 * @param rows
 *            the rows to set
 */
public void setRows(Collection rows) {
    this.rows = rows;
}

/**
 * An Map that contains the actual objects
 * 
 * @return the mapData
 */
public Map getMapData() {
    return mapData;
}

/**
 * An Map that contains the actual objects
 * 
 * @param mapData
 *            the mapData to set
 */
public void setMapData(Map mapData) {
    this.mapData = mapData;
}

/**
 * A String containing error code.
 * 
 * @return the errorCode
 */
public int getStatusCode() {
    return statusCode;
}

/**
 * A String containing error code.
 * 
 * @param errorCode
 *            the errorCode to set
 */
public void setStatusCode(int errorCode) {
    this.statusCode = errorCode;
}

/**
 * A String containing error message.
 * 
 * @return the errorMessage
 */
public String getMessage() {
    return message;
}

/**
 * A String containing error message.
 * 
 * @param errorMessage
 *            the errorMessage to set
 */
public void setMessage(String errorMessage) {
    this.message = errorMessage;
}

}

お役に立てれば。

0
shazinltc