Skip to content

Instantly share code, notes, and snippets.

@spaceCamel
Last active August 29, 2015 14:20
Show Gist options
  • Save spaceCamel/9f66c60d15fdbfb2fe7f to your computer and use it in GitHub Desktop.
Save spaceCamel/9f66c60d15fdbfb2fe7f to your computer and use it in GitHub Desktop.
Jackson and floating-point numbers
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.JsonSerializer
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializerProvider
import com.fasterxml.jackson.databind.module.SimpleModule
import spock.lang.Specification
import java.math.RoundingMode
class JacksonFloatingPointNumberTest extends Specification
{
static floatingPointFix = new SimpleModule("floating-point-rounding-fix").with { module ->
module.addSerializer(Double.class, new JsonSerializer<Double>() {
@Override
void serialize(final Double value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException
{
def asBD = value.toBigDecimal()
def truncated = asBD.scale() > 4 ? asBD.setScale(4, RoundingMode.HALF_EVEN) : asBD
def numericString = truncated.stripTrailingZeros().toPlainString()
jgen.writeNumber(numericString)
}
})
module.addSerializer(Float.class, new JsonSerializer<Float>() {
@Override
void serialize(final Float value, final JsonGenerator jgen, final SerializerProvider provider) throws IOException, JsonProcessingException
{
def asBD = value.toBigDecimal()
def truncated = asBD.scale() > 4 ? asBD.setScale(4, RoundingMode.HALF_EVEN) : asBD
def numericString = truncated.stripTrailingZeros().toPlainString()
jgen.writeNumber(numericString)
}
})
return module
}
def mapper = new ObjectMapper()
def 'serialize float'()
{
given:
float amount = 545.51f
def sourceMap = [amount: amount]
when:
def json = mapper.writeValueAsString(sourceMap)
then:
json == '{"amount":545.51}'
}
def 'serialize double'()
{
given:
double amount = 545.51d
def sourceMap = [amount: amount]
when:
def json = mapper.writeValueAsString(sourceMap)
then:
json == '{"amount":545.51}'
}
def 'serialize float upcasted to double'()
{
given:
double amount = 545.51f
def sourceMap = [amount: amount]
when:
def json = mapper.writeValueAsString(sourceMap)
then:
json == '{"amount":545.51}'
}
def 'serialize float upcasted to double with fix'()
{
given:
double amount = 0.255f
def sourceMap = [amount: amount]
mapper.registerModule(floatingPointFix)
when:
def json = mapper.writeValueAsString(sourceMap)
then:
json == '{"amount":0.255}'
}
def 'serialize double downcated to float'()
{
given:
float amount = 545.51d
def sourceMap = [amount: amount]
when:
def json = mapper.writeValueAsString(sourceMap)
then:
json == '{"amount":545.51}'
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment