ปัญหานี้ทำให้ฉันคลั่งไคล้ Spring เป็นเครื่องมือที่มีศักยภาพ แต่สิ่งง่ายๆเช่นการเขียนสตริงเอาต์พุตเนื่องจาก JSON ดูเหมือนจะเป็นไปไม่ได้หากไม่มีแฮ็กที่น่าเกลียด
วิธีแก้ปัญหาของฉัน (ใน Kotlin) ที่ฉันพบว่าสิ่งที่ล่วงล้ำน้อยที่สุดและโปร่งใสที่สุดคือการใช้คำแนะนำของคอนโทรลเลอร์และตรวจสอบว่าคำขอนั้นไปยังจุดสิ้นสุดชุดใดชุดหนึ่งหรือไม่ (โดยทั่วไปแล้ว REST API เนื่องจากเรามักต้องการส่งคืนคำตอบทั้งหมดจากที่นี่เป็น JSON และไม่สร้างความเชี่ยวชาญพิเศษในส่วนหน้าโดยพิจารณาว่าข้อมูลที่ส่งคืนเป็นสตริงธรรมดา ("Don't do JSON deserialization!") หรืออย่างอื่น ("Do JSON deserialization!")) ด้านบวกของสิ่งนี้คือคอนโทรลเลอร์ยังคงเหมือนเดิมและไม่มีแฮ็ก
supports
วิธีการทำให้แน่ใจว่าคำขอทั้งหมดที่ได้รับการจัดการโดยStringHttpMessageConverter
(เช่นแปลงที่จับเอาท์พุทของตัวควบคุมทั้งหมดที่ส่งกลับสตริงธรรมดา) จะประมวลผลและในbeforeBodyWrite
วิธีการที่เราควบคุมในกรณีที่เราต้องการที่จะขัดขวางและแปลงออกไป JSON (และแก้ไขส่วนหัวตามลำดับ)
@ControllerAdvice
class StringToJsonAdvice(val ob: ObjectMapper) : ResponseBodyAdvice<Any?> {
override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>): Boolean =
converterType === StringHttpMessageConverter::class.java
override fun beforeBodyWrite(
body: Any?,
returnType: MethodParameter,
selectedContentType: MediaType,
selectedConverterType: Class<out HttpMessageConverter<*>>,
request: ServerHttpRequest,
response: ServerHttpResponse
): Any? {
return if (request.uri.path.contains("api")) {
response.getHeaders().contentType = MediaType.APPLICATION_JSON
ob.writeValueAsString(body)
} else body
}
}
ฉันหวังว่าในอนาคตเราจะได้คำอธิบายประกอบง่ายๆซึ่งเราสามารถลบล้างสิ่งที่HttpMessageConverter
ควรใช้สำหรับผลลัพธ์ได้