如何通过工厂方法从 JAX-RS 中 REST 请求中的 JSON 主体读取数据对象?

问题描述 投票:0回答:1

在使用 JAX-RS(Jersey 3.1.1、Jackson 2.14.2)的 Java REST 服务中,我有一个不可变的数据对象,例如:

public class MyDataObj {
    private int a;
    public static MyDataObj valueOf(String jsonStr) {
        return new MyDataObj(new ObjectMapper().readTree(jsonStr).get("a").asInt());
    }
    public MyDataObj(int a) { this.a = a; }
    public int getA() { return a; }
}

我想从请求的 JSON 正文中读取它。为了简洁起见,上面的示例跳过了错误检查等。这是尝试读取请求正文的服务方法:

@POST
@Path("/myService")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response myService(MyDataObj serviceBody) {
    String msg = doSomethingMeaningfulWith(serviceBody.getA());
    return Response.ok().entity("{ \"result\": \"" + msg + "\" }");
}

使用内容类型“application/json”和正文

{ "a": 42 }
调用服务失败,并出现 HTTP 415“不支持的媒体类型”错误。例外的是
org.eclipse.persistence.exceptions.JAXBException Exception Description: The class MyDataObj requires a zero argument constructor or a specified factory method.  Note that non-static inner classes do not have zero argument constructors and are not supported.

如果我使用

@HeaderParam
(并在请求标头中发送数据)或
@QueryParam
(在 GET 请求中发送数据)注释“serviceBody”参数,上面的代码确实会成功,因为 JAX-RS 指定了您可以使用静态“valueOf”方法自行从 JSON 构造对象,该方法采用单个“String”作为参数,而不是使用默认构造函数和 setter。

但是上面的例子中“valueOf”静态方法不会被调用。

现在的问题是:如何在某个地方注册一个“工厂方法”来构造该对象?或者有什么替代方法吗?

java json jackson jersey jax-rs
1个回答
0
投票

选项1 最简单的方法是使用

@JsonCreator
注释并提供构造函数:

    @JsonCreator(mode = JsonCreator.Mode.PROPERTIES)
    public UserData(@JsonProperty("a") int a) {
        this.a = a
    }
© www.soinside.com 2019 - 2024. All rights reserved.