使用 JAX-RS 将 JSON 查询参数转换为对象

IT小君   2021-12-17T23:05:23

我有一个 JAX-RS 资源,它将其参数作为 JSON 字符串获取,如下所示:

http://some.test/aresource?query={"paramA":"value1", "paramB":"value2"}

在这里使用 JSON 的原因是查询对象在实际用例中可能非常复杂。

我想将 JSON 字符串转换为 Java 对象,在示例中为 dto:

@GET 
@Produces("text/plain")
public String getIt(@QueryParam("query") DataTransferObject dto ) {
    ...
}

JAX-RS 是否支持从作为查询参数传递的 JSON 到 Java 对象的这种转换?

评论(6)
IT小君

是的,您可以这样做,但您需要自己编写转换代码。幸运的是,这很容易,您只需要编写一个具有公共String构造函数的类来进行转换。例如:

public class JSONParam {
    private DataTransferObject dto;

    public JSONParam(String json) throws WebApplicationException {
        try {
            // convert json string DataTransferObject and set dto
        }
        catch (JSONException e) {
            throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
                    .entity("Couldn't parse JSON string: " + e.getMessage())
                    .build());
        }
    }

    public DataTransferObject getDTO() {
        return dto;
    }
}

然后你可以使用:

@GET 
@Produces("text/plain")
public String getIt(@QueryParam("query") JSONParam json) {
    DataTransferObject dto = json.getDTO();
    ...
}
2021-12-17T23:05:24   回复
IT小君

如前所述,您确实需要将 String 参数显式转换为 JSON。但是没有必要使用像 org.json 的解析器那样原始的东西;JacksonGson可以在一两行中进行数据绑定(字符串到 JSON,JSON 到 POJO)。与杰克逊:

MyValue value = new ObjectMapper().readValue(json, MyValue.class);

(对于生产代码,只需创建一次 ObjectMapper 作为静态成员,重复使用)

Jackson 是大多数 JAX-RS 实现用来实现 POST 数据的数据绑定的工具,因此这非常相似。

2021-12-17T23:05:24   回复
IT小君

添加到 Jason 的解决方案中,使用http://www.json.org/java/(Crockford提供):

import org.json.JSONObject;

public class JSONParam {
    private DataTransferObject dto;

    public JSONParam(String json) throws WebApplicationException {
        try {
            // convert json string DataTransferObject and set dto
            JSONObject jo = new JSONObject(json);
            dto.setParamA(jo.getString("paramA"));
            dto.setParamB(jo.getString("paramB"));
            // There are other get methods for Integer, Double, etc. 
            // You can also build JSON from Java objects.
        }
        catch (JSONException e) {
            throw new WebApplicationException(Response.status(Status.BAD_REQUEST)
                    .entity("Couldn't parse JSON string: " + e.getMessage())
                    .build());
        }
    }

     public DataTransferObject getDTO() {
        return dto;
    }                  
}

不要重新发明轮子:-)

2021-12-17T23:05:24   回复
IT小君

JAX-RS 支持使用 JAXB(用于 XML 绑定的 Java API)将 JavaBean 绑定到 XML 或 JSON,反之亦然。可以在此处找到更多详细信息,例如:http : //www.ibm.com/developerworks/web/library/wa-aj-tomcat/index.html

你需要

  • 在 DataTransferObject 上添加 @XmlRootElement 注释
  • 在 DataTransferObject 中创建一个空的默认构造函数
  • 将 @Consumes(MediaType.APPLICATION_JSON) 注释添加到您的 WebService
2021-12-17T23:05:24   回复
IT小君

如果您对生成 DTO 感兴趣,我可以建议jsonschema2pojo吗?您可以使用JSON Schema定义对象并自动生成 DTO。

编写架构后,您还可以将其提供给您的使用者,以便他们准确了解应如何格式化请求。

2021-12-17T23:05:24   回复
IT小君

也许你可以使用 http://docs.spring.io/spring-framework/docs/2.5.x/api/org/springframework/beans/BeanUtils.html

BeanUtils.copyProperties(source, target)
2021-12-17T23:05:24   回复