Jackson renames primitive boolean field by removing 'is'

后端 未结 10 770
渐次进展
渐次进展 2020-11-27 12:07

This might be a duplicate. But I cannot find a solution to my Problem.

I have a class

public class MyResponse implements Serializable {

    private          


        
相关标签:
10条回答
  • 2020-11-27 12:56

    This is a slightly late answer, but may be useful for anyone else coming to this page.

    A simple solution to changing the name that Jackson will use for when serializing to JSON is to use the @JsonProperty annotation, so your example would become:

    public class MyResponse implements Serializable {
    
        private boolean isSuccess;
    
        @JsonProperty(value="isSuccess")        
        public boolean isSuccess() {
            return isSuccess;
        }
    
        public void setSuccess(boolean isSuccess) {
            this.isSuccess = isSuccess;
        }
    }
    

    This would then be serialised to JSON as {"isSuccess":true}, but has the advantage of not having to modify your getter method name.

    Note that in this case you could also write the annotation as @JsonProperty("isSuccess") as it only has the single value element

    0 讨论(0)
  • 2020-11-27 12:57

    You can configure your ObjectMapper as follows:

    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);
                }
            });
    
    0 讨论(0)
  • 2020-11-27 13:00

    I didn't want to mess with some custom naming strategies, nor re-creating some accessors.
    The less code, the happier I am.

    This did the trick for us :

    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.annotation.JsonProperty;
    
    @JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates 
    public class MyResponse {
    
        private String id;
        private @JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name
        private @JsonProperty("isDeleted") boolean isDeleted;
    
    }
    
    0 讨论(0)
  • 2020-11-27 13:02

    The accepted answer won't work for my case.

    In my case, the class is not owned by me. The problematic class comes from 3rd party dependencies, so I can't just add @JsonProperty annotation in it.

    To solve it, inspired by @burak answer above, I created a custom PropertyNamingStrategy as follow:

    mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
      @Override
      public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
      {
        if (method.getParameterCount() == 1 &&
                (method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) &&
                method.getName().startsWith("set")) {
    
          Class<?> containingClass = method.getDeclaringClass();
          String potentialFieldName = "is" + method.getName().substring(3);
    
          try {
            containingClass.getDeclaredField(potentialFieldName);
            return potentialFieldName;
          } catch (NoSuchFieldException e) {
            // do nothing and fall through
          }
        }
    
        return super.nameForSetterMethod(config, method, defaultName);
      }
    
      @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")) {
    
          Class<?> containingClass = method.getDeclaringClass();
          String potentialFieldName = method.getName();
    
          try {
            containingClass.getDeclaredField(potentialFieldName);
            return potentialFieldName;
          } catch (NoSuchFieldException e) {
            // do nothing and fall through
          }
        }
        return super.nameForGetterMethod(config, method, defaultName);
      }
    });
    

    Basically what this does is, before serializing and deserializing, it checks in the target/source class which property name is present in the class, whether it is isEnabled or enabled property.

    Based on that, the mapper will serialize and deserialize to the property name that is exist.

    0 讨论(0)
提交回复
热议问题