@Data
@Accessors(chain = true)
public class BookPowerEntity {
private BookAggregateRootStatusEnum bookAggregateRootStatusEnum;
}
@AllArgsConstructor
@Getter
public enum BookAggregateRootStatusEnum {
BOOK_ALL_READ(0, "全部可读")
;
@JsonValue
private final Integer code;
private final String message;
@JsonCreator
public static BookAggregateRootStatusEnum valueOfCode(int code) {
return Arrays.stream(values()).filter(enu -> enu.getCode().equals(code)).findAny().get();
}
@RestController
public class BookController {
@PostMapping("book")
public void create(@RequestBody BookPowerEntity bookAggregateRoot) {
System.out.println(bookAggregateRoot);
}
}
When I use this way, the access request reports an error, and I must add @ jsonvalue to the get method
Comment From: wilkinsona
Thanks for the report. Unfortunately, it's not clear to me why you think that this is a bug in Spring Boot. @JsonValue
is a Jackson annotation with which Spring Boot isn't really involved. If you do think this is a Spring Boot bug, can you please explain why and provide a complete and minimal sample that we can use to reproduce the problem. You can share that sample with us by zipping it up and attaching it to this issue or by pushing it to a separate repository.
Comment From: yangle94
public static void main(String[] args) throws JsonProcessingException {
String json = "{\n" +
"\"bookAggregateRootStatusEnum\":0\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.readValue(json, BookPowerEntity.class);
}
I don't report an error when I use objectmapper directly, only when I use HTTP to request to access @ requestbody。So, I think there may be some problems in spring boot configuration。
Comment From: yangle94
Just a moment, please. I'll check
Comment From: yangle94
https://github.com/yangle94/jsonValueError
Please visit the repository. I have prepared two methods. One is to use objectmapper directly, and the other is to use HTTP to request access. The same JSON results in HTTP request error
Comment From: wilkinsona
Thanks for the sample. The ObjectMapper
that you are using in each case isn't the same. The key difference in the HTTP case is that you are using Spring Boot's auto-configured ObjectMapper
. This ObjectMapper
has Jackson's ParameterNamesModule
registered with it. You can reproduce the problem with no involvement from Spring Boot with the following code:
new ObjectMapper().registerModule(new ParameterNamesModule(JsonCreator.Mode.DEFAULT))
.readValue("{\"bookAggregateRootStatusEnum\":0}", BookPowerEntity.class);
I'm not sure if you have found a bug in Jackson or if @JsonCreator
needs to be used differently when the parameter names module is available. The Jackson team may be able to help you there.
If you don't need the functionality provided by the parameter names module, you can exclude it:
diff --git a/pom.xml b/pom.xml
index 5d36ee2..05250b8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,6 +22,12 @@
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>com.fasterxml.jackson.module</groupId>
+ <artifactId>jackson-module-parameter-names</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
With the above change in place, I can make a post request:
$ curl -X POST -i localhost:8080/book -d '{"bookAggregateRootStatusEnum":0}' -H "Content-Type:application/json"
HTTP/1.1 200
Content-Length: 0
Date: Thu, 26 Mar 2020 12:15:53 GMT
Comment From: yangle94
Thank you for your help
Comment From: cowtowncoder
If a test could be created by just isolating Enum
with @JsonValue
, using explicitly configured ObjectMapper
, showing the issue with just Jackson (with or without Java 8 parameter names module), I'd happily look into issue on Jackson side (either using earlier reported issue or new one).
I am not aware of issue wrt @JsonValue
, Enums, but that does not mean there wouldn't be one. More common usage is to use annotation on getter method.
Comment From: cowtowncoder
I think I actually found the underlying problem, once surrounding question of Spring Boot is resolved, notes on:
https://github.com/FasterXML/jackson-modules-java8/issues/169
and TL;DNR: need to add mode = JsonCreator.Mode.DELEGATING
to ensure delegating constructor used.
Comment From: wilkinsona
Thanks for taking a look, @cowtowncoder.