java - 使用 Feign 客户端发布未知类的 json

标签 java spring kotlin feign

我的服务必须将 json 数据重定向到另一个服务。在我在 feign 客户端上看到的所有示例中,发送者都知道发送对象的数据类型,因此它看起来像这样:

@RequestMapping("some/path", consumes = [MediaType.APPLICATION_JSON_VALUE])
interface UploadClient {

    @PostMapping("upload")
    fun upload(book: Book): Long
}

我的问题是我没有 Book 类,我只需要转发 json。我尝试用 String 来做到这一点,如下所示:

客户端接口(interface):

@RequestMapping("some/path")
interface UploadClient {

    @PostMapping("/upload", consumes = arrayOf(MediaType.APPLICATION_JSON_VALUE))
    fun import(@RequestBody strangeData: String): Long

}

假装工厂:

class DefaultFeignClientFactory() : FeignClientFactory {

override fun <T> getClient(target: Class<T>, url: String): T {
    return registry.getOrPut(target) {
        Feign.builder()
            .target(target, url)
    } as T
}

}

客户端使用 OSGi 实例化:

  <bean id="uploadClient" factory-ref="feignClientFactory" factory-method="getClient">
    <argument value="com.blah.blahblah.UploadClient"/>
  </bean>

与接收端相同的接口(interface)是:

 @RequestMapping("some/path")
 interface Loader {

     @PostMapping("/upload")
     fun import(@RequestBody myBooks: Collection<Book>): Long

 }

如果我直接将 json 扔到接收器中(curl/postman/etc),它会反序列化它并且工作正常。 将字符串传递给假客户端是可行的,但不幸的是,接收者无法以这种方式反序列化它。 所以我尝试将其更改为 byte[] (Kotlin 中的 ByteArray):

    @PostMapping("/upload", consumes = arrayOf(MediaType.APPLICATION_JSON_VALUE))
    fun import(@RequestBody strangeData: ByteArray): Long

它会出现org.springframework.web.HttpMediaTypeNotSupportedException消息:不支持的媒体类型 MediaType.APPLICATION_OCTET_STREAM_VALUEMediaType.ALL_VALUE 也有同样的运气(实际上 ALL_VALUE 因其他一些错误而失败) - 数据不会以任何形式发送到接收器服务。

在这些情况下我必须选择什么 Java 数据类型和什么 MediaType? 提前致谢。

最佳答案

声明您的方法接受通用 JSON 的一种方法是使用 Jackson 的 JsonNode作为您的参数类型。

@RequestMapping(value = ["some/path"], consumes = [MediaType.APPLICATION_JSON_VALUE])
interface UploadClient {

    @PostMapping("upload")
    fun upload(@RequestBody book: JsonNode): Long
}

这样,您就可以发布具有任意嵌套的 JSON 对象、JSON 数组、字符串、数字或 boolean 值。这是一个例子:

val book: ObjectNode = JsonNodeFactory.instance.objectNode()
        .put("authors", JsonNodeFactory.instance.arrayNode()
                .add("John Doe")
                .add("Jane Doe"))
        .put("title", "First Book about the Does")
        .put("year", 2018)

val id = uploadClient.upload(book)

这相当于下面的请求

POST /some/path HTTP/1.1
Host: localhost:8080
Content-Type: application/json

{
  "authors": ["John Doe", "Jane Doe"],
  "title": "First Book about the Does",
  "year": 2018
}

使用 JsonNode 也可以在服务器端工作。

关于java - 使用 Feign 客户端发布未知类的 json,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51481115/

相关文章:

kotlin - 在 Compose 中使用 Text() 时如何获取文本的字体大小?

java - 在 Rest Web 方法中传递 JSON 对象

Java:安卓开发: "The method getHolder() is undefined for the type GameView"

java - 从 DAO 获取值以在 JSP 中使用

java - 如何使用 Hibernate 保留枚举类型字段?

generics - 使用 "any of"而不是 "all of"的 Kotlin 通用约束

java - 生成对象的所有设置/获取

java - 以前可以使用空的 keystore 密码吗?

java - Spring - 调用了错误的方法

android - 地理围栏数据在转换时为空