में वैकल्पिक संपत्ति नामों को संभालना मैं एक आरईएसटी/जेएसओएन सेवा कोल्डफ्यूजन 9 से स्प्रिंग-एमवीसी 3.1 एप्लिकेशन में परिवर्तित करने पर काम कर रहा हूं। मैं जैक्सन (1.9.5) और मैपिंग जैक्सन जेसन कनवर्टर का उपयोग कर रहा हूं जो वसंत प्रदान करता है, और ऑब्जेक्टमैपर को CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES के साथ फ़ील्ड नाम देने के लिए अनुकूलित कर रहा हूं।जैक्सन Deserialization
मुझे जिस समस्या का सामना करना पड़ रहा है वह यह है कि हमारी विरासत सेवा जेसन संपत्ति के नाम के रूप में 'अंडरस्कोर के साथ ऊपरी मामले में ऊंट केस' उत्पन्न करती है। इस जेएसओएन के उपभोक्ता, कोल्डफ्यूजन में भी लिखे गए हैं, मामले के बारे में कम ख्याल रख सकते हैं, लेकिन जैक्सन मामले की परवाह करता है, और अपरिचित प्रॉपर्टी अपवादों को फेंक देता है।
लगभग हर मैं ObjectMapper से तक पहुँच सकता है की स्थापना में देखने के बाद - DeserializationConfig, DeserializerProvider, आदि, मैं एक बहुत ही गंदा हैक जिसमें मैं एक JSON पेड़ से पार्स साथ समाप्त हो गया, एक कस्टम JsonGenerator साथ उत्पादन यह है कि कम मामलों फ़ील्ड नाम, और फिर इसे एक ऑब्जेक्ट के रूप में वापस पार्स करता है।
MappingJacksonHttpMessageConverter mc = new MappingJacksonHttpMessageConverter() {
@Override
protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return this.getObjectMapper().readValue(translateToLowerCaseKeys(inputMessage.getBody()), getJavaType(clazz));
}
private byte[] translateToLowerCaseKeys(InputStream messageBody) throws IOException {
StringWriter sw = new StringWriter();
JsonGenerator lowerCaseFieldNameGenerator = new JsonGeneratorDelegate(this.getObjectMapper().getJsonFactory().createJsonGenerator(sw)) {
@Override
public void writeFieldName(String name) throws IOException, org.codehaus.jackson.JsonGenerationException {
delegate.writeFieldName(name.toLowerCase());
};
};
this.getObjectMapper().writeTree(lowerCaseFieldNameGenerator, this.getObjectMapper().readTree(messageBody));
lowerCaseFieldNameGenerator.close();
return sw.getBuffer().toString().getBytes();
}
};
यह समाधान बहुत अक्षम लगता है। एक solution है जो मानचित्र की कुंजी के लिए काम करता है, लेकिन मैं फ़ील्ड नामों के लिए एक समान समाधान नहीं ढूंढ पाया।
एक वैकल्पिक समाधान दो सेटर्स होना है, जो विरासत क्षेत्र के नाम से एनोटेटेड है। नामकरण रणनीति जो मेरी स्थिति में ठीक है के बाद से वस्तु नक्शाकार एक UPPER_UNDERSCORE रणनीति के साथ किसी भी अन्य वर्गों के साथ काम नहीं किया जाएगा इन क्षेत्रों, की अनदेखी करने के लिए बढ़ाया जा करने के लिए है:
public class JsonNamingTest {
public static class CaseInsensitive extends LowerCaseWithUnderscoresStrategy {
public String translate(String in) {
return (in.toUpperCase().equals(in) ? in : super.translate(in));
}
}
public static class A {
private String testField;
public String getTestField() {
return testField;
}
public void setTestField(String field) {
this.testField = field;
}
@JsonProperty("TEST_FIELD")
public void setFieldAlternate(String field) {
this.testField = field;
}
}
@Test
public void something() throws Exception {
A test = new A();
test.setTestField("test");
ObjectMapper mapper = new ObjectMapper().setPropertyNamingStrategy(new CaseInsensitive());
assertEquals("{\"test_field\":\"test\"}", mapper.writeValueAsString(test));
assertEquals("test", mapper.readValue("{\"test_field\":\"test\"}", A.class).getTestField());
assertEquals("test", mapper.readValue("{\"TEST_FIELD\":\"test\"}", A.class).getTestField());
}
}
यह पिछले की तुलना में अधिक आदर्श है समाधान, लेकिन प्रत्येक क्षेत्र के लिए दो एनोटेटेड सेटर्स की आवश्यकता होगी - एक नए प्रारूप के लिए, एक विरासत प्रारूप का समर्थन करने के लिए।
क्या कोई भी जैक्सन केस को क्षेत्रीय नामों को बेकार करने के लिए असंवेदनशील बनाने के लिए आया है, या उस मामले के लिए फ़ील्ड नाम के लिए कई उपनाम स्वीकार करते हैं?
'mapper.enable (MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); 'भी काम करना चाहिए। – Daniel