com.gitlab.oliverlj.jsonapi.configuration.JsonApiHttpMessageConverter Maven / Gradle / Ivy
Show all versions of spring-boot-starter-json-api Show documentation
package com.gitlab.oliverlj.jsonapi.configuration;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Objects;
import org.eclipse.jdt.annotation.Nullable;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.lang.NonNull;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.jasminb.jsonapi.JSONAPIDocument;
import com.github.jasminb.jsonapi.exceptions.DocumentSerializationException;
/**
* Implementation of {@link org.springframework.http.converter.HttpMessageConverter} that can read
* and write JSON using json api.
*
*
* This converter can be used to bind to {@link com.github.jasminb.jsonapi.annotations.Type} beans,
* {@link JSONAPIDocument} beans, or untyped {@link Iterable} instances.
*
*
* By default, this converter supports {@code application/vnd.api+json}.
*
*
* The default constructor uses the default configuration provided by
* {@link Jackson2ObjectMapperBuilder}.
*
* @author Olivier LE JACQUES ([email protected])
*
*/
public class JsonApiHttpMessageConverter extends AbstractJackson2HttpMessageConverter {
@NonNull
public static final String APPLICATION_JSON_API_VALUE = "application/vnd.api+json";
public static final MediaType APPLICATION_JSON_API = MediaType.valueOf(APPLICATION_JSON_API_VALUE);
private final ResourceConverterWrapper resourceConverterWrapper;
public JsonApiHttpMessageConverter(ObjectMapper objectMapper, ResourceConverterWrapper resourceConverterWrapper) {
super(objectMapper, APPLICATION_JSON_API);
Objects.requireNonNull(objectMapper, "An ObjectMapper must be provided.");
Objects.requireNonNull(resourceConverterWrapper, "A ResourceConverterWrapper must be provided.");
this.resourceConverterWrapper = resourceConverterWrapper;
}
@Override
public boolean canRead(Type type, @Nullable Class> contextClass, @Nullable MediaType mediaType) {
if (!canRead(mediaType)) {
return false;
}
return resourceConverterWrapper.canReadOrWrite(type, contextClass);
}
@Override
public boolean canWrite(@Nullable Type type, Class> contextClass, @Nullable MediaType mediaType) {
if (!canWrite(mediaType) || type == null) {
return false;
}
return resourceConverterWrapper.canReadOrWrite(type, contextClass);
}
@Override
protected boolean supports(Class> clazz) {
return resourceConverterWrapper.supports(clazz);
}
@Override
public Object read(Type type, @Nullable Class> contextClass, HttpInputMessage inputMessage) throws IOException {
return resourceConverterWrapper.deserialize(type, contextClass, inputMessage.getBody());
}
@Override
protected void writeInternal(Object object, @Nullable Type type, HttpOutputMessage outputMessage) throws IOException {
try {
outputMessage.getBody().write(resourceConverterWrapper.serialize(object));
} catch (DocumentSerializationException ex) {
String message = ex.getMessage();
message = message == null ? "" : message;
throw new HttpMessageNotWritableException(message, ex);
}
}
}