如何使用 Java 将包含 JSON 对象的字符串转换为实际的 JSON
How to convert String containing JSON object to actual JSON using Java
我已经研究了 3 天多,但找不到任何可解决的解决方案。我的 android 项目向我的 gcloud 函数发出请求,函数 returns 一个字符串格式的字符串响应:
[{"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.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)
看来您在评论中找到了答案。不过,我觉得这里有一点值得强调。
首先,由于您已经决定将原始 json
响应序列化为 java
对象,在本例中为 JSONObject
,因此没有必要解析其余的字符串了。您应该坚持使用其中一种方法以保持一致。因此,在这种情况下,方法应该是解析整个 json
字符串或使用 org.json
特征。在我个人看来,你应该继续使用 org.json
.
使用org.json
您分享的回复格式为 array
/list
共 object
。
[{"response": [{"Commission": 50, "Price": 0.5, "Quantity": "20"}, {"Commission": 50, "Quantity": 20, "Price": 1}, {"Quantity": 20, "Price": 10, "Commission": 50}], "code": 200}]
因为我们有 array
个 objects
,我们应该使用 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
键,这将是 object
的 array
。我们可以很容易地对其进行迭代。
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
的模型 class。更优雅的方法是将事物保留在它们自己的上下文中,并为 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
}
输出与 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]]
再进一步
最后的建议是使用 swagger 来跟踪 api 并摆脱大部分样板代码。它可用于客户端和服务器,并保持 API 文档化和清洁。请检查 this 是否招摇。
我已经研究了 3 天多,但找不到任何可解决的解决方案。我的 android 项目向我的 gcloud 函数发出请求,函数 returns 一个字符串格式的字符串响应:
[{"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.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)
看来您在评论中找到了答案。不过,我觉得这里有一点值得强调。
首先,由于您已经决定将原始 json
响应序列化为 java
对象,在本例中为 JSONObject
,因此没有必要解析其余的字符串了。您应该坚持使用其中一种方法以保持一致。因此,在这种情况下,方法应该是解析整个 json
字符串或使用 org.json
特征。在我个人看来,你应该继续使用 org.json
.
使用org.json
您分享的回复格式为 array
/list
共 object
。
[{"response": [{"Commission": 50, "Price": 0.5, "Quantity": "20"}, {"Commission": 50, "Quantity": 20, "Price": 1}, {"Quantity": 20, "Price": 10, "Commission": 50}], "code": 200}]
因为我们有 array
个 objects
,我们应该使用 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
键,这将是 object
的 array
。我们可以很容易地对其进行迭代。
Note that in
json
all keys arestring
while values can bestring
,numeric
,booelan
andobject
. 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
的模型 class。更优雅的方法是将事物保留在它们自己的上下文中,并为 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
}
输出与 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]]
再进一步
最后的建议是使用 swagger 来跟踪 api 并摆脱大部分样板代码。它可用于客户端和服务器,并保持 API 文档化和清洁。请检查 this 是否招摇。