java Jackson ObjectMapper 大写/小写问题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26744885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hymanson ObjectMapper upper/lower case issues
提问by Barni
When I serialize/deserialize any object, all field names are converted to lower case. Is there any configuration to set that makes Hymanson keep the field names exactly as they are? Both for serializing and deserializing?
当我序列化/反序列化任何对象时,所有字段名称都转换为小写。是否有任何配置可以让 Hymanson 保持字段名称的原样?既用于序列化又用于反序列化?
(I know about @JsonProperty, but this does not seems to be right, since what I need is just for Hymanson to respect what already exists)
(我知道@JsonProperty,但这似乎不对,因为我需要的只是让Hyman逊尊重已经存在的东西)
My test code:
我的测试代码:
import java.io.Serializable;
import com.fasterxml.Hymanson.databind.DeserializationFeature;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.databind.PropertyNamingStrategy;
import com.fasterxml.Hymanson.databind.SerializationFeature;
import com.fasterxml.Hymanson.databind.cfg.MapperConfig;
import com.fasterxml.Hymanson.databind.introspect.AnnotatedField;
import com.fasterxml.Hymanson.databind.introspect.AnnotatedMethod;
public class Test {
static class Example implements Serializable {
private String Test;
private String ABC;
private String XyZ;
public String getTest() { return Test; }
public void setTest(String test) { Test = test; }
public String getABC() { return ABC; }
public void setABC(String abc) { ABC = abc; }
public String getXyZ() { return XyZ; }
public void setXyZ(String xyz) { XyZ = xyz; }
}
static class MyPropertyNamingStrategy extends PropertyNamingStrategy {
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
return convert(defaultName);
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convert(defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convert(defaultName);
}
private String convert(String input) {
return input;
}
}
public static void main(String[] args) throws Exception {
ObjectMapper objectMapper = new ObjectMapper()
.setPropertyNamingStrategy(new MyPropertyNamingStrategy())
.enable(SerializationFeature.INDENT_OUTPUT)
.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
//From OBJECT to JSON
Example ex = new Example();
ex.setTest("1");
ex.setABC("2");
ex.setXyZ("3");
System.out.println(objectMapper.writeValueAsString(ex));
//FROM JSON to OBJECT
String jsonString = "{ \"Test\":\"0\", \"ABC\":\"1\", \"XyZ\":\"2\" }";
Example fEx = objectMapper.readValue(jsonString, Example.class);
}
}
Thanks to @BlueLettuce16, I have managed to build an 'improved' version of the PropertyNamingStrategy
. Here it is:
感谢@BlueLettuce16,我设法构建了一个“改进”版本的PropertyNamingStrategy
. 这里是:
import java.lang.reflect.Modifier;
import com.fasterxml.Hymanson.databind.PropertyNamingStrategy;
import com.fasterxml.Hymanson.databind.cfg.MapperConfig;
import com.fasterxml.Hymanson.databind.introspect.AnnotatedField;
import com.fasterxml.Hymanson.databind.introspect.AnnotatedMethod;
public class CustomPropertyNamingStrategy extends PropertyNamingStrategy {
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
return convertForField(defaultName);
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convertForMethod(method, defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convertForMethod(method, defaultName);
}
private String convertForField(String defaultName) {
return defaultName;
}
private String convertForMethod(AnnotatedMethod method, String defaultName) {
if (isGetter(method)) {
return method.getName().substring(3);
}
if (isSetter(method)) {
return method.getName().substring(3);
}
return defaultName;
}
private boolean isGetter(AnnotatedMethod method) {
if (Modifier.isPublic(method.getModifiers()) && method.getGenericParameterTypes().length == 0) {
if (method.getName().matches("^get[A-Z].*") && !method.getGenericReturnType().equals(void.class))
return true;
if (method.getName().matches("^is[A-Z].*") && method.getGenericReturnType().equals(boolean.class))
return true;
}
return false;
}
private boolean isSetter(AnnotatedMethod method) {
return Modifier.isPublic(method.getModifiers()) && method.getGenericReturnType().equals(void.class) && method.getGenericParameterTypes().length == 1
&& method.getName().matches("^set[A-Z].*");
}
}
采纳答案by BlueLettuce16
I think that this is the solution (using custom PropertyNamingStrategy):
我认为这是解决方案(使用自定义 PropertyNamingStrategy):
import com.fasterxml.Hymanson.databind.PropertyNamingStrategy;
import com.fasterxml.Hymanson.databind.cfg.MapperConfig;
import com.fasterxml.Hymanson.databind.introspect.AnnotatedField;
import com.fasterxml.Hymanson.databind.introspect.AnnotatedMethod;
public class MyPropertyNamingStrategy extends PropertyNamingStrategy {
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
return convert(field.getName());
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convert(method.getName().toString());
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convert(method.getName().toString());
}
private String convert(String input) {
return input.substring(3);
}
}
Test
测试
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.databind.SerializationFeature;
import java.io.IOException;
import java.io.StringWriter;
public class MyPropertyNamingStrategyTest {
public static void main(String[] args) {
PrivatePerson privatePerson = new PrivatePerson();
privatePerson.setFirstName("John");
privatePerson.setLastName("Smith");
ObjectMapper mapper = new ObjectMapper();
mapper.setPropertyNamingStrategy(new MyPropertyNamingStrategy());
mapper.enable(SerializationFeature.INDENT_OUTPUT);
StringWriter sw = new StringWriter();
try {
mapper.writeValue(sw, privatePerson);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(sw.toString());
}
}
PrivatePerson
个人
public class PrivatePerson {
private String firstName;
private String lastName;
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getFirstName() {
return firstName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getLastName() {
return lastName;
}
}
回答by Bobby
I've had the same problem.
我遇到了同样的问题。
This is my solution:
这是我的解决方案:
public class MyNamingStrategy extends PropertyNamingStrategy {
@Override
public String nameForField(MapperConfig<?> config, AnnotatedField field, String defaultName) {
return field.getName();
}
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convert(method, defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return convert(method, defaultName);
}
private String convert(AnnotatedMethod method, String defaultName) {
Class<?> clazz = method.getDeclaringClass();
List<Field> flds = FieldUtils.getAllFieldsList(clazz);
for (Field fld : flds) {
if (fld.getName().equalsIgnoreCase(defaultName)) {
return fld.getName();
}
}
return defaultName;
}
}
In this case you will get the exact name of the property, and will not have to depend on the correct names of the methods.
在这种情况下,您将获得属性的确切名称,而不必依赖于方法的正确名称。
回答by Ethan
Even though @JsonProperty
doesn't work, I was able to use @JsonSetter
and @JsonGetter
to map capitalized json field names.
即使@JsonProperty
不起作用,我也能够使用@JsonSetter
并@JsonGetter
映射大写的 json 字段名称。
@JsonSetter("ABC")
public void setABC(String ABC) {
this.ABC= ABC;
}
Spring will now serialize the object field as "ABC" and not "abc".
Spring 现在将对象字段序列化为“ABC”而不是“abc”。
回答by Leos Literak
You can configure Hymanson to be case sensitivity tolerant:
您可以将 Hymanson 配置为区分大小写:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);