A more general solution than the other suggested answers that require registering separate deserializers for each type is to provide a custom DefaultDeserializationContext before the ObjectMapper .
The following implementation worked for me (inspired by DefaultDeserializationContext.Impl ):
class LocalizedDeserializationContext extends DefaultDeserializationContext { private final NumberFormat format; public LocalizedDeserializationContext(Locale locale) { // Passing `BeanDeserializerFactory.instance` because this is what happens at // 'jackson-databind-2.8.1-sources.jar!/com/fasterxml/jackson/databind/ObjectMapper.java:562'. this(BeanDeserializerFactory.instance, DecimalFormat.getNumberInstance(locale)); } private LocalizedDeserializationContext(DeserializerFactory factory, NumberFormat format) { super(factory, null); this.format = format; } private LocalizedDeserializationContext(DefaultDeserializationContext src, DeserializationConfig config, JsonParser parser, InjectableValues values, NumberFormat format) { super(src, config, parser, values); this.format = format; } @Override public DefaultDeserializationContext with(DeserializerFactory factory) { return new LocalizedDeserializationContext(factory, format); } @Override public DefaultDeserializationContext createInstance(DeserializationConfig config, JsonParser parser, InjectableValues values) { return new LocalizedDeserializationContext(this, config, parser, values, format); } @Override public Object handleWeirdStringValue(Class<?> targetClass, String value, String msg, Object... msgArgs) throws IOException { // This method is called when default deserialization fails. if (targetClass == float.class || targetClass == Float.class) { return parseNumber(value).floatValue(); } if (targetClass == double.class || targetClass == Double.class) { return parseNumber(value).doubleValue(); } // TODO Handle `targetClass == BigDecimal.class`? return super.handleWeirdStringValue(targetClass, value, msg, msgArgs); } // Is synchronized because `NumberFormat` isn't thread-safe. private synchronized Number parseNumber(String value) throws IOException { try { return format.parse(value); } catch (ParseException e) { throw new IOException(e); } } }
Now configure your mapper object with the desired language:
Locale locale = Locale.forLanguageTag("da-DK"); ObjectMapper objectMapper = new ObjectMapper(null, null, new LocalizedDeserializationContext(locale));
If you use Spring RestTemplate , you can configure it to use ObjectMapper as follows:
RestTemplate template = new RestTemplate(); template.setMessageConverters( Collections.singletonList(new MappingJackson2HttpMessageConverter(objectMapper)) );
Please note that the value must be represented as a string in a JSON document (ie {"number": "2,2"} ), as, for example, {"number": 2,2} invalid JSON and not will understand.