
reactor.tcp.encoding.json.JsonCodec Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2011-2013 GoPivotal, Inc. All Rights Reserved.
*
* 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 reactor.tcp.encoding.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.function.Consumer;
import reactor.function.Function;
import reactor.io.Buffer;
import reactor.tcp.encoding.Codec;
import reactor.util.Assert;
import java.io.IOException;
/**
* A codec for decoding JSON into Java objects and encoding Java objects into JSON.
*
* @param The type to decode JSON into
* @param The type to encode into JSON
* @author Jon Brisbin
*/
public class JsonCodec implements Codec {
private final Class inputType;
private final ObjectMapper mapper;
/**
* Creates a new {@code JsonCodec} that will create instances of {@code inputType} when
* decoding.
*
* @param inputType The type to create when decoding.
*/
public JsonCodec(Class inputType) {
this(inputType, null);
}
/**
* Creates a new {@code JsonCodec} that will create instances of {@code inputType} when
* decoding. The {@code customModule} will be registered with the underlying {@link
* ObjectMapper}.
*
* @param inputType The type to create when decoding.
* @param customModule The module to register with the underlying ObjectMapper
*/
@SuppressWarnings("unchecked")
public JsonCodec(Class inputType, Module customModule) {
Assert.notNull(inputType, "inputType must not be null");
this.inputType = (null == inputType ? (Class) JsonNode.class : inputType);
this.mapper = new ObjectMapper();
if (null != customModule) {
this.mapper.registerModule(customModule);
}
}
@Override
public Function decoder(Consumer next) {
return new JsonDecoder(next);
}
@Override
public Function encoder() {
return new JsonEncoder();
}
private class JsonDecoder implements Function {
private final Consumer next;
private JsonDecoder(Consumer next) {
this.next = next;
}
@SuppressWarnings("unchecked")
@Override
public IN apply(Buffer buffer) {
IN in;
try {
if (JsonNode.class.isAssignableFrom(inputType)) {
in = (IN) mapper.readTree(buffer.inputStream());
} else {
in = mapper.readValue(buffer.inputStream(), inputType);
}
if (null != next) {
next.accept(in);
return null;
} else {
return in;
}
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
}
private class JsonEncoder implements Function {
@Override
public Buffer apply(OUT out) {
try {
return Buffer.wrap(mapper.writeValueAsBytes(out));
} catch (JsonProcessingException e) {
throw new IllegalStateException(e);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy