【问题标题】:MOXy - Serializing and Deserializing of Enums using Jackson2 Annotations (Weblogic 12.2.1.3)MOXy - 使用 Jackson2 注释对枚举进行序列化和反序列化 (Weblogic 12.2.1.3)
【发布时间】:2022-11-06 04:20:27
【问题描述】:

假设,我们有 2 个 RESTful Web 服务 (JAX-RS)。第一个服务充当消费者并调用第二个服务的 API。第二个服务(提供者)是使用 openapi-generator-maven-plugin 和 jaxrs-spec 选项和描述 API 的底层 .yml 文件生成的。提供者和消费者 Web 服务都成功部署在 Weblogic 应用程序服务器上,并按预期服务请求......

...除了一个小例外。 Enums 的序列化/反序列化没有按预期工作。 Eums 是使用相应的 Jackson2 注释 @JsonValue@Jsoncreator 生成的:

public enum MyEnum {
   FIRST_VALUE("first_value"),
   SECOND_VALUE("second_value");

   private static Map<String, MyEnum> ENUM_MAP = Stream
        .of(MyEnum.values())
        .collect(Collectors.toMap(s -> s.formatted, Function.identity()));

   private final String value;

   private MyEnum(String value) { this.value = value; }

   @JsonValue 
   public String value() { return value; }

   @JsonCreator
   public static MyEnum fromString(String string) {
        return Optional
            .ofNullable(ENUM_MAP.get(string))
            .orElseThrow(() -> new IllegalArgumentException(string));
    }

}

期望(假设 ObjectMapper 不会忽略 Jackson 注释)Java 对象 MyEnum.FIRST_VALUE 被序列化为 {"first_value"}。但是,结果(提供者 Web 服务接收和消费者 Web 服务发送的内容)是 {"FIRST_VALUE"}。怎么来的? Weblogic 使用 MOXy 作为默认 JSON 提供程序。而 MOXy 忽略了上面提到的 Jackson2 Annotations。

因此,问题是:如何让网络服务接收 {"first_value"} 而不是 {"FIRST_VALUE"}我应该如何调整我的 JAX-RS Jersey 客户端(在第一个 Web 服务中),以便在使用调用时将值 {"first_value"} 传递给我的第二个 Web 服务

Client client = ClientBuilder().newClient();
client.target(MY_URI)
      .request(MediaType.APPLICATION_JSON)
      .post(Entity.entity(MyEnum.FIRST_VALUE, MediaType.APPLICATION_JSON));

我尝试了以下方法:

  1. 当我们使用 Jackson 作为 JSON 提供者时,发现序列化/反序列化在 Java SE 环境中正常工作(在添加相应的 maven 坐标之后)。请点击here,我的示例枚举看起来一样(加上@JsonValue注解,减去@JsonProperty)。但是,序列化在 Java SE 单元测试中按预期工作
  2. 发现 MOXy 需要 JAXB-Annotations,因此我们可以使用 openapi-generator-maven-plugin 来生成 JAXB-Annotations。见here。似乎有点太复杂,无法实现目标。
  3. 编写自定义 XmlAdapter,请参阅 here。当杰克逊开箱即用时,我们为什么要这样做?
  4. 禁用 MOXy 作为默认 JSON 提供程序,请参阅 here。实际上,这解决了生产者方面的问题,但是消费者呢?客户端仍然发送“错误”的 JSON,因此服务会抛出异常。

【问题讨论】:

    标签: json enums weblogic


    【解决方案1】:

    我终于能够解决这个问题。希望这对一些在同样问题上苦苦挣扎的可怜人有所帮助。正如我在最初的问题中已经指出的那样,解决方案是禁用 MOXy:

    提供者:

    import javax.ws.rs.core.Application;
    public class MyApplication extends Application
    {
        @Override
        public Map<String, Object> getProperties()
        {
            Map<String, Object> proprties = new HashMap<>();
            proprties.put("jersey.config.server.disableMoxyJson", true);
    
            return proprties;
        }
    }
    

    另见Weblogic 12.2.1.3 from Moxy to Jackson

    消费者:

    javax.ws.rs.client.ClientBuilder.newClient().register(Class.forName("org.glassfish.jersey.jackson.JacksonFeature"));
    

    这将在客户端解决问题。

    另见Weblogic 12.2.1.2 - How to tune the object Serializer to use Jackson 2 and strange phenomena on jaxrs enablement for application/json endpoints

    向 99Sono 致敬。非常感谢你结束这次冒险!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 2013-05-20
      • 1970-01-01
      • 1970-01-01
      • 2013-07-17
      • 2021-11-30
      相关资源
      最近更新 更多