java - 在同一 Jersey 服务中解码不同对象

标签 java ajax json jersey marshalling

我正在尝试找到一种方法来创建一个服务,该服务将接收不同的对象类型作为 JSON 并正确解码它们。到目前为止,我能够使用自定义反序列化器和谷歌的 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
    }
  });

但它只是不会读取参数名称,并且会卡住,因为它认为必须解码所有 data结构为单个对象。

我使用的是 2.19 号 Jersey 。另外,我正在寻找一种正常的解决方案,而不是“黑客”解决方案。我也可以将对象作为“字符串”发送并自己解码,但我想坚持使用注释并拥有自定义序列化器或某种类型的 web.xml 的服务标准。负责(取消)编码的配置。我喜欢使用gson因为它的简单性(特别是日期格式并且不需要字段排除注释等),但我愿意使用 Jackson也是如此。

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

最佳答案

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

@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 内容应该仅包含一个单一根元素。因此,无论如何您可能都必须使用此方法来创建有效的传输消息。

关于java - 在同一 Jersey 服务中解码不同对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31638000/

相关文章:

java - 将类强制转换为 Spring 中的接口(interface)

ajax - jquery ajax页面如何加载?

javascript - jquery .each() 不工作

javascript - Sequelize 引用错误的外键

python - 将 django ValuesQuerySet 转换为 json 对象

扩展 Activity 时出现 java.lang.NullPointerException

java - 我可以将正则表达式与 Stacks 一起使用吗?

javascript - 如何在执行嵌入式脚本时仅插入使用 $.ajax() 加载的完整页面的一部分?

java - 使用 Logback 即时更改日志文件路径属性

javascript - 修改现有 Shopify 主题与从头开始构建