Kotlin SpringBoot应用如何原样发送Unicode码点至第三方接口
问题:Kotlin SpringBoot应用发送Unicode码点(\u20ac)至第三方系统的问题
问题场景
开发Kotlin SpringBoot应用时,需在请求中发送特殊字符(如欧元符号)。测试发现发送Unicode码点\u20ac时,第三方系统可正确解析显示,该效果能通过Postman实现,但应用内无法复现。
Postman测试结果
请求体:
{ "comment": "The value is € 200 and \u20ac 300" }
第三方系统输出:
{ "comment": "The value is € 200 and \u20ac 300" }
可见Postman能将\u20ac原样发送至第三方系统。
应用代码实现
Controller代码
import org.springframework.http.HttpStatus import org.springframework.http.ResponseEntity import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RestController @RestController class TestRestController( private val restClient: RestClient ) { data class Data( val comment: String ) @PostMapping("/data-test") fun dataTest(): ResponseEntity<String> { val euroSymbol = "\u20ac" val escapedEuroSymbol = "\\u20ac" val mockData = Data( comment = "The value is $euroSymbol 200 and $escapedEuroSymbol 300" ) restClient.createRequest(mockData) return ResponseEntity.status(HttpStatus.OK).body("ok") } }
Rest Client代码
import org.springframework.cloud.openfeign.FeignClient import org.springframework.http.MediaType import org.springframework.web.bind.annotation.PostMapping import org.springframework.web.bind.annotation.RequestBody import javax.validation.Valid @FeignClient( value = "restClient", url = "https://envpqi8gjjxx8.x.pipedream.net/", ) interface RestClient { @PostMapping( value = ["/test"], consumes = [MediaType.APPLICATION_JSON_VALUE] ) fun createRequest( @RequestBody request: @Valid TestRestController.Data ): String? }
ObjectMapper配置
objectMapper.setTimeZone(TimeZone.getDefault()) objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL) objectMapper.registerModules(kotlinModule(), JavaTimeModule())
当前应用输出结果
第三方系统接收内容:
{ "comment": "The value is € 200 and \\u20ac 300" }
直接使用\u20ac出现乱码,转义为\\u20ac后被发送为\\u20ac,无法达到Postman的效果。
解决方案
1. 调整Jackson序列化配置
默认Jackson会以UTF-8编码输出特殊字符,而非转义为Unicode码点。需添加配置让Jackson将非ASCII字符转义为Unicode格式:
objectMapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true)
2. 验证修改效果
修改后可简化mockData的定义:
val mockData = Data( comment = "The value is $euroSymbol 200 and $euroSymbol 300" )
此时第三方系统接收内容会变为:
{ "comment": "The value is \u20ac 200 and \u20ac 300" }
与Postman的效果一致。
3. 注意事项
- 若仅需特定字符转义而非全部非ASCII字符,可自定义
CharacterEscapes实现,但开启ESCAPE_NON_ASCII已能满足多数场景需求。 - 确保FeignClient使用的是配置后的ObjectMapper,Spring Boot默认会自动注入自定义配置的ObjectMapper到Feign中,若有自定义Feign配置需确认引用正确的Bean。
内容的提问来源于stack exchange,提问作者firstpostcommenter
相关产品推荐
相关产品推荐

