|
|
|
@ -16,13 +16,15 @@ |
|
|
|
|
|
|
|
|
|
|
|
package org.springframework.http.codec.json; |
|
|
|
package org.springframework.http.codec.json; |
|
|
|
|
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
|
|
|
|
import java.util.Collections; |
|
|
|
|
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
|
|
|
import com.fasterxml.jackson.annotation.JsonView; |
|
|
|
import static java.util.Arrays.asList; |
|
|
|
|
|
|
|
import static java.util.Collections.*; |
|
|
|
import org.junit.Test; |
|
|
|
import org.junit.Test; |
|
|
|
|
|
|
|
import static org.springframework.http.MediaType.*; |
|
|
|
|
|
|
|
import static org.springframework.http.codec.json.Jackson2JsonDecoder.*; |
|
|
|
|
|
|
|
import static org.springframework.http.codec.json.JacksonViewBean.*; |
|
|
|
import reactor.core.publisher.Flux; |
|
|
|
import reactor.core.publisher.Flux; |
|
|
|
import reactor.core.publisher.Mono; |
|
|
|
import reactor.core.publisher.Mono; |
|
|
|
import reactor.test.StepVerifier; |
|
|
|
import reactor.test.StepVerifier; |
|
|
|
@ -31,7 +33,6 @@ import org.springframework.core.ResolvableType; |
|
|
|
import org.springframework.core.codec.CodecException; |
|
|
|
import org.springframework.core.codec.CodecException; |
|
|
|
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase; |
|
|
|
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase; |
|
|
|
import org.springframework.core.io.buffer.DataBuffer; |
|
|
|
import org.springframework.core.io.buffer.DataBuffer; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
|
|
|
|
import org.springframework.http.codec.Pojo; |
|
|
|
import org.springframework.http.codec.Pojo; |
|
|
|
|
|
|
|
|
|
|
|
import static org.junit.Assert.assertFalse; |
|
|
|
import static org.junit.Assert.assertFalse; |
|
|
|
@ -50,9 +51,9 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
public void canDecode() { |
|
|
|
public void canDecode() { |
|
|
|
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(); |
|
|
|
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(); |
|
|
|
ResolvableType type = ResolvableType.forClass(Pojo.class); |
|
|
|
ResolvableType type = ResolvableType.forClass(Pojo.class); |
|
|
|
assertTrue(decoder.canDecode(type, MediaType.APPLICATION_JSON)); |
|
|
|
assertTrue(decoder.canDecode(type, APPLICATION_JSON)); |
|
|
|
assertTrue(decoder.canDecode(type, null)); |
|
|
|
assertTrue(decoder.canDecode(type, null)); |
|
|
|
assertFalse(decoder.canDecode(type, MediaType.APPLICATION_XML)); |
|
|
|
assertFalse(decoder.canDecode(type, APPLICATION_XML)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
@ -60,12 +61,11 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\": \"foofoo\", \"bar\": \"barbar\"}")); |
|
|
|
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\": \"foofoo\", \"bar\": \"barbar\"}")); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, |
|
|
|
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, |
|
|
|
Collections.emptyMap()); |
|
|
|
emptyMap()); |
|
|
|
|
|
|
|
|
|
|
|
StepVerifier.create(flux) |
|
|
|
StepVerifier.create(flux) |
|
|
|
.expectNext(new Pojo("foofoo", "barbar")) |
|
|
|
.expectNext(new Pojo("foofoo", "barbar")) |
|
|
|
.expectComplete() |
|
|
|
.verifyComplete(); |
|
|
|
.verify(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
@ -73,7 +73,7 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\":}")); |
|
|
|
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\":}")); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, |
|
|
|
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, |
|
|
|
Collections.emptyMap()); |
|
|
|
emptyMap()); |
|
|
|
|
|
|
|
|
|
|
|
StepVerifier.create(flux).verifyError(CodecException.class); |
|
|
|
StepVerifier.create(flux).verifyError(CodecException.class); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -85,10 +85,10 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
|
|
|
|
|
|
|
|
ResolvableType elementType = ResolvableType.forClassWithGenerics(List.class, Pojo.class); |
|
|
|
ResolvableType elementType = ResolvableType.forClassWithGenerics(List.class, Pojo.class); |
|
|
|
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType, |
|
|
|
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType, |
|
|
|
null, Collections.emptyMap()); |
|
|
|
null, emptyMap()); |
|
|
|
|
|
|
|
|
|
|
|
StepVerifier.create(mono) |
|
|
|
StepVerifier.create(mono) |
|
|
|
.expectNext(Arrays.asList(new Pojo("f1", "b1"), new Pojo("f2", "b2"))) |
|
|
|
.expectNext(asList(new Pojo("f1", "b1"), new Pojo("f2", "b2"))) |
|
|
|
.expectComplete() |
|
|
|
.expectComplete() |
|
|
|
.verify(); |
|
|
|
.verify(); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -100,21 +100,20 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
|
|
|
|
|
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, |
|
|
|
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null, |
|
|
|
Collections.emptyMap()); |
|
|
|
emptyMap()); |
|
|
|
|
|
|
|
|
|
|
|
StepVerifier.create(flux) |
|
|
|
StepVerifier.create(flux) |
|
|
|
.expectNext(new Pojo("f1", "b1")) |
|
|
|
.expectNext(new Pojo("f1", "b1")) |
|
|
|
.expectNext(new Pojo("f2", "b2")) |
|
|
|
.expectNext(new Pojo("f2", "b2")) |
|
|
|
.expectComplete() |
|
|
|
.verifyComplete(); |
|
|
|
.verify(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
public void jsonView() throws Exception { |
|
|
|
public void fieldLevelJsonView() throws Exception { |
|
|
|
Flux<DataBuffer> source = Flux.just( |
|
|
|
Flux<DataBuffer> source = Flux.just( |
|
|
|
stringBuffer("{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}")); |
|
|
|
stringBuffer("{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}")); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(JacksonViewBean.class); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(JacksonViewBean.class); |
|
|
|
Map<String, Object> hints = Collections.singletonMap(Jackson2JsonDecoder.JSON_VIEW_HINT, MyJacksonView1.class); |
|
|
|
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class); |
|
|
|
Flux<JacksonViewBean> flux = new Jackson2JsonDecoder() |
|
|
|
Flux<JacksonViewBean> flux = new Jackson2JsonDecoder() |
|
|
|
.decode(source, elementType, null, hints).cast(JacksonViewBean.class); |
|
|
|
.decode(source, elementType, null, hints).cast(JacksonViewBean.class); |
|
|
|
|
|
|
|
|
|
|
|
@ -124,8 +123,25 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
assertNull(b.getWithView2()); |
|
|
|
assertNull(b.getWithView2()); |
|
|
|
assertNull(b.getWithoutView()); |
|
|
|
assertNull(b.getWithoutView()); |
|
|
|
}) |
|
|
|
}) |
|
|
|
.expectComplete() |
|
|
|
.verifyComplete(); |
|
|
|
.verify(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
|
|
|
|
public void classLevelJsonView() throws Exception { |
|
|
|
|
|
|
|
Flux<DataBuffer> source = Flux.just(stringBuffer( |
|
|
|
|
|
|
|
"{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}")); |
|
|
|
|
|
|
|
ResolvableType elementType = ResolvableType.forClass(JacksonViewBean.class); |
|
|
|
|
|
|
|
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView3.class); |
|
|
|
|
|
|
|
Flux<JacksonViewBean> flux = new Jackson2JsonDecoder() |
|
|
|
|
|
|
|
.decode(source, elementType, null, hints).cast(JacksonViewBean.class); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
StepVerifier.create(flux) |
|
|
|
|
|
|
|
.consumeNextWith(b -> { |
|
|
|
|
|
|
|
assertNull(b.getWithView1()); |
|
|
|
|
|
|
|
assertNull(b.getWithView2()); |
|
|
|
|
|
|
|
assertTrue(b.getWithoutView().equals("without")); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.verifyComplete(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Test |
|
|
|
@Test |
|
|
|
@ -133,54 +149,11 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa |
|
|
|
Flux<DataBuffer> source = Flux.empty(); |
|
|
|
Flux<DataBuffer> source = Flux.empty(); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
ResolvableType elementType = ResolvableType.forClass(Pojo.class); |
|
|
|
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType, |
|
|
|
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType, |
|
|
|
null, Collections.emptyMap()); |
|
|
|
null, emptyMap()); |
|
|
|
|
|
|
|
|
|
|
|
StepVerifier.create(mono) |
|
|
|
StepVerifier.create(mono) |
|
|
|
.expectNextCount(0) |
|
|
|
.expectNextCount(0) |
|
|
|
.expectComplete() |
|
|
|
.verifyComplete(); |
|
|
|
.verify(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private interface MyJacksonView1 {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private interface MyJacksonView2 {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@SuppressWarnings("unused") |
|
|
|
|
|
|
|
private static class JacksonViewBean { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JsonView(MyJacksonView1.class) |
|
|
|
|
|
|
|
private String withView1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JsonView(MyJacksonView2.class) |
|
|
|
|
|
|
|
private String withView2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private String withoutView; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getWithView1() { |
|
|
|
|
|
|
|
return withView1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setWithView1(String withView1) { |
|
|
|
|
|
|
|
this.withView1 = withView1; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getWithView2() { |
|
|
|
|
|
|
|
return withView2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setWithView2(String withView2) { |
|
|
|
|
|
|
|
this.withView2 = withView2; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public String getWithoutView() { |
|
|
|
|
|
|
|
return withoutView; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setWithoutView(String withoutView) { |
|
|
|
|
|
|
|
this.withoutView = withoutView; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|