Add Jsonb support
Spring Framework 5 will support Jsonb as a HttpMessageConverter, this commit adds auto-configuration support. Also, support for Jsonb in the @JsonTest has been added. This implementation is running against Apache Johnzon See gh-9648pull/9635/head
parent
676dec8cf7
commit
97aeaa4a32
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.http;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
|
||||
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.NoneNestedConditions;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Conditional;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.http.converter.json.JsonbHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
|
||||
/**
|
||||
* Configuration for HTTP Message converters that use JSON-B.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author 2.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(Jsonb.class)
|
||||
class JsonbHttpMessageConvertersConfiguration {
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(Jsonb.class)
|
||||
@Conditional(PreferJsonbOrMissingJacksonAndGsonCondition.class)
|
||||
protected static class JsonbHttpMessageConverterConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public JsonbHttpMessageConverter jsonbHttpMessageConverter(Jsonb jsonb) {
|
||||
JsonbHttpMessageConverter converter = new JsonbHttpMessageConverter();
|
||||
converter.setJsonb(jsonb);
|
||||
return converter;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class PreferJsonbOrMissingJacksonAndGsonCondition extends AnyNestedCondition {
|
||||
|
||||
PreferJsonbOrMissingJacksonAndGsonCondition() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "jsonb", matchIfMissing = false)
|
||||
static class JsonbPreferred {
|
||||
|
||||
}
|
||||
|
||||
@Conditional(JacksonAndGsonMissing.class)
|
||||
static class JacksonGsonMissing {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class JacksonAndGsonMissing extends NoneNestedConditions {
|
||||
|
||||
JacksonAndGsonMissing() {
|
||||
super(ConfigurationPhase.REGISTER_BEAN);
|
||||
}
|
||||
|
||||
@ConditionalOnBean(MappingJackson2HttpMessageConverter.class)
|
||||
static class JacksonMissing {
|
||||
|
||||
}
|
||||
|
||||
@ConditionalOnProperty(name = HttpMessageConvertersAutoConfiguration.PREFERRED_MAPPER_PROPERTY, havingValue = "gson")
|
||||
static class GsonMissing {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.jsonb;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
import javax.json.bind.JsonbBuilder;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for JSON-B.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(Jsonb.class)
|
||||
public class JsonbAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Jsonb jsonb() {
|
||||
return JsonbBuilder.create();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for JSON-B.
|
||||
*/
|
||||
package org.springframework.boot.autoconfigure.jsonb;
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.autoconfigure.jsonb;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JsonbAutoConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class JsonbAutoConfigurationTests {
|
||||
|
||||
AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jsonbRegistration() {
|
||||
this.context.register(JsonbAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
Jsonb jsonb = this.context.getBean(Jsonb.class);
|
||||
assertThat(jsonb.toJson(new DataObject())).isEqualTo("{\"data\":\"hello\"}");
|
||||
}
|
||||
|
||||
public class DataObject {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String data = "hello";
|
||||
|
||||
public String getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.test.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
|
||||
import org.springframework.beans.factory.ObjectFactory;
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* AssertJ based JSON tester backed by Jsonb. Usually instantiated via
|
||||
* {@link #initFields(Object, Jsonb)}, for example: <pre class="code">
|
||||
* public class ExampleObjectJsonTests {
|
||||
*
|
||||
* private JsonbTester<ExampleObject> json;
|
||||
*
|
||||
* @Before
|
||||
* public void setup() {
|
||||
* Jsonb jsonb = JsonbBuilder.create();
|
||||
* JsonbTester.initFields(this, jsonb);
|
||||
* }
|
||||
*
|
||||
* @Test
|
||||
* public void testWriteJson() throws IOException {
|
||||
* ExampleObject object = // ...
|
||||
* assertThat(json.write(object)).isEqualToJson("expected.json");
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* See {@link AbstractJsonMarshalTester} for more details.
|
||||
*
|
||||
* @param <T> the type under test
|
||||
* @author Eddú Meléndez
|
||||
* @since 2.0.0
|
||||
*/
|
||||
public class JsonbTester<T> extends AbstractJsonMarshalTester<T> {
|
||||
|
||||
private final Jsonb jsonb;
|
||||
|
||||
/**
|
||||
* Create a new uninitialized {@link JsonbTester} instance.
|
||||
* @param jsonb the Jsonb instance
|
||||
*/
|
||||
protected JsonbTester(Jsonb jsonb) {
|
||||
Assert.notNull(jsonb, "Jsonb must not be null");
|
||||
this.jsonb = jsonb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link JsonbTester} instance.
|
||||
* @param resourceLoadClass the source class used to load resources
|
||||
* @param type the type under test
|
||||
* @param jsonb the Jsonb instance
|
||||
* @see #initFields(Object, Jsonb)
|
||||
*/
|
||||
public JsonbTester(Class<?> resourceLoadClass, ResolvableType type, Jsonb jsonb) {
|
||||
super(resourceLoadClass, type);
|
||||
Assert.notNull(jsonb, "Jsonb must not be null");
|
||||
this.jsonb = jsonb;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String writeObject(T value, ResolvableType type) throws IOException {
|
||||
return this.jsonb.toJson(value, type.getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected T readObject(Reader reader, ResolvableType type) throws IOException {
|
||||
return this.jsonb.fromJson(reader, type.getType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to initialize {@link JsonbTester} fields. See {@link JsonbTester
|
||||
* class-level documentation} for example usage.
|
||||
* @param testInstance the test instance
|
||||
* @param jsonb the Jsonb instance
|
||||
*/
|
||||
public static void initFields(Object testInstance, Jsonb jsonb) {
|
||||
new JsonbFieldInitializer().initFields(testInstance, jsonb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to initialize {@link JsonbTester} fields. See {@link JsonbTester
|
||||
* class-level documentation} for example usage.
|
||||
* @param testInstance the test instance
|
||||
* @param jsonb an object factory to create the Jsonb instance
|
||||
*/
|
||||
public static void initFields(Object testInstance, ObjectFactory<Jsonb> jsonb) {
|
||||
new JsonbTester.JsonbFieldInitializer().initFields(testInstance, jsonb);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link FieldInitializer} for Jsonb.
|
||||
*/
|
||||
private static class JsonbFieldInitializer extends FieldInitializer<Jsonb> {
|
||||
|
||||
protected JsonbFieldInitializer() {
|
||||
super(JsonbTester.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJsonMarshalTester<Object> createTester(
|
||||
Class<?> resourceLoadClass, ResolvableType type, Jsonb marshaller) {
|
||||
return new JsonbTester<>(resourceLoadClass, type, marshaller);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2012-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.boot.test.json;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.json.bind.Jsonb;
|
||||
import javax.json.bind.JsonbBuilder;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JsonbTester}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class JsonbTesterTests extends AbstractJsonMarshalTesterTests {
|
||||
|
||||
@Test
|
||||
public void initFieldsWhenTestIsNullShouldThrowException() {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("TestInstance must not be null");
|
||||
JsonbTester.initFields(null, JsonbBuilder.create());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initFieldsWhenMarshallerIsNullShouldThrowException() {
|
||||
this.thrown.expect(IllegalArgumentException.class);
|
||||
this.thrown.expectMessage("Marshaller must not be null");
|
||||
JsonbTester.initFields(new InitFieldsTestClass(), (Jsonb) null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void initFieldsShouldSetNullFields() {
|
||||
InitFieldsTestClass test = new InitFieldsTestClass();
|
||||
assertThat(test.test).isNull();
|
||||
assertThat(test.base).isNull();
|
||||
JsonbTester.initFields(test, JsonbBuilder.create());
|
||||
assertThat(test.test).isNotNull();
|
||||
assertThat(test.base).isNotNull();
|
||||
assertThat(test.test.getType().resolve()).isEqualTo(List.class);
|
||||
assertThat(test.test.getType().resolveGeneric()).isEqualTo(ExampleObject.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractJsonMarshalTester<Object> createTester(Class<?> resourceLoadClass,
|
||||
ResolvableType type) {
|
||||
return new JsonbTester<>(resourceLoadClass, type, JsonbBuilder.create());
|
||||
}
|
||||
|
||||
static abstract class InitFieldsBaseClass {
|
||||
|
||||
public JsonbTester<ExampleObject> base;
|
||||
|
||||
public JsonbTester<ExampleObject> baseSet = new JsonbTester<>(
|
||||
InitFieldsBaseClass.class, ResolvableType.forClass(ExampleObject.class),
|
||||
JsonbBuilder.create());
|
||||
|
||||
}
|
||||
|
||||
static class InitFieldsTestClass extends InitFieldsBaseClass {
|
||||
|
||||
public JsonbTester<List<ExampleObject>> test;
|
||||
|
||||
public JsonbTester<ExampleObject> testSet = new JsonbTester<>(
|
||||
InitFieldsBaseClass.class, ResolvableType.forClass(ExampleObject.class),
|
||||
JsonbBuilder.create());
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue