Jersey 检查 JSON 正文并根据 JSON 正文内容创建不同的 POJO

Jersey check JSON body and create differing POJO based on JSON body content

与将 2 个不同 JSON 正文发布到同一路径的客户合作。希望 Jersey POST 可以将 2 个不同的 JSON 主体映射到 POJO @ 相同路径:

最初尝试像这样重载 API 端点方法,但没有成功:

@POST
@Path("message")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public RumorMessage basicMessage(RumorMessage rumor) {
    System.out.println("basic message: " + rumor);
    return rumor;
}

@POST
@Path("message")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public WantMessage basicMessage(WantMessage want) {
    System.out.println("basic message: " + want);
    return want;
}

示例 JSON 两种消息类型的正文

{"Want": {"ABCD-1234-ABCD-1234-ABCD-125A": 3,
      "ABCD-1234-ABCD-1234-ABCD-129B": 5,
      "ABCD-1234-ABCD-1234-ABCD-123C": 10
     } ,
"EndPoint": "https://example.com/gossip/asff3"
}

{"Rumor" : {"MessageID": "ABCD-1234-ABCD-1234-ABCD-1234:5" ,
        "Originator": "Phil",
        "Text": "Hello World!"
        },
"EndPoint": "https://example.com/gossip/13244"
}

如何将 POST 的 2 个不同的 JSON 主体解析为相同的 @Path("message")?

您的问题最常见的解决方案是更改客户端代码并针对不同 'Pojo-types' 使用不同的路径或媒体类型(是的,媒体类型也是一个很好的解决方案,请参阅:https://sites.google.com/site/restframework/media-type-design).

但如果这不可能(会很伤心,因为它闻起来不太好)你可以为两种类型定义 one 资源方法(端点)并编写一些代码识别它们。

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
//...
@POST
@Path("message")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String basicMessage(String json) throws JSONException {
    ObjectMapper mapper = new ObjectMapper();
    JsonNode obj = mapper.readTree(json);
    if(obj.hasNonNull("???")){
        RumorMessage msg = mapper.treeToValue(obj, RumorMessage.class);
        //...
        return mapper.writeValueAsString(msg);
    } else if(obj.hasNonNull("??????")) {
        WantMessage msg = mapper.treeToValue(obj, WantMessage.class);
        //...
        return mapper.writeValueAsString(msg);
    } else {
        throw new BadRequestException();
    }
}