[英]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 arestring
while values can bestring
,numeric
,booelan
andobject
.请注意,在
json
所有键都是string
而值可以是string
、numeric
、booelan
和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
}
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()
:输出与
InvestmentsModel
的toString()
:
[[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.