Джексон переименовывает примитивное булевское поле, удаляя 'is'
Это может быть дубликатом. Но я не могу найти решение моей проблемы.
У меня есть класс
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Геттеры и сеттеры создаются Eclipse.
В другом классе я устанавливаю значение true и записываю его в виде строки JSON.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
В JSON ключ появляется как {"success": true}
.
Я хочу ключ как сам TG43. Джексон использует метод установки во время сериализации? Как сделать ключ самим именем поля?
Ответы
Ответ 1
Это немного поздний ответ, но может быть полезен для всех, кто придет на эту страницу.
Простое решение для изменения имени, которое Джексон будет использовать для сериализации в JSON, заключается в использовании аннотации @JsonProperty, поэтому ваш пример будет стали:
public class MyResponse implements Serializable {
private boolean isSuccess;
@JsonProperty(value="isSuccess")
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Затем это будет сериализовано для JSON как {"isSuccess":true}
, но имеет то преимущество, что вам не нужно изменять имя метода getter.
Обратите внимание, что в этом случае вы также можете записать аннотацию как @JsonProperty("isSuccess")
, поскольку она имеет только один элемент value
Ответ 2
Недавно я столкнулся с этой проблемой, и это то, что я нашел. Джексон проверит любой класс, который вы передадите ему для геттеров и сеттеров, и используйте эти методы для сериализации и десериализации. Что следует за "get", "is" и "set" в этих методах, будет использоваться как ключ для поля JSON ( "isValid" для getIsValid и setIsValid).
public class JacksonExample {
private boolean isValid = false;
public boolean getIsValid() {
return isValid;
}
public void setIsValid(boolean isValid) {
this.isValid = isValid;
}
}
Аналогично "isSuccess" станет "успехом", если только он не переименован в "isIsSuccess" или "getIsSuccess"
Подробнее здесь: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
Ответ 3
Вы можете настроить свой ObjectMapper
следующим образом:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
return method.getName();
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
Ответ 4
Основываясь на ответе Уткарша.
В качестве имени JSON используются имена Getter минус get/is.
public class Example{
private String radcliffe;
public getHarryPotter(){
return radcliffe;
}
}
хранится как { "harryPotter": "whateverYouGaveHere" }
Для десериализации Джексон проверяет как сеттер, так и имя поля.
Для Json String { "word1": "example" } действуют оба приведенных ниже.
public class Example{
private String word1;
public setword2( String pqr){
this.word1 = pqr;
}
}
public class Example2{
private String word2;
public setWord1(String pqr){
this.word2 = pqr ;
}
}
Более интересным вопросом является тот порядок, который Джексон считает для десериализации. Если я пытаюсь десериализовать { "word1": "myName" } с помощью
public class Example3{
private String word1;
private String word2;
public setWord1( String parameter){
this.word2 = parameter ;
}
}
Я не тестировал вышеприведенный случай, но было бы интересно увидеть значения word1 и word2...
Примечание. Я использовал радикально разные имена, чтобы подчеркнуть, какие поля должны быть одинаковыми.
Ответ 5
Используя обе приведенные ниже аннотации, вынуждает выходной JSON включать is_xxx
:
@get:JsonProperty("is_something")
@param:JsonProperty("is_something")
Ответ 6
существует другой метод для этой проблемы.
просто определите новый подкласс, который расширяет свойство PropertyNamingStrategy и передает его экземпляру ObjectMapper.
здесь фрагмент кода может помочь больше:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
String input = defaultName;
if(method.getName().startsWith("is")){
input = method.getName();
}
//copy from LowerCaseWithUnderscoresStrategy
if (input == null) return input; // garbage in, garbage out
int length = input.length();
StringBuilder result = new StringBuilder(length * 2);
int resultLength = 0;
boolean wasPrevTranslated = false;
for (int i = 0; i < length; i++)
{
char c = input.charAt(i);
if (i > 0 || c != '_') // skip first starting underscore
{
if (Character.isUpperCase(c))
{
if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
{
result.append('_');
resultLength++;
}
c = Character.toLowerCase(c);
wasPrevTranslated = true;
}
else
{
wasPrevTranslated = false;
}
result.append(c);
resultLength++;
}
}
return resultLength > 0 ? result.toString() : input;
}
});
Ответ 7
Вы должны добавить конфигурацию в объект сопоставления объектов Jakson, например:
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.getObjectMapper().disable(MapperFeature.AUTO_DETECT_IS_GETTERS);