Spring 引导序列化 text/javascript 到 JSON
Spring Boot serialize text/javascript to JSON
我创建了以下 Kotlin 数据 class:
@JsonInclude(JsonInclude.Include.NON_NULL)
public data class ITunesArtist(val artistName: String,
val artistId: Long, val artistLinkUrl: URL)
(一个数据 class 是一个 Kotlin class,它在编译时自动生成 equals、hashcode、toString 等——节省时间)。
现在我尝试使用 Spring RestTemplate
填充它:
@Test
fun loadArtist()
{
val restTemplate = RestTemplate()
val artist = restTemplate.getForObject(
"https://itunes.apple.com/search?term=howlin+wolf&entity=allArtist&limit=1", ITunesQueryResults::class.java);
println("Got artist: $artist")
}
它失败了:
Could not extract response: no suitable HttpMessageConverter found for response type
[class vampr.api.service.authorization.facebook.ITunesArtist]
and content type [text/javascript;charset=utf-8]
很公平 - JSON 对象映射器可能需要 text/json
的 mime 类型。除了告诉 RestTemplate
映射到 String::class.java
,然后手动实例化 JacksonObjectMapper
的实例之外,有没有办法告诉我的 RestTemplate
将返回的 mime 类型视为JSON?
不确定 Spring,但 Jackson 需要我说明我使用的是 Java Bean。你看,Kotlin data class
在字节码层面上和一个标准的Bean完全一样
不要忘记 Java Bean 规范暗示了一个空的构造函数(没有参数)。自动生成它的一个好方法是为主构造函数的所有参数提供默认值。
将对象从 Jackson 序列化为字符串:
- Java Beans 规范的 'get' 部分是必需的。
要将 JSON 字符串读取到对象:
- 规范的 'set' 部分是必需的。
- 此外,该对象需要一个空的构造函数。
修改 class 以包括:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
data public class ITunesArtist(var artistName: String? = null,
var artistId: Long = -1L, val amgArtistId: String = "id",
var artistLinkUrl: URL? = null)
- 字段提供默认值以便有一个空的构造函数。
编辑:
使用@mhlz(现已接受)答案中的 Kotlin 模块,无需提供默认构造函数。
除了为数据中的所有属性提供默认值 class,您还可以使用以下方法:https://github.com/FasterXML/jackson-module-kotlin
这个 Jackson 模块将允许您序列化和反序列化 Kotlin 的数据 classes,而不必担心提供空的构造函数。
在 Spring 引导应用程序中,您可以使用 @Configuration
class 注册模块,如下所示:
@Configuration
class KotlinModuleConfiguration {
@Bean
fun kotlinModule(): KotlinModule {
return KotlinModule()
}
}
除此之外,您还可以使用文档中提到的扩展函数向 Jackson 注册模块。
除了支持数据 classes,您还将获得来自 Kotlin stdlib 的几个 classes 的支持,例如 Pair。
我创建了以下 Kotlin 数据 class:
@JsonInclude(JsonInclude.Include.NON_NULL)
public data class ITunesArtist(val artistName: String,
val artistId: Long, val artistLinkUrl: URL)
(一个数据 class 是一个 Kotlin class,它在编译时自动生成 equals、hashcode、toString 等——节省时间)。
现在我尝试使用 Spring RestTemplate
填充它:
@Test
fun loadArtist()
{
val restTemplate = RestTemplate()
val artist = restTemplate.getForObject(
"https://itunes.apple.com/search?term=howlin+wolf&entity=allArtist&limit=1", ITunesQueryResults::class.java);
println("Got artist: $artist")
}
它失败了:
Could not extract response: no suitable HttpMessageConverter found for response type
[class vampr.api.service.authorization.facebook.ITunesArtist]
and content type [text/javascript;charset=utf-8]
很公平 - JSON 对象映射器可能需要 text/json
的 mime 类型。除了告诉 RestTemplate
映射到 String::class.java
,然后手动实例化 JacksonObjectMapper
的实例之外,有没有办法告诉我的 RestTemplate
将返回的 mime 类型视为JSON?
不确定 Spring,但 Jackson 需要我说明我使用的是 Java Bean。你看,Kotlin data class
在字节码层面上和一个标准的Bean完全一样
不要忘记 Java Bean 规范暗示了一个空的构造函数(没有参数)。自动生成它的一个好方法是为主构造函数的所有参数提供默认值。
将对象从 Jackson 序列化为字符串:
- Java Beans 规范的 'get' 部分是必需的。
要将 JSON 字符串读取到对象:
- 规范的 'set' 部分是必需的。
- 此外,该对象需要一个空的构造函数。
修改 class 以包括:
@JsonIgnoreProperties(ignoreUnknown = true)
@JsonInclude(JsonInclude.Include.NON_NULL)
data public class ITunesArtist(var artistName: String? = null,
var artistId: Long = -1L, val amgArtistId: String = "id",
var artistLinkUrl: URL? = null)
- 字段提供默认值以便有一个空的构造函数。
编辑:
使用@mhlz(现已接受)答案中的 Kotlin 模块,无需提供默认构造函数。
除了为数据中的所有属性提供默认值 class,您还可以使用以下方法:https://github.com/FasterXML/jackson-module-kotlin
这个 Jackson 模块将允许您序列化和反序列化 Kotlin 的数据 classes,而不必担心提供空的构造函数。
在 Spring 引导应用程序中,您可以使用 @Configuration
class 注册模块,如下所示:
@Configuration
class KotlinModuleConfiguration {
@Bean
fun kotlinModule(): KotlinModule {
return KotlinModule()
}
}
除此之外,您还可以使用文档中提到的扩展函数向 Jackson 注册模块。
除了支持数据 classes,您还将获得来自 Kotlin stdlib 的几个 classes 的支持,例如 Pair。