2017-05-23 9 views
0

レスポンスを返すRESTアプリケーションにメソッドがあります。私はレスポンスを返すように 'throw200Ok' を使用し、その後、私の応答をパーソナライズするために特定のクラスRestResponseを使用しています:RESTアプリケーションのレスポンスにJSON形式が正しくありません

@GET 
@Path("/resultat/{id}") 
public Response getResultat(@PathParam("id") int id) { 
    Response response = null; 
    RestResponse<JsonObject> restResponse = new RestResponse<JsonObject>(); 
    JsonObject jsonObject = null; 

    "Some code" 

    jsonObject = SMConverter.getResultat(socialChoices, list); 
    restResponse.setData(jsonObject); 
    response = restResponse.throw200Ok(); 

    return response; 
} 

クラスSMConverter:

:に対応する

public class SMConverter { 

private static String RESULTATS = "resultats"; 
private static String STATS = "stats"; 

/** 
* Transform a SocialChoices and a list of vote which belong to him to a JsonObject which contain 
* the result and statistics 
* @param socialChoices 
* @param list 
* @return JsonObject 
*/ 
public static JsonObject getResultat(SocialChoices socialChoices, List<Votes> list) { 

    // Recover the number of choice 
    int nbChoice = socialChoices.getValue().size(); 
    // Recover the number of voter 
    int nbVoter = list.size(); 

    try { 
     Matrix matrix = new Matrix(nbVoter, nbChoice); 
     matrix.init(); 

     // Maps used to treat the response to clear informations 
     HashMap<String, Integer> map = new HashMap<>(); 
     HashMap<Integer, String> mapReverse = new HashMap<>(); 

     for(int i = 0; i < nbChoice; i++) { 
      // Map the i index to the choice i and put it in a HashMap 
      String valueChoice = socialChoices.getValue().get(i).getName(); 
      map.put(valueChoice,i); 
      mapReverse.put(i,valueChoice); 
     } 

     System.out.println(map); 
     System.out.println(mapReverse); 

     int choiceNb = socialChoices.getData().getInt("choiceNb"); 
     boolean ordered = socialChoices.getData().getBoolean("ordered"); 
     System.out.println(choiceNb); 
     System.out.println(ordered); 

     if (choiceNb > 1 && ordered) { 
      for (int x = 0; x < nbVoter; x ++) { 
       for (int j = choiceNb; j > 0; j--) { 
        // Recover the choice of each voter 
        String choice = list.get(x).getData().getString(Integer.toString(choiceNb-j+1)); 
        // Use the map to get the index of the voter choice and map it to a tab 
        // Tab could be seen as a Matrix representing the choice of each voter 
        matrix.getTab()[map.get(choice)][x] = (byte) j; 
       } 
      } 
      System.out.println(matrix); 
      JsonObject jsonObject = treatment(ScrutinMajoritaireParSomme.voteScrutinMajoritaireParSomme(matrix), mapReverse); 
      System.out.println(jsonObject); 

      return jsonObject; 
     } else if (!ordered) { 
      System.out.println("ok ok"); 
      for (int x = 0; x < nbVoter; x ++) { 
       for (int j = choiceNb; j > 0; j--) { 
        // Recover the choice of each voter 
        // choiceNb-j+1 : because j start at choiceNb and not 1 
        String choice = list.get(x).getData().getString(Integer.toString(choiceNb-j+1)); 
        // Use the map to get the index of the voter choice and map it to a tab 
        // Tab could be seen as a Matrix representing the choice of each voter 
        matrix.getTab()[map.get(choice)][x] = 1; 
       } 
      } 
      System.out.println(matrix); 
      JsonObject jsonObject = treatment(ScrutinMajoritaireParSomme.voteScrutinMajoritaireParSomme(matrix), mapReverse); 
      System.out.println(jsonObject); 

      return jsonObject; 
     } 

    } catch (MatrixFormatException e) { 
     e.printStackTrace(); 
    } 

    return null; 
} 

/** 
* Transform a result to a clear and readable JsonObject 
* @param resu 
* @param map 
* @return 
*/ 
public static JsonObject treatment(Resultat resu, HashMap<Integer, String> map) { 

    JsonObjectBuilder resultats = Json.createObjectBuilder(); 
    JsonObjectBuilder stats = Json.createObjectBuilder(); 

    // For each result set the ranking and the choice to a readable name 
    for (int i = 0; i < resu.getResultats().size(); i++) { 
     resultats.add(Integer.toString(i+1),map.get(resu.getResultats().get(i+1))); 
    } 

    // For each statistics transform the key index to a readable name 
    for (int j = 0; j < resu.getStats().size(); j++) { 
     stats.add(map.get(j),resu.getStats().get(j)); 
    } 

    JsonObject value = Json.createObjectBuilder() 
      .add(RESULTATS,resultats.build()) 
      .add(STATS,stats.build()) 
      .build(); 

    return value; 
} 
} 

私の 'jsonObject' 変数を

{"resultats":{"1":"a"},"stats":{"a":3,"b":1,"c":0}} 

私のレスポンスをパーソナライズするためのMy RestResponseクラス。私はレスポンスを返す使用している方法「throw200Ok()」:

