Skip to content

Commit b1f8a31

Browse files
committed
Fix #1948 can force deser Locale use java style
config: System.setProperty("jackson.std.locale.de.java", "not empty")
1 parent 8b1b40f commit b1f8a31

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java

+36
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,13 @@ public static class Std extends FromStringDeserializer<Object>
220220
public final static int STD_INET_ADDRESS = 11;
221221
public final static int STD_INET_SOCKET_ADDRESS = 12;
222222
public final static int STD_STRING_BUILDER = 13;
223+
/**
224+
* If you are using java's {@linkplain Locale#toString()} serialize Locale
225+
* (split language, country and variant with '_')<br>
226+
* You can force jackson deserialize String to Locale with java Locale style.<br>
227+
* config: {@linkplain System#setProperty(String, String) System.setProperty("jackson.std.locale.de.java", "not empty")}
228+
*/
229+
public final static String STD_LOCALE_DE_JAVA = "jackson.std.locale.de.java";
223230

224231
protected final int _kind;
225232

@@ -255,6 +262,10 @@ protected Object _deserialize(String value, DeserializationContext ctxt) throws
255262
return Pattern.compile(value);
256263
case STD_LOCALE:
257264
{
265+
if (!System.getProperty(STD_LOCALE_DE_JAVA, "").isEmpty()) {
266+
return deJavaLocale(value);
267+
}
268+
258269
int ix = _firstHyphenOrUnderscore(value);
259270
if (ix < 0) { // single argument
260271
return new Locale(value);
@@ -330,5 +341,30 @@ protected int _firstHyphenOrUnderscore(String str)
330341
}
331342
return -1;
332343
}
344+
345+
/** see {@link Locale#toString()}, but ignore extends */
346+
private Locale deJavaLocale(String value) {
347+
if (value.isEmpty()) {
348+
return new Locale("");
349+
}
350+
351+
int extStart = value.indexOf("_#");
352+
if (extStart != -1) value = value.substring(0, extStart);
353+
354+
String language = value, country = "", variant = "";
355+
int pos1 = value.indexOf('_');
356+
if (pos1 != -1) {
357+
language = value.substring(0, pos1++);
358+
359+
int pos2 = value.indexOf('_', pos1);
360+
if (pos2 == -1) {
361+
country = value.substring(pos1);
362+
} else {
363+
country = value.substring(pos1, pos2);
364+
variant = value.substring(pos2 + 1);
365+
}
366+
}
367+
return new Locale(language, country, variant);
368+
}
333369
}
334370
}

src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKStringLikeTypesTest.java

+22
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import com.fasterxml.jackson.databind.*;
1919
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
20+
import com.fasterxml.jackson.databind.deser.std.FromStringDeserializer;
2021
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
2122
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
2223
import com.fasterxml.jackson.databind.module.SimpleModule;
@@ -132,6 +133,23 @@ public void testFile() throws Exception
132133

133134
public void testLocale() throws IOException
134135
{
136+
// [databind #1948]
137+
String deJavaKey = FromStringDeserializer.Std.STD_LOCALE_DE_JAVA;
138+
String old = System.setProperty(deJavaKey, "1");
139+
try {
140+
assertLocale(new Locale(""));
141+
assertLocale(new Locale("en"));
142+
assertLocale(new Locale("en", "US"));
143+
assertLocale(new Locale("zh", "CN"));
144+
assertLocale(new Locale("zh-hant", "CN"));
145+
} finally {
146+
if (old == null) {
147+
System.getProperties().remove(deJavaKey);
148+
} else {
149+
System.setProperty(deJavaKey, old);
150+
}
151+
}
152+
135153
assertEquals(new Locale("en"), MAPPER.readValue(quote("en"), Locale.class));
136154
assertEquals(new Locale("es", "ES"), MAPPER.readValue(quote("es_ES"), Locale.class));
137155
assertEquals(new Locale("FI", "fi", "savo"),
@@ -144,6 +162,10 @@ public void testLocale() throws IOException
144162
assertSame(Locale.ROOT, loc);
145163
}
146164

165+
private void assertLocale(Locale loc) throws IOException {
166+
assertEquals(loc, MAPPER.readValue(MAPPER.writeValueAsString(loc), Locale.class));
167+
}
168+
147169
public void testCharSequence() throws IOException
148170
{
149171
CharSequence cs = MAPPER.readValue("\"abc\"", CharSequence.class);

0 commit comments

Comments
 (0)