สวัสดีทุกคน! กาลครั้งหนึ่งในกาแล็กซีอันไกลโพ้น มีการค้นพบ JSON ที่ยาวมาก... และฉันก็ขี้เกียจเกินไปที่จะสร้าง POJO สำหรับมัน และฉันถามตัวเองว่า: ลองนึกภาพสถานการณ์ที่ฉันได้รับคำตอบในรูปแบบ JSON เช่น อัตราแลกเปลี่ยน JSON มีหลายช่อง และฉันต้องการ 2 ช่อง และตอนนี้ฉันอยากจะรู้ - ฉันสามารถสร้างคลาสที่มีฟิลด์ที่ฉันต้องการและลองแยกวิเคราะห์ json นี้ลงในคลาสอ็อบเจ็กต์ได้หรือไม่? แจ็คสันจะเข้าใจสิ่งที่ฉันต้องการจากเขาไหม? แล้วถ้าเขาเข้าใจและสามารถทำแบบนี้ได้ เขาจะทำยังไงให้ถูกต้องมากขึ้น และอะไรจะได้ผลเร็วขึ้น? ดังนั้น สำหรับคำถามที่ฉันมีเกี่ยวกับการรับรู้ของ JSON และแจ็คสัน แจ็คสันจะเข้าใจทุกอย่าง เขาฉลาด. เขาแค่ต้องการความช่วยเหลือเล็กน้อยในเรื่องนี้ เราสร้าง POJO ซึ่งเป็นคลาส Java ปกติ ซึ่งจะอธิบายตัวแปรที่เราต้องการจาก JSON ฉันจะบอกทันทีว่าสำหรับสิ่งนี้ เป็นที่พึงปรารถนาอย่างยิ่งที่จะศึกษา JSON เอง ซึ่งเรากำลังเขียนคลาส (ส่วนใหญ่แล้วมันจะมีคลาสที่ซ้อนกันซึ่งจำเป็นต้องสร้างด้วย) ต่อไป เมื่อใช้คำอธิบายประกอบ @JsonCreator เหนือตัวสร้าง เราจะแสดงให้เห็นว่าจำเป็นต้องกรอกข้อมูลฟิลด์ของคลาสนี้จาก JSON ในพารามิเตอร์ตัวสร้าง เราสามารถระบุฟิลด์ Json ที่จะกำหนดให้กับฟิลด์คลาสโดยใช้คำอธิบายประกอบ @JsonParam("JsonFieldName") หากมีฟิลด์ใน json มากกว่าที่เราต้องการ (และนี่คือคำถามของฉัน แต่เดิม) เราต้องเตือนเกี่ยวกับเรื่องนี้และอธิบายว่าเราไม่ต้องการฟิลด์ที่เหลือ สำหรับสิ่งนี้ เราใช้คำอธิบายประกอบ @JsonIgnoreProperties(ignoreUnknown=true) จากนั้นเมื่อเจอช่องที่ไม่รู้จักโปรแกรมจะไม่ล่ม แล้วก็ดรัมโรล...! เรามีคลาสอ็อบเจ็กต์ที่มีการกรอกฟิลด์ (ใช่แล้ว ตรงกับที่เราต้องการ) และเราสามารถใช้มันได้ ในตอนแรก ฉันเขียนชั้นเรียนแยกของตัวเองด้วยวิธีคงที่ซึ่งดึงเอาคุณค่าที่ฉันต้องการออกมา และหากจำเป็น ก็นำมันมาสู่รูปแบบอันศักดิ์สิทธิ์ มันเป็นงานบ้าน มันเป็นงานฝีมือ เหล่านี้คือไม้ค้ำยัน นี่คือคลาสพร้อมวิธีการ:
public class Methods {
public static double findRes(String body, String need){
int begin = body.indexOf(need);
int end = body.indexOf(",", begin);
String res = body.substring(begin, end);
String res2 = res.substring(res.indexOf(":")+2);
double finalRes = Double.parseDouble(res2);
return finalRes;
}
public static String findUrl(String body, String need){
int begin = body.indexOf(need) + need.length();
int end = body.indexOf(",", begin);
String res = body.substring(begin, end);
String res2 = res.substring(res.indexOf(":")+1);
return res2;
}
}
การใช้ Jackson สะดวกและอ่านง่ายกว่ามาก (อย่างน้อยก็สวยกว่ามาก) ในการสนทนากับพี่ชายของเรา พวกเขายืนยันว่า: ในกรณีของเรา แจ็คสัน ควรใช้ห้องสมุดมากกว่า
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.stereotype.Component;
@Component
@JsonIgnoreProperties(ignoreUnknown = true)
public class CurrencyPojo {
private Rates rates;
public CurrencyPojo() {
}
@JsonCreator
public CurrencyPojo(@JsonProperty("rates") Rates rates) {
this.rates = rates;
}
public Rates getRates() {
return rates;
}
public void setRates(Rates rates) {
this.rates = rates;
}
@Override
public String toString() {
return "CurrencyPojo{" +
"rates=" + rates +
'}';
}
@Component
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Rates {
private double rub;
private double inr;
private double eur;
public Rates() {
}
@JsonCreator
public Rates(@JsonProperty("RUB") double rub,
@JsonProperty("INR") double inr,
@JsonProperty("EUR") double eur) {
this.rub = rub;
this.inr = inr;
this.eur = eur;
}
public double getRub() {
return rub;
}
public void setRub(double rub) {
this.rub = rub;
}
public double getInr() {
return inr;
}
public void setInr(double inr) {
this.inr = inr;
}
public double getEur() {
return eur;
}
public void setEur(double eur) {
this.eur = eur;
}
@Override
public String toString() {
return "Rates{" +
"rub=" + rub +
", inr=" + inr +
", eur=" + eur +
'}';
}
}
}
ฉันอยากจะดึงความสนใจของคุณไปที่การใช้คลาสที่ซ้อนกัน ก่อนงานนี้ ฉันคิดไม่ออกว่าจะใช้พวกมันได้ =) และนี่คือตัวอย่างของ JSON ที่เข้ามา: ฉันไม่รู้วิธีสร้าง "สปอยล์" ดังนั้นมาฝึกนิ้วของเรากันดีกว่า))
{
"disclaimer": "Usage subject to terms: https://openexchangerates.org/terms",
"license": "https://openexchangerates.org/license",
"timestamp": 1638143999,
"base": "USD",
"rates": {
"AED": 3.672934,
"AFN": 95.889778,
"ALL": 107.277494,
"AMD": 483.27152,
"ANG": 1.802446,
"AOA": 585,
"ARS": 100.99011,
"AUD": 1.400119,
"AWG": 1.80025,
"AZN": 1.700805,
"BAM": 1.734322,
"BBD": 2,
"BDT": 85.804468,
"BGN": 1.727247,
"BHD": 0.377164,
"BIF": 1994.344572,
"BMD": 1,
"BND": 1.370223,
"BOB": 6.905713,
"BRL": 5.593606,
"BSD": 1,
"BTC": 0.000017488138,
"BTN": 74.895631,
"BWP": 11.828585,
"BYN": 2.560653,
"BZD": 2.015918,
"CAD": 1.27258,
"CDF": 2003.492833,
"CHF": 0.92439,
"CLF": 0.030154,
"CLP": 831.315923,
"CNH": 6.395085,
"CNY": 6.393,
"COP": 3975.845415,
"CRC": 639.731775,
"CUC": 1,
"CUP": 25.75,
"CVE": 97.95,
"CZK": 22.7447,
"DJF": 178.031664,
"DKK": 6.585348,
"DOP": 56.599119,
"DZD": 139.135508,
"EGP": 15.756894,
"ERN": 15.000155,
"ETB": 47.819833,
"EUR": 0.885541,
"FJD": 2.12473,
"FKP": 0.749595,
"GBP": 0.749595,
"GEL": 3.095,
"GGP": 0.749595,
"GHS": 6.142755,
"GIP": 0.749595,
"GMD": 52.425,
"GNF": 9472.013443,
"GTQ": 7.738789,
"GYD": 209.235741,
"HKD": 7.7981,
"HNL": 24.17051,
"HRK": 6.661782,
"HTG": 98.81349,
"HUF": 327.09539,
"IDR": 14379.716018,
"ILS": 3.185445,
"IMP": 0.749595,
"INR": 75.050444,
"IQD": 1458.680982,
"IRR": 42275,
"ISK": 130.231848,
"JEP": 0.749595,
"JMD": 155.740793,
"JOD": 0.709,
"JPY": 113.7185,
"KES": 112.535405,
"KGS": 84.774702,
"KHR": 4069.37439,
"KMF": 436.000041,
"KPW": 900,
"KRW": 1195.716418,
"KWD": 0.30268,
"KYD": 0.833396,
"KZT": 436.292325,
"LAK": 10839.499888,
"LBP": 1520.868483,
"LKR": 202.516227,
"LRD": 142.25,
"LSL": 16.236278,
"LYD": 4.615464,
"MAD": 9.244198,
"MDL": 17.763696,
"MGA": 3988.128848,
"MKD": 54.637275,
"MMK": 1790.896161,
"MNT": 2854.559306,
"MOP": 8.033255,
"MRO": 356.999828,
"MRU": 36.094075,
"MUR": 43.067396,
"MVR": 15.45,
"MWK": 816.475065,
"MXN": 21.738389,
"MYR": 4.239,
"MZN": 63.857001,
"NAD": 16.26,
"NGN": 410.875846,
"NIO": 35.230131,
"NOK": 9.0605,
"NPR": 119.833306,
"NZD": 1.465193,
"OMR": 0.385109,
"PAB": 1,
"PEN": 4.033921,
"PGK": 3.51889,
"PHP": 50.480705,
"PKR": 176.598456,
"PLN": 4.168379,
"PYG": 6826.299832,
"QAR": 3.646364,
"RON": 4.37388,
"RSD": 103.877366,
"RUB": 75.58127,
"RWF": 1024.40338,
"SAR": 3.7514,
"SBD": 8.064563,
"SCR": 14.654883,
"SDG": 438,
"SEK": 9.148279,
"SGD": 1.370086,
"SHP": 0.749595,
"SLL": 11119.30017,
"SOS": 580.721202,
"SRD": 21.52,
"SSP": 130.26,
"STD": 21187.940504,
"STN": 22.195,
"SVC": 8.750748,
"SYP": 2512.5,
"SZL": 15.967534,
"THB": 33.757117,
"TJS": 11.286041,
"TMT": 3.51,
"TND": 2.882,
"TOP": 2.277258,
"TRY": 12.378954,
"TTD": 6.78112,
"TWD": 27.866934,
"TZS": 2302.544214,
"UAH": 27.094403,
"UGX": 3563.214629,
"USD": 1,
"UYU": 44.148288,
"UZS": 10783.399861,
"VES": 4.57705,
"VND": 22678.30849,
"VUV": 111.998805,
"WST": 2.563531,
"XAF": 580.876668,
"XAG": 0.04289544,
"XAU": 0.00055691,
"XCD": 2.70255,
"XDR": 0.714635,
"XOF": 580.876668,
"XPD": 0.00055962,
"XPF": 105.673123,
"XPT": 0.00101782,
"YER": 250.249937,
"ZAR": 16.1344,
"ZMW": 17.776133,
"ZWL": 322
}
}
ในการแปลง json ให้เป็นวัตถุคลาสเราใช้ mapper:
ObjectMapper mapper = new ObjectMapper();
currencyPojo(an object нашего класса) = mapper.readValue(jsonResponse(Джсон в стринге), CurrencyPojo.class(класс, который нам нужен));
รหัสใช้งานได้ มันดึงสิ่งที่ฉันต้องการออกมาจากสิ่งที่ฉันต้องการ นี่คือผลลัพธ์ของคลาสอ็อบเจ็กต์หลังการแยกวิเคราะห์: CurrencyPojo{rates=Rates{rub=73.6944, inr=75.621547, eur=0.885436}} ฉันดีใจมาก วันที่สองฉันปรบมือให้ทั่วใบหน้าและยิ้มด้วยมือ... หรืออะไรประมาณนั้น ค่าเรตอาจแตกต่างกันเพราะว่า ข้อความ JSON และวัตถุพิมพ์จากวันที่ต่างกัน แต่โดยทั่วไปแล้วผลลัพธ์ควรมีความชัดเจน ป.ล. ฉันกำลังเขียนบทความเป็นครั้งแรก ดังนั้นอย่าตัดสินอย่างเคร่งครัด และฉันเป็นเพียงแฮกเกอร์มือใหม่ =) ฉันชอบและยอมรับคำวิจารณ์;) PS2 ฉันขอโทษสำหรับ "จดหมายจำนวนมาก" แต่ฉันพยายามนำเสนอสิ่งที่ฉันทำมาหลายวัน
GO TO FULL VERSION