简体   繁体   English

如何使用 Java 将包含 JSON 对象的字符串转换为实际的 JSON

[英]How to convert String containing JSON object to actual JSON using Java

I have stayed with the problem for more than 3 days of research but cant find any solvable solution.我在这个问题上呆了超过 3 天的研究,但找不到任何可解决的解决方案。 My android project makes a request to my gcloud functions and the function returns a string response with a String format:我的 android 项目向我的 gcloud 函数发出请求,该函数返回一个字符串格式的字符串响应:

[{"response": [{"Commission": 50, "Price": 0.5, "Quantity": "20"}, {"Commission": 50, "Quantity": 20, "Price": 1}, {"Quantity": 20, "Price": 10, "Commission": 50}], "code": 200}]

I was able to convert the string to JSON and retrieve the value of the "response" key.我能够将字符串转换为 JSON 并检索“响应”键的值。

try {
                //convertion of response to json to fetch value
                JSONObject jsonObj = new JSONObject("[{"response": [{"Commission": 50, "Price": 0.5, "Quantity": "20"}, {"Commission": 50, "Quantity": 20, "Price": 1}, {"Quantity": 20, "Price": 10, "Commission": 50}], "code": 200}]");
                String code = jsonObj.getString("code");

                final String Cod = code;
                if (Cod.equals("200")){
                    String availableInv = jsonObj.getString("response");
                    availableInv = availableInv.replace("[", "");
                    availableInv = availableInv.replace("]", "");
                    String strng[] = availableInv.split("},");

                    for (String val:strng) {
                        int valLength = val.length();
                        if(!val.substring(valLength-1, valLength).contentEquals("}")) {
                            val +="}";
                        }
                        System.out.println(">>>>>>=====================response==========="+val);
                        JSONObject jsonObjInv = new JSONObject(val);
                        float price = Float.valueOf(jsonObjInv.getString("Price"));
                        float comission = Float.valueOf(jsonObjInv.getString("Commission"));
                        float quantity = Float.valueOf(jsonObjInv.getString("Quantity"));
                        myDataset.add(new InvestmentsModel(price,comission, quantity));
                    }
                }
            }

Now i want to be able to iterate through the list of the JSON object and fetch the keys and values.现在我希望能够遍历 JSON 对象的列表并获取键和值。 When i run my solution i get the following error:当我运行我的解决方案时,我收到以下错误:

2020-03-24 16:17:55.235 4959-5006/com.example.SMS E/AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
Process: com.example.SMS, PID: 4959
java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 1
},
 ^
    at java.util.regex.Pattern.compileImpl(Native Method)
    at java.util.regex.Pattern.compile(Pattern.java:1340)
    at java.util.regex.Pattern.<init>(Pattern.java:1324)
    at java.util.regex.Pattern.compile(Pattern.java:946)
    at java.lang.String.split(String.java:2384)
    at java.lang.String.split(String.java:2426)
    at com.example.SMS.Fragment.investEarnFrag_1$5.onResponse(investEarnFrag_1.java:251)
    at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
    at java.lang.Thread.run(Thread.java:764)

Seems that you find your answer in the comments.似乎您在评论中找到了答案。 However, I think there is some point which is worth to emphasize here.但是,我认为这里有一点值得强调

First of all, since you already decided to serialize your raw json response to a java object, which is JSONObject in this case, there is no point to parse the rest of the string anymore.首先,由于您已经决定将原始json响应序列化为java对象,在本例中为JSONObject ,因此没有必要再解析字符串的其余部分。 You should stick with one of the methodologies to keep it consistent.您应该坚持使用其中一种方法来保持一致。 So, in this case the methodology should be either parsing the whole json string or using org.json features.因此,在这种情况下,方法应该是解析整个json字符串或使用org.json功能。 In my personal opinion, you should keep using the org.json .在我个人看来,你应该继续使用org.json

Using org.json使用org.json

The response you shared is in form of array / list of object .您共享的响应采用array / object list的形式。

[{"response": [{"Commission": 50, "Price": 0.5, "Quantity": "20"}, {"Commission": 50, "Quantity": 20, "Price": 1}, {"Quantity": 20, "Price": 10, "Commission": 50}], "code": 200}]

Since we have array of objects , we should use JSONArray to keep our json in.由于我们有objects array ,我们应该使用JSONArray来保存我们的json

JSONArray jsonArray = new JSONArray("[{\"response\": [{\"Commission\": 50, \"Price\": 0.5, \"Quantity\": \"20\"}, {\"Commission\": 50, \"Quantity\": 20, \"Price\": 1}, {\"Quantity\": 20, \"Price\": 10, \"Commission\": 50}], \"code\": 200}]");
// just to exemplify we get the first element, this should be depending on the business logic
JSONObject jsonObj = (JSONObject) jsonArray.get(0);

Now, we have the inner object in our jsonObj variable, which is:现在,我们的jsonObj变量中有内部对象,它是:

{
  "response": [
    {
      "Commission": 50, 
      "Price": 0.5, 
      "Quantity": "20"
    }, 
    {
      "Commission": 50, 
      "Quantity": 20, 
      "Price": 1
    }, 
    {
      "Quantity": 20, 
      "Price": 10, 
      "Commission": 50
    }
  ], 
  "code": 200
}

