Add class level @JsonView tests
Issue: SPR-14925
This commit is contained in:
@@ -16,13 +16,15 @@
|
||||
|
||||
package org.springframework.http.codec.json;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
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 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.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
@@ -31,7 +33,6 @@ import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.codec.CodecException;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
@@ -50,9 +51,9 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
public void canDecode() {
|
||||
Jackson2JsonDecoder decoder = new Jackson2JsonDecoder();
|
||||
ResolvableType type = ResolvableType.forClass(Pojo.class);
|
||||
assertTrue(decoder.canDecode(type, MediaType.APPLICATION_JSON));
|
||||
assertTrue(decoder.canDecode(type, APPLICATION_JSON));
|
||||
assertTrue(decoder.canDecode(type, null));
|
||||
assertFalse(decoder.canDecode(type, MediaType.APPLICATION_XML));
|
||||
assertFalse(decoder.canDecode(type, APPLICATION_XML));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -60,12 +61,11 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\": \"foofoo\", \"bar\": \"barbar\"}"));
|
||||
ResolvableType elementType = ResolvableType.forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null,
|
||||
Collections.emptyMap());
|
||||
emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("foofoo", "barbar"))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,7 +73,7 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
Flux<DataBuffer> source = Flux.just(stringBuffer("{\"foo\":}"));
|
||||
ResolvableType elementType = ResolvableType.forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null,
|
||||
Collections.emptyMap());
|
||||
emptyMap());
|
||||
|
||||
StepVerifier.create(flux).verifyError(CodecException.class);
|
||||
}
|
||||
@@ -85,10 +85,10 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
|
||||
ResolvableType elementType = ResolvableType.forClassWithGenerics(List.class, Pojo.class);
|
||||
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType,
|
||||
null, Collections.emptyMap());
|
||||
null, emptyMap());
|
||||
|
||||
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()
|
||||
.verify();
|
||||
}
|
||||
@@ -100,21 +100,20 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
|
||||
ResolvableType elementType = ResolvableType.forClass(Pojo.class);
|
||||
Flux<Object> flux = new Jackson2JsonDecoder().decode(source, elementType, null,
|
||||
Collections.emptyMap());
|
||||
emptyMap());
|
||||
|
||||
StepVerifier.create(flux)
|
||||
.expectNext(new Pojo("f1", "b1"))
|
||||
.expectNext(new Pojo("f2", "b2"))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonView() throws Exception {
|
||||
public void fieldLevelJsonView() throws Exception {
|
||||
Flux<DataBuffer> source = Flux.just(
|
||||
stringBuffer("{\"withView1\" : \"with\", \"withView2\" : \"with\", \"withoutView\" : \"without\"}"));
|
||||
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()
|
||||
.decode(source, elementType, null, hints).cast(JacksonViewBean.class);
|
||||
|
||||
@@ -124,8 +123,25 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
assertNull(b.getWithView2());
|
||||
assertNull(b.getWithoutView());
|
||||
})
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@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
|
||||
@@ -133,54 +149,11 @@ public class Jackson2JsonDecoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
Flux<DataBuffer> source = Flux.empty();
|
||||
ResolvableType elementType = ResolvableType.forClass(Pojo.class);
|
||||
Mono<Object> mono = new Jackson2JsonDecoder().decodeToMono(source, elementType,
|
||||
null, Collections.emptyMap());
|
||||
null, emptyMap());
|
||||
|
||||
StepVerifier.create(mono)
|
||||
.expectNextCount(0)
|
||||
.expectComplete()
|
||||
.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;
|
||||
}
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
|
||||
package org.springframework.http.codec.json;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import static java.util.Collections.*;
|
||||
import org.junit.Test;
|
||||
import static org.springframework.http.MediaType.*;
|
||||
import static org.springframework.http.MediaType.APPLICATION_STREAM_JSON;
|
||||
import static org.springframework.http.codec.json.Jackson2JsonEncoder.*;
|
||||
import static org.springframework.http.codec.json.JacksonViewBean.*;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
@@ -31,7 +33,6 @@ import reactor.test.StepVerifier;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.codec.Pojo;
|
||||
import org.springframework.http.codec.ServerSentEvent;
|
||||
|
||||
@@ -49,11 +50,11 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
@Test
|
||||
public void canEncode() {
|
||||
ResolvableType pojoType = ResolvableType.forClass(Pojo.class);
|
||||
assertTrue(this.encoder.canEncode(pojoType, MediaType.APPLICATION_JSON));
|
||||
assertTrue(this.encoder.canEncode(pojoType, APPLICATION_JSON));
|
||||
assertTrue(this.encoder.canEncode(pojoType, null));
|
||||
assertFalse(this.encoder.canEncode(pojoType, MediaType.APPLICATION_XML));
|
||||
assertFalse(this.encoder.canEncode(pojoType, APPLICATION_XML));
|
||||
ResolvableType sseType = ResolvableType.forClass(ServerSentEvent.class);
|
||||
assertFalse(this.encoder.canEncode(sseType, MediaType.APPLICATION_JSON));
|
||||
assertFalse(this.encoder.canEncode(sseType, APPLICATION_JSON));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -64,24 +65,22 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
new Pojo("foofoofoo", "barbarbar")
|
||||
);
|
||||
ResolvableType type = ResolvableType.forClass(Pojo.class);
|
||||
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory, type, null, Collections.emptyMap());
|
||||
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory, type, null, emptyMap());
|
||||
|
||||
StepVerifier.create(output)
|
||||
.consumeNextWith(stringConsumer("[{\"foo\":\"foo\",\"bar\":\"bar\"},{\"foo\":\"foofoo\",\"bar\":\"barbar\"},{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}]"))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void encodeWithType() throws Exception {
|
||||
Flux<ParentClass> source = Flux.just(new Foo(), new Bar());
|
||||
ResolvableType type = ResolvableType.forClass(ParentClass.class);
|
||||
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory, type, null, Collections.emptyMap());
|
||||
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory, type, null, emptyMap());
|
||||
|
||||
StepVerifier.create(output)
|
||||
.consumeNextWith(stringConsumer("[{\"type\":\"foo\"},{\"type\":\"bar\"}]"))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -92,31 +91,45 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
new Pojo("foofoofoo", "barbarbar")
|
||||
);
|
||||
ResolvableType type = ResolvableType.forClass(Pojo.class);
|
||||
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory, type, APPLICATION_STREAM_JSON, Collections.emptyMap());
|
||||
Flux<DataBuffer> output = this.encoder.encode(source, this.bufferFactory, type, APPLICATION_STREAM_JSON, emptyMap());
|
||||
|
||||
StepVerifier.create(output)
|
||||
.consumeNextWith(stringConsumer("{\"foo\":\"foo\",\"bar\":\"bar\"}\n"))
|
||||
.consumeNextWith(stringConsumer("{\"foo\":\"foofoo\",\"bar\":\"barbar\"}\n"))
|
||||
.consumeNextWith(stringConsumer("{\"foo\":\"foofoofoo\",\"bar\":\"barbarbar\"}\n"))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonView() throws Exception {
|
||||
public void fieldLevelJsonView() throws Exception {
|
||||
JacksonViewBean bean = new JacksonViewBean();
|
||||
bean.setWithView1("with");
|
||||
bean.setWithView2("with");
|
||||
bean.setWithoutView("without");
|
||||
|
||||
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
|
||||
Map<String, Object> hints = Collections.singletonMap(Jackson2JsonEncoder.JSON_VIEW_HINT, MyJacksonView1.class);
|
||||
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView1.class);
|
||||
Flux<DataBuffer> output = this.encoder.encode(Mono.just(bean), this.bufferFactory, type, null, hints);
|
||||
|
||||
StepVerifier.create(output)
|
||||
.consumeNextWith(stringConsumer("{\"withView1\":\"with\"}"))
|
||||
.expectComplete()
|
||||
.verify();
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classLevelJsonView() throws Exception {
|
||||
JacksonViewBean bean = new JacksonViewBean();
|
||||
bean.setWithView1("with");
|
||||
bean.setWithView2("with");
|
||||
bean.setWithoutView("without");
|
||||
|
||||
ResolvableType type = ResolvableType.forClass(JacksonViewBean.class);
|
||||
Map<String, Object> hints = singletonMap(JSON_VIEW_HINT, MyJacksonView3.class);
|
||||
Flux<DataBuffer> output = this.encoder.encode(Mono.just(bean), this.bufferFactory, type, null, hints);
|
||||
|
||||
StepVerifier.create(output)
|
||||
.consumeNextWith(stringConsumer("{\"withoutView\":\"without\"}"))
|
||||
.verifyComplete();
|
||||
}
|
||||
|
||||
|
||||
@@ -132,46 +145,4 @@ public class Jackson2JsonEncoderTests extends AbstractDataBufferAllocatingTestCa
|
||||
private static class Bar extends ParentClass {
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.http.codec.json;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
|
||||
/**
|
||||
* @author Sebastien Deleuze
|
||||
*/
|
||||
@JsonView(JacksonViewBean.MyJacksonView3.class)
|
||||
class JacksonViewBean {
|
||||
|
||||
interface MyJacksonView1 {}
|
||||
interface MyJacksonView2 {}
|
||||
interface MyJacksonView3 {}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
@@ -256,7 +256,7 @@ public class MappingJackson2HttpMessageConverterTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonView() throws Exception {
|
||||
public void fieldLevelJsonView() throws Exception {
|
||||
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
|
||||
JacksonViewBean bean = new JacksonViewBean();
|
||||
bean.setWithView1("with");
|
||||
@@ -273,6 +273,24 @@ public class MappingJackson2HttpMessageConverterTests {
|
||||
assertThat(result, not(containsString("\"withoutView\":\"without\"")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classLevelJsonView() throws Exception {
|
||||
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
|
||||
JacksonViewBean bean = new JacksonViewBean();
|
||||
bean.setWithView1("with");
|
||||
bean.setWithView2("with");
|
||||
bean.setWithoutView("without");
|
||||
|
||||
MappingJacksonValue jacksonValue = new MappingJacksonValue(bean);
|
||||
jacksonValue.setSerializationView(MyJacksonView3.class);
|
||||
this.converter.writeInternal(jacksonValue, null, outputMessage);
|
||||
|
||||
String result = outputMessage.getBodyAsString(StandardCharsets.UTF_8);
|
||||
assertThat(result, not(containsString("\"withView1\":\"with\"")));
|
||||
assertThat(result, not(containsString("\"withView2\":\"with\"")));
|
||||
assertThat(result, containsString("\"withoutView\":\"without\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filters() throws Exception {
|
||||
MockHttpOutputMessage outputMessage = new MockHttpOutputMessage();
|
||||
@@ -449,12 +467,15 @@ public class MappingJackson2HttpMessageConverterTests {
|
||||
}
|
||||
|
||||
|
||||
private interface MyJacksonView1 {};
|
||||
private interface MyJacksonView1 {}
|
||||
|
||||
private interface MyJacksonView2 {};
|
||||
private interface MyJacksonView2 {}
|
||||
|
||||
private interface MyJacksonView3 {}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@JsonView(MyJacksonView3.class)
|
||||
private static class JacksonViewBean {
|
||||
|
||||
@JsonView(MyJacksonView1.class)
|
||||
|
||||
Reference in New Issue
Block a user