解组相同Jersey服务中的不同对象

时间:2015-07-26 14:17:57

标签: java ajax json jersey marshalling

我正在尝试找到一种方法来创建一个服务,该服务将接收不同的对象类型作为JSON并正确地解组它们。到目前为止,我能够使用自定义反序列化器和google的gson库来实现单个或列表对象解组,但这确实是有限的。我可以使用它创建的唯一类型的服务只能将一种类型的对象作为参数,如下所示:

@GET
@Path("myService")
@Consumes(MediaType.APPLICATION_JSON)
public Response myService(MyEntity entity) {
    //Random stuff using entity
    return Response.ok().build();
}

但是我正在尝试创建这样的服务:

@GET
@Path("advancedService")
@Consumes(MediaType.APPLICATION_JSON)
public Response advancedService(MyEntity1 entity1, MyEntity2 entity2, @QueryParam("normalParam") int normalParam, @QueryParam("normalBoolean") boolean normalBoolean) {
    //Do stuff using both entity1 and entity2.
    return Response.ok().build();
}

现在,当我通过ajax请求发送JSON时,为了使服务能够理解对象结构,必须将其格式化为:

$.ajax({
    url: 'services/MyServices/myService',
    type: 'GET',
    data: JSON.stringify(myEntityObjectStructure),
    contentType: 'application/json; charset=UTF-8',
    dataType: 'json',
    success: function (result, status, xhr) {
      //blahblah
    }
  });

data配置中,它只需要读取对象结构,否则会混淆。我正在尝试发送这样的请求:

$.ajax({
    url: 'services/MyServices/myService',
    type: 'GET',
    data: {
        myEntity1: JSON.stringify(myEntity1ObjectStructure),
        myEntity2: JSON.stringify(myEntity2ObjectStructure),
        normalParam: param1,
        booleanParam: param2
    },
    contentType: 'application/json; charset=UTF-8',
    dataType: 'json',
    success: function (result, status, xhr) {
      //blahblah
    }
  });

但它只是不会读取param名称而且它会被卡住,因为它认为它必须将所有data结构解组为单个对象。

我正在使用球衣2.19。此外,我正在寻找一个正常的解决方案,而不是'hacky'。我也可以将对象作为“字符串”发送并自行取消编组,但我希望使用注释并使用自定义序列化程序或某种类型的web.xml配置来处理服务标准。 )编组。我喜欢使用gson来简化(特别是使用日期格式而不需要注释以进行字段排除等)但我也可以使用Jackson

编辑:它也可以是POST类型的服务,我只需要它有2个不同的类作为参数。

1 个答案:

答案 0 :(得分:0)

我认为最漂亮的解决方案是创建一个父对象,其中包含您要传输的所有内容。

@XmlRootElement
class AdvancedServiceInput {
    public MyEntity1 entity1;
    public MyEntity2 entity2;
}

然后通过接受容器对象来接收数据:

@GET
@Path("advancedService")
@Consumes(MediaType.APPLICATION_JSON)
public Response advancedService(AdvancedServiceInput input, @QueryParam("normalParam") int normalParam, @QueryParam("normalBoolean") boolean normalBoolean) {
    //Do stuff using both input.entity1 and input.entity2.
    return Response.ok().build();
}

是什么让这个解决方案美丽

  • 通常较少的参数可提高可读性。具有大量参数的方法使得难以识别哪个参数用于哪个参数。 (特别是因为java不允许命名参数)
  • 拥有容器可让您的代码更容易扩展。如果要添加第三个实体类型,只需扩展容器类,就不必更改(大量)方法签名。
  • XML和JSON内容应该只包含 one,single root 元素。因此,您可能必须使用此方法来创建有效的传输消息。