So, we can easily get on key response which will be againg an array of object .所以,我们可以很容易地得到关键response ,这将是一个object array We can easily iterate on it.我们可以轻松地对其进行迭代。

Note that in json all keys are string while values can be string , numeric , booelan and object .请注意,在json所有键都是string而值可以是stringnumericbooelanobject For instance, status can be parsed as integer.例如,状态可以被解析为整数。

try {
    //convertion of response to json to fetch value
    JSONArray jsonArray = new JSONArray("[{\"response\": [{\"Commission\": 50, \"Price\": 0.5, \"Quantity\": \"20\"}, {\"Commission\": 50, \"Quantity\": 20, \"Price\": 1}, {\"Quantity\": 20, \"Price\": 10, \"Commission\": 50}], \"code\": 200}]");
    JSONObject jsonObj = (JSONObject) jsonArray.get(0);
    int code = jsonObj.getInt("code");
    List<InvestmentsModel> myDataset = new ArrayList<>();

    if (code == 200){
        JSONArray availableInv = jsonObj.getJSONArray("response");

        for (Object val: availableInv) {
            JSONObject value = (JSONObject) val;

            float price = value.getFloat("Price");
            float comission = value.getFloat("Commission");
            float quantity = value.getFloat("Quantity");
            myDataset.add(new InvestmentsModel(price,comission, quantity));
        }
    }
} catch (Exception e ) {
    // todo handle exception
}  

This can be a more naive answer to your question than parsing the raw response.与解析原始响应相比,这可能是对您问题的更幼稚的回答。

Taking one step further更进一步

It seems that we already have model class for InvestmentsModel .似乎我们已经有了InvestmentsModel模型类。 The more elegant approach is to keep things in their own contexts and to create for pojo s for responses.更优雅的方法是将事物保存在它们自己的上下文中,并为pojo创建响应。

Assumed we have such InvestmentsModel :假设我们有这样的InvestmentsModel

import com.fasterxml.jackson.annotation.JsonProperty;

public class InvestmentsModel {

    @JsonProperty("Price")
    private float price;

    @JsonProperty("Commission")
    private float comission;

    @JsonProperty("Quantity")
    private float quantity;

    public InvestmentsModel() {
    }

    public InvestmentsModel(float price, float comission, float quantity) {
        this.price = price;
        this.comission = comission;
        this.quantity = quantity;
    }

    public InvestmentsModel price(float price) {
        this.price = price;
        return this;
    }

    public InvestmentsModel comission(float comission) {
        this.comission = comission;
        return this;
    }

    public InvestmentsModel quantity(float quantity) {
        this.quantity = quantity;
        return this;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    public float getComission() {
        return comission;
    }

    public void setComission(float comission) {
        this.comission = comission;
    }

    public float getQuantity() {
        return quantity;
    }

    public void setQuantity(float quantity) {
        this.quantity = quantity;
    }

    @Override
    public String toString() {
        return "[price -> " + this.price + ", comission -> " + this.comission + ", quantity -> " + this.quantity + "]";
    }
}

For the response structure, we have:对于响应结构,我们有:

import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;

public class GetInvestmentsResponseModel {

    @JsonProperty("response")
    private List<InvestmentsModel> response;

    @JsonProperty("code")
    private int code;

    public GetInvestmentsResponseModel() {
    }

    public GetInvestmentsResponseModel(List<InvestmentsModel> response, int code) {
        this.response = response;
        this.code = code;
    }

    public GetInvestmentsResponseModel response(List<InvestmentsModel> response) {
        this.response = response;
        return this;
    }

    public GetInvestmentsResponseModel code(int code) {
        this.code = code;
        return this;
    }

    public List<InvestmentsModel> getResponse() {
        return response;
    }

    public void setResponse(List<InvestmentsModel> response) {
        this.response = response;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }
}

And then code becomes:然后代码变成:

        final String rawResponse = "[{\"response\": [{\"Commission\": 50, \"Price\": 0.5, \"Quantity\": \"20\"}, {\"Commission\": 50, \"Quantity\": 20, \"Price\": 1}, {\"Quantity\": 20, \"Price\": 10, \"Commission\": 50}], \"code\": 200}]";

        ObjectMapper mapper = new ObjectMapper();

        try {

            GetInvestmentsResponseModel[] responseObjects = mapper.readValue(rawResponse, GetInvestmentsResponseModel[].class);

            GetInvestmentsResponseModel responseObject = responseObjects[0];

            if(responseObject.getCode() == 200) {
                List<InvestmentsModel> investmentsModels = responseObject.getResponse();
                System.out.println(investmentsModels);
            }

        } catch (JsonProcessingException e) {
            // handle JsonProcessingException
        }

Outputs as just as in the InvestmentsModel 's toString() :输出与InvestmentsModeltoString()

[[price -> 0.5, comission -> 50.0, quantity -> 20.0], [price -> 1.0, comission -> 50.0, quantity -> 20.0], [price -> 10.0, comission -> 50.0, quantity -> 20.0]]

Take one more step further再往前走一步

The final suggestion is to use swagger to both keep track of the api and get rid of the most of the boilerplate code.最后的建议是使用 swagger 来跟踪 api 并摆脱大部分样板代码。 It can be used both clients and servers, and keeps APIs documented and clean.它可以用于客户端和服务器,并保持 API 记录和清洁。 Please check this out for swagger.请检查是否招摇。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM