micronaut-core
micronaut-core copied to clipboard
@JsonFormat (jackson) not working when no explicity @Body speficied
Expected Behavior
Body need to be parsed using Jackson annotations even when not explicity annotated with @Body. When trying to use @Body annotation we can't use @RequestBean due to the bean is replaced with a new instance to fill body params.
Actual Behaviour
Body was parsed but not respecting Jackson Annotations like @JsonFormat(...)
Steps To Reproduce
Just run the follow test in any Micronaut Application
import static org.junit.jupiter.api.Assertions.assertNotNull;
import java.time.LocalDate;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.junit.jupiter.api.Test;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.PathVariable;
import io.micronaut.http.annotation.Post;
import io.micronaut.http.annotation.RequestBean;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.runtime.server.EmbeddedServer;
import io.micronaut.security.annotation.Secured;
import io.micronaut.security.rules.SecurityRule;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
@MicronautTest
public class TestDate {
@Inject
EmbeddedServer embeddedServer;
@Test
void testBindDate() {
String inputId = "abc";
String inputDate = "2022-01-23 00";
TestClient testClient = embeddedServer.getApplicationContext().getBean(TestClient.class);
assertNotNull(testClient.test(inputId, Map.of("date", inputDate)));
}
@Client("/api/test")
static interface TestClient {
@Post("/{id}")
public String test(@PathVariable("id") String id, @Body Map<String, Object> body);
}
@Secured(SecurityRule.IS_ANONYMOUS)
@Controller("/test")
static class TestController {
@Post("/{id}")
public String test(@RequestBean TestPojo testPojo) {
return testPojo.getDate().toString() + testPojo.getId();
}
}
@Introspected
static class TestPojo {
@PathVariable("id")
private String id;
@JsonFormat(pattern = "yyyy-MM-dd HH")
private LocalDate date;
public void setDate(LocalDate date) {
this.date = date;
}
public LocalDate getDate() {
return date;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
}
Environment Information
Any
Example Application
No response
Version
3.5.0
i dont think jackson is used to populate TestPojo, so not sure why this should work. it's a separate mechanism
Hi Jonas, so what is the correct way to set the LocalDateTime/LocalDate format? Thanks
please try io.micronaut.core.convert.format.Format
I tried with @Format annotation but it didn't work either
@yawkat Did you run the test I posted? Did you make it work? If yes, please post the answer. If not, let's wait for someone who knows.
https://github.com/micronaut-projects/micronaut-core/issues/2156
#2156 does not apply here, TestPojo contains a PathVariable so it can't be parsed from json (i.e. through jackson)
The test case is a bit problematic in this regard, it has mismatched path, sends a json body but expects query params on the controller side, and it uses LocalDate with a format that has a time component. it cannot work in its current state