基于枚举字段的 Java 类

huangapple go评论78阅读模式
英文:

Java Class based on Enum fields

问题

我在处理JWT并设置自定义字段。
所有这些自定义字段都在枚举中描述:

public enum JwtFields {
    userId,
    manyOtherCustomFieldsBellow,
    blaBlaBla
}

因此,每当我创建令牌时,我都不会传递键的字符串,而是使用枚举,因为它更快速和安全。

Claims claims = Jwts.claims().setSubject(userId);
claims.put(JwtFields.someCustomFieldFromEnum.name(), "someValue");

现在,一旦我检查接收到的令牌有效,并且所有必要的自定义字段都存在,我希望将其反序列化为某个TokenDecoded类,并将其附加到请求有效载荷,这样每当我处理请求时,我都会从JWT令牌中获得所有值和字段。

然而,这个反序列化类几乎包含了枚举中的所有字段,如果明天我将新字段添加到枚举中,我还必须手动更新我的TokenDecoded类,以包括那个新的自定义字段。

问题:
如何使TokenDecoded类基于枚举字段,以便如果我向枚举中添加新字段,它将自动出现在TokenDecoded中?是否涉及反射?还是有更简单的方法可以实现?

英文:

I'm dealing here with JWT and setting up custom fields.
All those custom fields are described in an Enum:

public enum JwtFields {
    userId,
    manyOtherCustomFieldsBellow,
    blaBlaBla
}

So whenever I create token instead of passing strings for the keys, I'm using an enum as it is faster and safer.

Claims claims = Jwts.claims().setSubject(userId);
claims.put(JwtFields.someCustomFieldFromEnum.name(), "someValue")

Now, once I check that the received token is valid and all necessary custom fields are present, I want to deserialise it to some TokenDecoded class and attach it to the request payload, so whenever I'm processing a request I will have all values and fields from the JWT token.

However, that deserialise class pretty much contains all fields from the enum, and if tomorrow I will add new fields to the enum, I'll have to also manually update my TokenDecoded class to include that new custom field too.

The question:
How can I make this TokenDecoded class to be based on the enum fields, so if I add a new field to the enum, it will be automatically present in TokenDecoded? Is there reflection involved? Or it could be achieved simpler?

答案1

得分: 1

Lombok提供了一个相反的功能:如果您在类中定义字段,您可以使用@FieldNameConstants(asEnum = true)进行注释,以生成基于字段名称的枚举。或者,如果您只需要将其作为字符串使用,则可以不使用asEnum参数,您将获得字段的public static final String

英文:

Lombok provides a feature that works the other way 'round: If you define your fields in a class, you can annotate it with @FieldNameConstants(asEnum = true) to generate an enum based on the field names. Or, without the asEnum parameter, you'll get public static final Strings for your fields if you only need it as Strings.

答案2

得分: 0

你有几个选择:

  • 使用 Map 而不是类。这是最简单的解决方案,但不强制执行类型或字段。
  • 代码生成:你可以在编译时生成类(例如 JavaPoet)。
  • 字节码生成:你可以在运行时为类生成字节码(例如 Javassist)。
  • 使用 Groovy 的 元编程 特性(或任何其他支持运行时数据结构定义的基于 JVM 的语言)。

在我看来,编译时的代码生成最适合你的情况。

请注意,如果你正在使用 JWT,你可能希望考虑使用 JWT 库,而不是重新发明轮子。

英文:

You have several options:

  • Use a Map instead of a class. Simplest solution but doesn't enforce typing or fields.
  • Code generation: you can generate the class at compile time (e.g. JavaPoet).
  • Byte code generation: you can generate byte code for the class at runtime (e.g. Javassist).
  • Use Groovy metaprogramming features (or any other JVM-based language that support runtime data structure definition).

In my opinion code generation at compile time is best suited to your scenario.

Note that if you're using JWT you might want to look into a JWT library instead of reinventing the wheel.

huangapple
  • 本文由 发表于 2020年3月15日 08:48:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/60688734.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定