英文:
Java Records (JEP359) as Spring Controller Request and Response DTOs
问题
我只是在这些新的Java Records上进行实验,我想知道是否可以将它们用作Spring Boot应用程序中请求/响应类型的DTOs。
因此,我只是修改了一些代码(将带有大量样板getter/setter的类改成了records),编译并启动了我的应用程序。尝试了一些REST端点,但我得到的只是一个异常,告诉我:
找不到类x.y.CreateNewShopListeCommand$Item的序列化程序,也没有发现任何属性来创建BeanSerializer(要避免异常,请禁用SerializationFeature.FAIL_ON_EMPTY_BEANS)
好吧,records不会创建带有'get'前缀的getter方法。现在我想知道:是否可以将records用作Spring Boot控制器的请求/响应类型?
编辑:示例应用程序(https://github.com/kaipaysen/playground-jdk14-records-as-dto)
// HelloController.java
@RestController
@RequestMapping("/hello")
public class HelloController {
public record HelloRequest(
@JsonProperty("name") String name
) {}
public record HelloResponse(
@JsonProperty("message") String message
) {}
@RequestMapping(method = RequestMethod.POST)
public HelloResponse hello(@RequestBody @Valid HelloRequest query) {
return new HelloResponse("Hello " + query.name());
}
}
调用curl -X POST -H "Content-Type: application/json" -d '{"name":"Max"}' http://localhost:8080/hello
返回 {"message":"Hello null"}
。调试hello
方法揭示出请求未被正确反序列化。对此有什么想法吗?
编辑#2:
刚刚在FasterXML存储库中找到了这个问题Support for JDK 14 record types #2709。他们正在为jackson 2.12版解决这个问题。
英文:
I'm just experimenting with these new Java Records and I'm wondering if I could use them as DTOs for my request / response types in a spring boot application.
Therefore I just modified some code (class with a lot of boilerplate getter/setter to records), compiled and started my application. Trying some rest endpoints and all I got was an exception telling me:
No serializer found for class x.y.CreateNewShopListeCommand$Item and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS
Well, ok, records do not create 'get'prefixed getter methods. Now I wonder: is it possible to use records as request / response types for spring boot controller?
EDIT: Sample Application (https://github.com/kaipaysen/playground-jdk14-records-as-dto)
// HelloController.java
@RestController
@RequestMapping("/hello")
public class HelloController {
public record HelloRequest(
@JsonProperty("name") String name
) {}
public record HelloResponse(
@JsonProperty("message") String message
) {}
@RequestMapping(method = RequestMethod.POST)
public HelloResponse hello(@RequestBody @Valid HelloRequest query) {
return new HelloResponse("Hello " + query.name());
}
}
Calling curl -X POST -H "Content-Type: application/json" -d '{"name":"Max"}' http://localhost:8080/hello
returns {"message":"Hello null"}
. Debugging hello
reveals that the Request is not properly deserialized. Any ideas on that spot?
EDIT#2:
Just found this issue Support for JDK 14 record types #2709 in the FasterXML repo. They are working on it for jackson 2.12.
答案1
得分: 1
你需要将这个类级别的注解添加到你的记录中。
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
在 jackson 版本 1.12 中,它应该在没有注解的情况下可用。
我认为这是 Jackson 的一个 bug,你需要为你的记录添加第二个字段,因为它对只有一个字段的记录不起作用。
英文:
You need to add this class level annotation to yours records.
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
In the jackson version 1.12 it should be available without annotation.
I think this's a bug in Jackson, You need to add a second field to your record because it doesn't work for the record which has only one field.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论