我的REST应用程序的响应中的JSON格式错误

时间:2017-05-23 14:17:01

标签: java json rest httpresponse

我的REST应用程序中有一个返回Response的方法。我正在使用特定的类RestResponse来个性化我的响应然后我使用'throw200Ok'来返回响应:

@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;
}

class 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}}

我的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应用程序返回'Response'。我正在使用正确的URL发出请求,我的回复是:

{
"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
}

3 个答案:

答案 0 :(得分:0)

"a": {
      "integral": true,
      "valueType": "NUMBER"
    },

在响应构建器中,您传递的是该值的数据类型,而不是传递值。 请检查响应构建逻辑。

答案 1 :(得分:0)

我找到了解决方案。

我没有在RestResponse的所有方法中传递“this”,而是传递“this.toString”。此外,我有“@Override”的'toString'方法来控制我的响应的显示。

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();
}

答案 2 :(得分:0)

这个技巧应该有效:最后,在将json对象传递给Response之前,只需将其字符串化: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;
}