【问题标题】:Convert JSON query parameters to objects with JAX-RS使用 JAX-RS 将 JSON 查询参数转换为对象
【发布时间】:2011-02-11 10:57:47
【问题描述】:

我有一个 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 对象的这种转换?

【问题讨论】:

    标签: java json jakarta-ee jax-rs


    【解决方案1】:

    是的,您可以这样做,但您需要自己编写转换代码。幸运的是,这很容易,您只需要编写一个具有公共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();
        ...
    }
    

    【讨论】:

    • 既然“JSONParam”似乎只是包装“DataTransferObject”并使用基于字符串的构造函数......是否可以将基于字符串的构造函数添加到“DataTransferObject”?
    • 您可以阅读更多关于parameter conversion in the Jersey documentation的信息。
    【解决方案2】:

    添加到 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;
        }                  
    }
    

    不要重新发明轮子:-)

    【讨论】:

    • 如果您不通过参数传递您的 JSON 对象,则无法使用此解决方案。但是你可以使用莉莉建议的版本(lili
    【解决方案3】:

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

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

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

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        【解决方案5】:

        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

        【讨论】:

        【解决方案6】:

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

        BeanUtils.copyProperties(source, target)
        

        【讨论】:

          猜你喜欢
          • 2019-04-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-14
          • 1970-01-01
          • 2017-02-24
          • 1970-01-01
          相关资源
          最近更新 更多