【问题标题】:How to convert String containing JSON object to actual JSON using Java如何使用 Java 将包含 JSON 对象的字符串转换为实际的 JSON
【发布时间】:2020-07-04 23:29:34
【问题描述】:

我已经研究这个问题超过 3 天,但找不到任何可解决的解决方案。我的 android 项目向我的 gcloud 函数发出请求,该函数返回一个字符串格式的字符串响应:

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

我能够将字符串转换为 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));
                    }
                }
            }

现在我希望能够遍历 JSON 对象的列表并获取键和值。 当我运行我的解决方案时,我收到以下错误:

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)

【问题讨论】:

  • 你能把整个堆栈跟踪吗?
  • 我已经包含了它
  • 我可以看到您正在使用正则表达式,我认为问题出在此处。
  • 我该如何解决正则表达式问题
  • 嗯,错误表明正则表达式模式有问题,这可能会对stackoverflow.com/questions/25844060/… 有所帮助。如果不能解决问题,请添加模式。

标签: java json okhttp


【解决方案1】:

您似乎在 cmets 中找到了答案。不过,我认为这里有一点值得强调

首先,由于您已经决定将原始json 响应序列化为java 对象,在本例中为JSONObject,因此不再需要解析字符串的其余部分。您应该坚持使用其中一种方法来保持一致。因此,在这种情况下,方法应该是解析整个 json 字符串或使用 org.json 功能。在我个人看来,你应该继续使用org.json

使用org.json

您分享的回复格式为array/list of object

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

既然我们有arrayobjects,我们应该使用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);

现在,我们的 jsonObj 变量中有内部对象,即:

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

因此,我们可以轻松获得密钥response,这将再次成为arrayobject。我们可以轻松地对其进行迭代。

请注意,在json 中,所有键都是string,而值可以是stringnumericbooelanobject。例如,状态可以解析为整数。

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
}  

这可能比解析原始响应更天真地回答您的问题。

更进一步

看来我们已经有了InvestmentsModel 的模型类。更优雅的方法是将事物保存在它们自己的上下文中,并为pojos 创建响应。

假设我们有这样的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 + "]";
    }
}

对于响应结构,我们有:

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

然后代码变成:

        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
        }

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]]

更进一步

最后的建议是使用 swagger 来跟踪 api 并摆脱大部分样板代码。它可以用于客户端和服务器,并保持 API 文档化和清洁。请检查this 大摇大摆。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-18
    • 2018-03-05
    • 2015-05-24
    • 2012-01-22
    • 1970-01-01
    相关资源
    最近更新 更多