有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我研究这个问题已经三天多了,但找不到任何解决办法。我的安卓项目向我的gcloud函数发出请求,该函数返回字符串格式的字符串响应:

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

我能够将字符串转换为JSON并检索“response”键的值

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)

共 (1) 个答案

  1. # 1 楼答案

    似乎你在评论中找到了答案。然而,我认为这里有一点值得强调

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

    使用org.json

    您共享的响应是array/listof object的形式

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

    既然我们有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);
    
    

    现在,我们在jsonObj变量中有一个内部对象,它是:

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

    因此,我们可以很容易地得到response键,它将是objectarray。我们可以很容易地重复它

    Note that in json all keys are string while values can be string, numeric, booelan and object. 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
    }  
    

    对于你的问题,这可能是一个比解析原始响应更幼稚的答案

    更进一步

    似乎我们已经有了InvestmentsModel的模型类。更优雅的方法是将事情保持在自己的上下文中,并为pojo创建响应

    假设我们有这样的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是否有虚张声势