@IntDef Android支持与杰克逊反序列化的公告

时间:2021-01-12 18:03:30

Using JacksonAnnotations along with Android Support Annotations. My POJO is:

使用JacksonAnnotations和Android支持注释。我的POJO是:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Schedule {
    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

    private Integer weekday;

    public Schedule() {
    }

    @Weekday
    public Integer getWeekday() {
        return weekday;
    }

    public void setWeekday(@Weekday Integer weekday) {
        this.weekday = weekday;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @IntDef({SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY})
    public @interface Weekday {}
}

From backed i get object:

从支持我得到对象:

{"schedule":{"weekday":"MONDAY"}}

What i want is to map Weekday to it's integer value defined in constants. Is there any way i can achieve this?

我想要的是将Weekday映射到常量中定义的整数值。有什么办法可以实现吗?

Update: The main purpose is optimization (You should strictly avoid using enums on Android like it said here).

更新:主要目的是优化(你应该严格避免在Android上使用枚举,就像它在这里说的那样)。

4 个解决方案

#1


3  

Since you can count on weekdays not growing out of control, creating a static map seems like a pretty clean solution. Providing a @JsonCreator factory named fromString will work with Jackson and will also play nicely with JAX-RS:

由于你可以指望工作日不会失去控制,因此创建静态地图似乎是一个非常干净的解决方案。提供一个名为fromString的@JsonCreator工厂将与杰克逊合作,并且还将与JAX-RS很好地配合:

public class Schedule {
    ...
    private static final ImmutableMap<String, Schedule> WEEKDAY_TO_INT_MAP =
            ImmutableMap.<String, Schedule>builder()
                .put("SUNDAY", withIntWeekday(0))
                .put("MONDAY", withIntWeekday(1))
                .put("TUESDAY", withIntWeekday(2))
                .put("WEDNESDAY", withIntWeekday(3))
                .put("THURSDAY", withIntWeekday(4))
                .put("FRIDAY", withIntWeekday(5))
                .put("SATURDAY", withIntWeekday(6))
                .build();

    public static Schedule withIntWeekday(int weekdayInt) {
        Schedule schedule = new Schedule();
        schedule.setWeekday(weekdayInt);
        return schedule;
    }

    @JsonCreator
    public static Schedule fromString(String weekday) {
        return WEEKDAY_TO_INT_MAP.get(weekday);
    }
    ...
}

#2


1  

Maybe I am missing something, but why not do something like this:

也许我错过了什么,但为什么不做这样的事情:

public class Schedule {
    public enum Weekday {
        SUNDAY(0),
        MONDAY(1),
        TUESDAY(2),
        WEDNESDAY(3),
        THURSDAY(4),
        FRIDAY(5),
        SATURDAY(6);

        private final Integer weekday;

        Weekday(Integer weekday) {
            this.weekday = weekday;
        }

        public Integer getWeekday() {
            return weekday;
        }
    }

    private Weekday weekday;

    public Integer getWeekday() {
        return weekday.getWeekday();
    }

    public void setWeekday(Weekday weekday) {
        this.weekday = weekday;
    }

}

#3


0  

If the backend is returning "MONDAY" as a string then you probably should not be using @IntDef because you will have to manage converting "MONDAY" into an integer value.

如果后端将“MONDAY”作为字符串返回,那么您可能不应该使用@IntDef,因为您必须管理将“MONDAY”转换为整数值。

I would try using the @StringDef annotation instead that way you won't have to worry about any sort of conversion between the backend and the client app. The only catch is you need to have reliable responses from your backend and agree upon the naming conventions ahead of time.

我会尝试使用@StringDef注释,这样您就不必担心后端和客户端应用之间的任何转换。唯一的问题是您需要从后端获得可靠的响应,并提前就命名约定达成一致。

If you change the type from @IntDef to @StringDef it would look like this:

如果将类型从@IntDef更改为@StringDef,它将如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Schedule {
    public static final String SUNDAY = "SUNDAY";
    public static final String MONDAY = "MONDAY";
    public static final String TUESDAY = "TUESDAY";
    public static final String WEDNESDAY = "WEDNESDAY";
    public static final String THURSDAY = "THURSDAY";
    public static final String FRIDAY = "FRIDAY";
    public static final String SATURDAY = "SATURDAY";

    private String weekday;

    public Schedule() {
    }

    @Weekday
    public String getWeekday() {
        return weekday;
    }

    public void setWeekday(@Weekday String weekday) {
        this.weekday = weekday;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @StringDef({SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY})
    public @interface Weekday {}
}

#4


0  

The elegant solution is using an Enum.

优雅的解决方案是使用Enum。

The efficient solution is writing a custom serializer that maps a week day string to an int and vice versa using switch statements.

有效的解决方案是编写一个自定义序列化程序,使用switch语句将一周的字符串映射到一个int,反之亦然。

You could also access the values in the StringDef annotation using reflection in your serializer, but that will be slower and less readable.

您还可以使用序列化程序中的反射来访问StringDef注释中的值,但这样会更慢且可读性更低。

#1


3  

Since you can count on weekdays not growing out of control, creating a static map seems like a pretty clean solution. Providing a @JsonCreator factory named fromString will work with Jackson and will also play nicely with JAX-RS:

由于你可以指望工作日不会失去控制,因此创建静态地图似乎是一个非常干净的解决方案。提供一个名为fromString的@JsonCreator工厂将与杰克逊合作,并且还将与JAX-RS很好地配合:

public class Schedule {
    ...
    private static final ImmutableMap<String, Schedule> WEEKDAY_TO_INT_MAP =
            ImmutableMap.<String, Schedule>builder()
                .put("SUNDAY", withIntWeekday(0))
                .put("MONDAY", withIntWeekday(1))
                .put("TUESDAY", withIntWeekday(2))
                .put("WEDNESDAY", withIntWeekday(3))
                .put("THURSDAY", withIntWeekday(4))
                .put("FRIDAY", withIntWeekday(5))
                .put("SATURDAY", withIntWeekday(6))
                .build();

    public static Schedule withIntWeekday(int weekdayInt) {
        Schedule schedule = new Schedule();
        schedule.setWeekday(weekdayInt);
        return schedule;
    }

    @JsonCreator
    public static Schedule fromString(String weekday) {
        return WEEKDAY_TO_INT_MAP.get(weekday);
    }
    ...
}

#2


1  

Maybe I am missing something, but why not do something like this:

也许我错过了什么,但为什么不做这样的事情:

public class Schedule {
    public enum Weekday {
        SUNDAY(0),
        MONDAY(1),
        TUESDAY(2),
        WEDNESDAY(3),
        THURSDAY(4),
        FRIDAY(5),
        SATURDAY(6);

        private final Integer weekday;

        Weekday(Integer weekday) {
            this.weekday = weekday;
        }

        public Integer getWeekday() {
            return weekday;
        }
    }

    private Weekday weekday;

    public Integer getWeekday() {
        return weekday.getWeekday();
    }

    public void setWeekday(Weekday weekday) {
        this.weekday = weekday;
    }

}

#3


0  

If the backend is returning "MONDAY" as a string then you probably should not be using @IntDef because you will have to manage converting "MONDAY" into an integer value.

如果后端将“MONDAY”作为字符串返回,那么您可能不应该使用@IntDef,因为您必须管理将“MONDAY”转换为整数值。

I would try using the @StringDef annotation instead that way you won't have to worry about any sort of conversion between the backend and the client app. The only catch is you need to have reliable responses from your backend and agree upon the naming conventions ahead of time.

我会尝试使用@StringDef注释,这样您就不必担心后端和客户端应用之间的任何转换。唯一的问题是您需要从后端获得可靠的响应,并提前就命名约定达成一致。

If you change the type from @IntDef to @StringDef it would look like this:

如果将类型从@IntDef更改为@StringDef,它将如下所示:

@JsonIgnoreProperties(ignoreUnknown = true)
public class Schedule {
    public static final String SUNDAY = "SUNDAY";
    public static final String MONDAY = "MONDAY";
    public static final String TUESDAY = "TUESDAY";
    public static final String WEDNESDAY = "WEDNESDAY";
    public static final String THURSDAY = "THURSDAY";
    public static final String FRIDAY = "FRIDAY";
    public static final String SATURDAY = "SATURDAY";

    private String weekday;

    public Schedule() {
    }

    @Weekday
    public String getWeekday() {
        return weekday;
    }

    public void setWeekday(@Weekday String weekday) {
        this.weekday = weekday;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @StringDef({SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY})
    public @interface Weekday {}
}

#4


0  

The elegant solution is using an Enum.

优雅的解决方案是使用Enum。

The efficient solution is writing a custom serializer that maps a week day string to an int and vice versa using switch statements.

有效的解决方案是编写一个自定义序列化程序,使用switch语句将一周的字符串映射到一个int,反之亦然。

You could also access the values in the StringDef annotation using reflection in your serializer, but that will be slower and less readable.

您还可以使用序列化程序中的反射来访问StringDef注释中的值,但这样会更慢且可读性更低。