You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 05:27:19