Fix FilterProvider handling in AbstractJacksonEncoder

Closes gh-35575
This commit is contained in:
Sébastien Deleuze
2025-10-08 11:28:56 +02:00
parent e11cb2d856
commit 891c3e3a1f
2 changed files with 64 additions and 14 deletions
@@ -22,6 +22,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import org.junit.jupiter.api.Test;
@@ -30,6 +31,9 @@ import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import tools.jackson.databind.SerializationFeature;
import tools.jackson.databind.json.JsonMapper;
import tools.jackson.databind.ser.FilterProvider;
import tools.jackson.databind.ser.std.SimpleBeanPropertyFilter;
import tools.jackson.databind.ser.std.SimpleFilterProvider;
import org.springframework.core.ResolvableType;
import org.springframework.core.io.buffer.DataBuffer;
@@ -50,6 +54,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.http.MediaType.APPLICATION_NDJSON;
import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM;
import static org.springframework.http.MediaType.APPLICATION_XML;
import static org.springframework.http.codec.JacksonCodecSupport.FILTER_PROVIDER_HINT;
import static org.springframework.http.codec.JacksonCodecSupport.JSON_VIEW_HINT;
/**
@@ -211,6 +216,24 @@ class JacksonJsonEncoderTests extends AbstractEncoderTests<JacksonJsonEncoder> {
);
}
@Test
void fieldLevelJsonViewStream() {
JacksonViewBean bean = new JacksonViewBean();
bean.setWithView1("with");
bean.setWithView2("with");
bean.setWithoutView("without");
Flux<JacksonViewBean> input = Flux.just(bean, bean);
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class);
testEncodeAll(input, type, APPLICATION_NDJSON, hints, step -> step
.consumeNextWith(expectString("{\"withView1\":\"with\"}\n"))
.consumeNextWith(expectString("{\"withView1\":\"with\"}\n"))
.verifyComplete()
);
}
@Test
void classLevelJsonView() {
JacksonViewBean bean = new JacksonViewBean();
@@ -228,6 +251,33 @@ class JacksonJsonEncoderTests extends AbstractEncoderTests<JacksonJsonEncoder> {
);
}
@Test
void filterProvider() {
JacksonFilteredBean filteredBean = new JacksonFilteredBean("foo", "bar");
FilterProvider filters = new SimpleFilterProvider().addFilter("myJacksonFilter",
SimpleBeanPropertyFilter.serializeAllExcept("property2"));
Mono<JacksonFilteredBean> input = Mono.just(filteredBean);
Map<String, Object> hints = singletonMap(FILTER_PROVIDER_HINT, filters);
testEncode(input, ResolvableType.forClass(Pojo.class), APPLICATION_JSON, hints, step -> step
.consumeNextWith(expectString("{\"property1\":\"foo\"}"))
.verifyComplete()
);
}
@Test
void filterProviderStream() {
JacksonFilteredBean filteredBean = new JacksonFilteredBean("foo", "bar");
FilterProvider filters = new SimpleFilterProvider().addFilter("myJacksonFilter",
SimpleBeanPropertyFilter.serializeAllExcept("property2"));
Flux<JacksonFilteredBean> input = Flux.just(filteredBean, filteredBean);
Map<String, Object> hints = singletonMap(FILTER_PROVIDER_HINT, filters);
testEncodeAll(input, ResolvableType.forClass(Pojo.class), APPLICATION_NDJSON, hints, step -> step
.consumeNextWith(expectString("{\"property1\":\"foo\"}\n"))
.consumeNextWith(expectString("{\"property1\":\"foo\"}\n"))
.verifyComplete()
);
}
@Test // gh-22771
public void encodeWithFlushAfterWriteOff() {
JsonMapper mapper = JsonMapper.builder().configure(SerializationFeature.FLUSH_AFTER_WRITE_VALUE, false).build();
@@ -267,4 +317,8 @@ class JacksonJsonEncoderTests extends AbstractEncoderTests<JacksonJsonEncoder> {
private static class Bar extends ParentClass {
}
@JsonFilter("myJacksonFilter")
record JacksonFilteredBean(String property1, String property2) {
}
}