【问题标题】:How do I return a List<String> from Rest call如何从 Rest 调用返回 List<String>
【发布时间】:2014-04-04 18:10:20
【问题描述】:

我正在尝试返回几种不同媒体类型的列表。我在 glassfish 4 上托管这个。

@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
public List<String> getSessions(){
    return Arrays.asList("foo","bar");
}

如果我在没有指定类型的情况下执行普通 GET,我会收到 500 内部服务器错误。指定 application/json 也会给我一个 500 内部服务器错误。服务器日志显示绝对没有错误。

如果我使用 Accept: text/plain 执行 GET,我会得到以下信息:

org.glassfish.jersey.message.internal.MessageBodyProviderNotFoundException: 找不到媒体类型 = 文本/纯文本、类型 = 类的 MessageBodyWriter java.util.Arrays$ArrayList, genericType=java.util.List.

我原以为 glassfish 可以在这里弄清楚如何处理基本集合类。当我尝试将它们解析为 json 并且显然没有 messagebodywriter 将它们转换为字符串时,它们会默默地失败。我错过了什么明显的东西吗?

更新 我使用此处的说明将 Jackson 添加为 jaxrs json 提供程序: https://github.com/FasterXML/jackson-jaxrs-providers

显然在当前版本中,我不需要专门注册JacksonFeature.class,我也不能,因为没有JacksonFeature 类,只有一个JacksonFeatures 接口。

我将此依赖项添加到我的项目中:

<dependency>
  <groupId>com.fasterxml.jackson.jaxrs</groupId>
  <artifactId>jackson-jaxrs-json-provider</artifactId>
  <version>2.3.0</version>
</dependency>

如果我通过 Response 对象返回 json,现在可以返回 json,如下所示:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getSessions(){
    Response r = Response.ok(Arrays.asList("foo","bar")).build();
    return r;
}

但是,尝试返回 List 仍然失败,并出现 500 内部服务器错误并且没有消息显示到服务器错误日志。

如果这是正确的方法,我愿意使用 Response 方法,但似乎其他方法应该可行。

【问题讨论】:

  • 由于 json 与键值对一起使用,因此您无法在 json 中传递列表。类似的文本你不能通过列表。如果你想传递字符串列表而不是将其转换为字符串数组并传递它

标签: java json rest jakarta-ee glassfish


【解决方案1】:

您必须启用对 Jersey 的 JSON 支持(Glassfish 中的 JAX-RS 实现)。 您可以在这里找到详细信息:

顺便说一句,添加 jersey-media-json-jackson 依赖项后,这个最小配置对我来说已经足够了:

@ApplicationPath("/rest")
public class App extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet<>();
        // enable JSON support through Jackson
        classes.add(JacksonFeature.class);
        // my rest service
        classes.add(MyRESTService.class);
        return classes;
    }
}

【讨论】:

  • 感谢 mihu86 的指导。当我尝试添加 jersey-media-json-jackson 依赖项时,我的部署因以下异常而爆炸:Unsatisfied dependencies for type [Set] with qualifiers [@Default] at injection point [[BackedAnnotatedParameter] Parameter 1 of [BackedAnnotatedConstructor ] @ Inject com.google.common.util.concurrent.ServiceManager(Set)] 我相信这是因为此依赖项使用了 Guava 14.0,我将其排除在外,但随后又出现了类似的错误。探索 Jackson 文档并尝试更新版本,如我的帖子中所述。
  • (Guava 14.0 与 glassfish 4 不兼容,因为它修改了清单以尝试支持@inject 注释。Guava 的后续版本工作正常。)
【解决方案2】:

您可以使用“响应”,但您必须将列表作为实体传递,以便响应构建器可以正确地形成响应。在您的代码中,您将列表委托给不知道 ArrayList 类型意味着什么的 ok() 方法,因此在您的代码中只需像这样添加实体:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getSessions(){
    Response r = Response.ok().entity(Arrays.asList("foo","bar")).build();
    return r;
}

注意:实体方法可以映射许多 MediaType,这意味着你可以使用这个:

@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})

或者即使您使用自己定制的 MediaType,它也能胜任:

@Produces({"application/vnd.myList+json", "application/vnd.myList+xml"})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-20
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多