public class RestResponse<T> implements Serializable { 
private int httpErrorCode; 
private T data; 
private String errorMessage; 
public static final String MEDIA_TYPE = MediaType.APPLICATION_JSON + ";charset=utf-8"; 


public RestResponse(){ 
    httpErrorCode = 200; 
} 

/** 
* Constructor by parameter 
* @param httpErrorCode 
* @param data 
* @param errorMessage 
*/ 
public RestResponse(int httpErrorCode, T data, String errorMessage) { 
    this.httpErrorCode = httpErrorCode; 
    this.data = data; 
    this.errorMessage = errorMessage; 
} 

public Response throw200Ok() { 
    setHttpErrorCode(200); 
    return Response.ok(this).type(MEDIA_TYPE).build(); 
} 

public Response throw204NoContent(){ 
    setHttpErrorCode(204); 
    return Response.status(Response.Status.NO_CONTENT).entity(this).type(MEDIA_TYPE).build(); 
} 

public Response throw403Forbidden() { 
    setHttpErrorCode(403); 
    return Response.status(Response.Status.FORBIDDEN).entity(this).type(MEDIA_TYPE).build(); 
} 

public Response throw404NotFound(){ 
    setHttpErrorCode(404); 
    return Response.status(Response.Status.NOT_FOUND).entity(this).type(MEDIA_TYPE).build(); 
} 

public Response throw405MethodNotAllowed() { 
    setHttpErrorCode(405); 
    return Response.status(405).entity(this).type(MEDIA_TYPE).build(); 
} 

public Response throw409Conflict() { 
    setHttpErrorCode(409); 
    return Response.status(Response.Status.CONFLICT).entity(this).type(MEDIA_TYPE).build(); 
} 

public Response throw412PreconditionFailed() { 
    setHttpErrorCode(412); 
    return Response.status(Response.Status.PRECONDITION_FAILED).entity(this).type(MEDIA_TYPE).build(); 
} 

public Response throw500InternalServerError() { 
    setHttpErrorCode(500); 
    return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(this).type(MEDIA_TYPE).build(); 
} 

public int getHttpErrorCode() { 
    return httpErrorCode; 
} 

/** 
* 
* @param httpErrorCode 
*/ 
private void setHttpErrorCode(int httpErrorCode) { 
    this.httpErrorCode = httpErrorCode; 
} 

public boolean isSuccess() { 
    return httpErrorCode == 200; 
} 

public T getData() { 
    return data; 
} 

/** 
* 
* @param data 
*/ 
public void setData(T data) { 
    this.data = data; 
} 

public String getErrorMessage() { 
    return errorMessage; 
} 

/** 
* 
* @param errorMessage 
*/ 
public void setErrorMessage(String errorMessage) { 
    this.errorMessage = errorMessage; 
} 
} 

次に、私は私のRESTアプリケーションから「レスポンス」を返します。そして、私は右のURLで要求を作ってるんだし、私のREPONSEは次のとおりです。

{ 
"httpErrorCode": 200, 
"data": { 
    "resultats": { 
    "1": { 
     "chars": "a", 
     "valueType": "STRING", 
     "string": "a" 
    } 
    }, 
    "stats": { 
    "a": { 
     "integral": true, 
     "valueType": "NUMBER" 
    }, 
    "b": { 
     "integral": true, 
     "valueType": "NUMBER" 
    }, 
    "c": { 
     "integral": true, 
     "valueType": "NUMBER" 
    } 
    } 
}, 
"errorMessage": null, 
"success": true 
} 

の代わりに:

{ 
"httpErrorCode": 200, 
"data": { 
    "resultats":{"1":"a"}, 
    "stats":{"a":3,"b":1,"c":0} 
}, 
"errorMessage": null, 
"success": true 
} 
+0

この方法SMConverter.getResultat(ID) –

+0

@MikeAdamenkoが、私はそれを行っているが、私はそれは正しい「JsonObject」は「{ 『resultats』に対応して返すので、このクラスは問題ではないことを確信しているを示しています。 –

答えて

0

解決策が見つかりました。

"this"をRestResponseのすべてのメソッドに渡すのではなく、 "this.toString"を渡しています。さらに、私は自分のレスポンスの表示を制御するために、 "toString"メソッドを "@Override"しています。

return Response.status(Response.Status.ACCEPTED).entity(this.toString()).type(MEDIA_TYPE).build(); 

マイオーバーライド:

@Override 
public String toString() { 
    final StringBuilder sb = new StringBuilder("{"); 
    sb.append("\"httpErrorCode\":").append(httpErrorCode); 
    sb.append(", \"data\":").append(data.toString()); 
    sb.append(", \"errorMessage\":").append(errorMessage); 
    sb.append('}'); 
    return sb.toString(); 
} 
0
"a": { 
     "integral": true, 
     "valueType": "NUMBER" 
    }, 

応答ビルダーでは、代わりに値を渡すので、あなたがデータを渡していますその値のタイプ。 レスポンスビルドロジックを確認してください。

+0

「httpErrorCode」という属性を失っている以外は何も変わりません。「http:// www。 errorMessage 'と' success 'です。だから問題はまったく同じです。 –

+0

throw200Ok()メソッドも変更されましたか? Response.ok(データ)。 – kswaughs

+0

入手しました。必要に応じてJSONObjectが構築されていないようです。以前に提案した変更を元に戻し、jsonobjectの構築ロジックを調べてください。 – kswaughs

0

このトリックは著作必要があります。最後の最後に、レスポンスにJSONオブジェクトを渡す前に、それを文字列化:またjsonObject => jsonObject.toString()

、私はいつもあなたをお勧めします右のコンテンツタイプを使用:あなたのケースで@Produces(APPLICATION_JSON)

を、コードが必要がありますので、次のようになります。

@GET 
@Path("/resultat/{id}") 
@Produces(APPLICATION_JSON) // 2) optional 
public Response getResultat(@PathParam("id") int id) { 
    Response response = null; 
    RestResponse<JsonObject> restResponse = new RestResponse<JsonObject>(); 
    JsonObject jsonObject = null; 

    "Some code" 

    jsonObject = SMConverter.getResultat(socialChoices, list); 
    restResponse.setData(jsonObject.toString()); // 1) .toString() should do a trick! 
    response = restResponse.throw200Ok(); 

    return response; 
} 
関連する問題