LocalDate, LocalTime, LocalDateTime เป็นเวลาและวันที่ APIs ที่จัดทำโดย Java 8 ซึ่งส่วนใหญ่ใช้เพื่อเพิ่มประสิทธิภาพการดำเนินการประมวลผลของเวลาและวันที่ใน Java 8 ก่อน อย่างไรก็ตามเมื่อเราใช้สปริงบูตหรือสปริงคลาวด์แสร้งเรามักจะพบว่าปัญหาต่าง ๆ จะเกิดขึ้นเมื่อใช้พารามิเตอร์คำขอหรือส่งคืนผลลัพธ์ ในบทความนี้เราจะพูดคุยเกี่ยวกับปัญหาที่เกิดขึ้นในสถานการณ์นี้และวิธีการแก้ปัญหา
ปรากฏการณ์ปัญหา
มาดูอาการก่อน ตัวอย่างเช่นตัวอย่างต่อไปนี้:
@springbootapplicationpublic คลาสแอปพลิเคชัน {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {springapplication.run (application.class, args); } @RestController คลาส HelloController {@postmapping ("/user") ผู้ใช้สาธารณะผู้ใช้ (@requestbody userdto userdto) โยนข้อยกเว้น {return userdto; }} @data @NoArgSconstructor @AllArgSconstructor คลาสคงที่ USERDTO {ชื่อผู้ใช้สตริงส่วนตัว; วันเกิดท้องถิ่นส่วนตัว; -รหัสด้านบนสร้างแอปพลิเคชันเว็บสปริงบูตอย่างง่ายซึ่งให้อินเทอร์เฟซเพื่อส่งข้อมูลผู้ใช้ซึ่งมีข้อมูลประเภท localDate ในเวลานี้ถ้าเราใช้ Feign เพื่อเรียกอินเทอร์เฟซนี้เราจะได้รับข้อผิดพลาดต่อไปนี้:
2018-03-13 09: 22: 58,445 เตือน [http-nio-9988-Exec-3] org.springframework.web.servlet.mvc.support.defaulthandlerexceptionResolver-ล้มเหลวในการอ่านข้อความ HTT org.springframework.http.converter.httpmessagenotreadableexception: JSON Parse ข้อผิดพลาด: ไม่สามารถสร้างอินสแตนซ์ของ java.time.localdate: ไม่พบตัวสร้างที่เหมาะสม ข้อยกเว้นที่ซ้อนกันคือ com.fasterxml.jackson.databind.jsonmappingexception: ไม่สามารถสร้างอินสแตนซ์ของ java.time.localdate: ไม่พบตัวสร้างที่เหมาะสมไม่สามารถค้นพบจากค่าวัตถุ บรรทัด: 1, คอลัมน์: 63] (ผ่านห่วงโซ่อ้างอิง: java.util.arraylist [0]-> com.didispace.userdto ["วันเกิด"]))
การวิเคราะห์และการแก้ปัญหา
สำหรับข้อความแสดงข้อผิดพลาดด้านบน JSON parse error: Can not construct instance of java.time.LocalDate: no suitable constructor found, can not deserialize from Object value รองเท้าของเด็กที่คุ้นเคยกับ Spring MVC ควรจะสามารถค้นหาข้อผิดพลาดได้ทันทีและเกี่ยวข้องกับการลดลงของ LocalDate อย่างไรก็ตามจะยังมีผู้อ่านหลายคนที่จะสับสนโดยข้อความแสดงข้อผิดพลาดนี้ java.util.ArrayList[0]->com.didispace.UserDto["birthday"] UserDto["birthday"] เราตั้งชื่อและส่งเป็นวัตถุ LocalDate มันเกี่ยวข้องกับอะไรกับวัตถุรายการ ArrayList?
เราอาจส่งคำขอด้วยตนเองผ่านบุรุษไปรษณีย์หรือข้อมูลอื่น ๆ เพื่อดูว่าเซิร์ฟเวอร์ส่งคืนอะไร ตัวอย่างเช่นคุณสามารถทำการร้องขอตามภาพต่อไปนี้:
จากรูปด้านบนเราสามารถเข้าใจความสับสนที่ฉันกล่าวถึงข้างต้น ในความเป็นจริงโดยค่าเริ่มต้นสปริง MVC ทำให้ serialize localDate เป็นประเภทอาร์เรย์และเมื่อเรียกว่าการแสร้งทำมันยังคงประมวลผลตาม arrayList ดังนั้นโดยธรรมชาติแล้วมันไม่สามารถตรวจพบกับวัตถุในท้องถิ่นได้
สารละลาย
เพื่อที่จะแก้ปัญหาข้างต้นมันง่ายมากเพราะแจ็คสันยังให้ชุดโซลูชั่นอนุกรมที่สมบูรณ์สำหรับสิ่งนี้ เราจำเป็นต้องแนะนำการพึ่งพา Jackson-Datatype-JSR310 ใน pom.xml ดังนี้:
<Ederency> <roupId> com.fasterxml.jackson.datatype </groupid> <ratifactid> Jackson-Datatype-JSR310 </artifactId>
หมายเหตุ: เมื่อมีการตั้งค่า Parent of Spring Boot ไม่จำเป็นต้องระบุเวอร์ชันเฉพาะและไม่แนะนำให้ระบุเวอร์ชันเฉพาะ
ห่อหุ้มการดำเนินการตามลำดับเวลา API ของ Java 8 ในโมดูลนี้และการใช้งานเฉพาะของมันอยู่ในคลาสนี้: com.fasterxml.jackson.datatype.jsr310.javatimemodule (หมายเหตุ: บางรุ่นก่อนหน้านี้ การพึ่งพาเราจำเป็นต้องเพิ่มโมดูลการทำให้เป็นอนุกรมนี้ในคลาสหลักของแอปพลิเคชันด้านบนและในเวลาเดียวกันเปิดใช้งานรูปแบบมาตรฐาน ISO 8601:
@BeanPublic ObjectMapper serializingObjectMapper () {ObjectMapper ObjectMapper = New ObjectMapper (); ObjectMapper.disable (serializationFeature.write_dates_as_timestamps); ObjectMapper.registerModule (Javatimemodule ใหม่ ()); ส่งคืน ObjectMapper;}ในเวลานี้เมื่อเราเข้าถึงอินเทอร์เฟซตอนนี้มันไม่ได้เป็นประเภทอาร์เรย์อีกต่อไปและข้อผิดพลาดข้างต้นจะไม่เกิดขึ้นอีกต่อไปเมื่อเราเรียกไคลเอ็นต์ปลอม
ตัวอย่างรหัส
สำหรับตัวอย่างที่เกี่ยวข้องในบทความนี้คุณสามารถดูไดเรกทอรีบทที่ 3-1-7 ในที่เก็บต่อไปนี้:
GitHub: https://github.com/dyc87112/springboot-learning
Gitee: https://gitee.com/diidispace/springboot-learning
สรุป
ข้างต้นคือปัญหาการทำให้เป็นอนุกรมของการใช้ Java 8 เวลาและวันที่ API (localDate ฯลฯ ) ในการบูตฤดูใบไม้ผลิและการแสร้งทำเป็น ฉันหวังว่ามันจะเป็นประโยชน์กับทุกคน หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับทุกคนในเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!