使用 JAX-RS Jersey 2 和 Grizzly 的 Swagger 文档 [英] Swagger documentation with JAX-RS Jersey 2 and Grizzly

查看:47
本文介绍了使用 JAX-RS Jersey 2 和 Grizzly 的 Swagger 文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用 JAX-RS 实现了一个 Rest Web 服务(该功能不相关).现在我想使用 Swagger 生成它的文档.我已按照以下步骤操作:

I have implementated a Rest web service (the function is not relevant) using JAX-RS. Now I want to generate its documentation using Swagger. I have followed these steps:

1) 在 build.gradle 中,我得到了我需要的所有依赖项:

1) In build.gradle I get all the dependencies I need:

编译'org.glassfish.jersey.media:jersey-media-moxy:2.13'

2) 我用 Swagger 注释记录我的代码

2) I documentate my code with Swagger annotations

3) 我在我的应用程序子类中连接了 Swagger:

3) I hook up Swagger in my Application subclass:

public class ApplicationConfig extends ResourceConfig  {

    /**
     * Main constructor
     * @param addressBook a provided address book
     */
    public ApplicationConfig(final AddressBook addressBook) {
        register(AddressBookService.class);
        register(MOXyJsonProvider.class);
        register(new AbstractBinder() {
            @Override
            protected void configure() {
                bind(addressBook).to(AddressBook.class);
            }
        });
        register(io.swagger.jaxrs.listing.ApiListingResource.class);
        register(io.swagger.jaxrs.listing.SwaggerSerializers.class);

        BeanConfig beanConfig = new BeanConfig();
        beanConfig.setVersion("1.0.2");
        beanConfig.setSchemes(new String[]{"http"});
        beanConfig.setHost("localhost:8282");
        beanConfig.setBasePath("/");
        beanConfig.setResourcePackage("rest.addressbook");
        beanConfig.setScan(true);
    }
}

但是,当我在 http://localhost:8282/swagger.json 中访问我的服务时,我得到了这个输出.

However, when going to my service in http://localhost:8282/swagger.json, I get this output.

您可以在此处查看我的公共存储库.

You can check my public repo here.

推荐答案

在这种情况下(当对问题没有真正的解释时),我会抛出一个 ExceptionMapper.通常与服务器相关的异常,没有映射器来处理异常,所以它冒泡到容器,我们得到一个无用的 500 状态代码,也许还有一些来自服务器的无用消息(正如你从 Grizzly 看到的).

It's times like this (when there is no real explanation for the problem) that I throw in an ExceptionMapper<Throwable>. Often with server related exceptions, there are no mappers to handle the exception, so it bubbles up to the container and we get a useless 500 status code and maybe some useless message from the server (as you are seeing from Grizzly).

import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;

public class DebugMapper implements ExceptionMapper<Throwable>  {

    @Override
    public Response toResponse(Throwable exception) {
        exception.printStackTrace();
        if (exception instanceof WebApplicationException) {
            return ((WebApplicationException)exception).getResponse();
        }
        return Response.serverError().entity(exception.getMessage()).build();
    }  
}

然后只需在应用程序中注册

Then just register with the application

public ApplicationConfig(final AddressBook addressBook) {
    ...
    register(DebugMapper.class);
}

当您再次运行应用程序并尝试访问端点时,您现在将看到包含异常原因的堆栈跟踪

When you run the application again and try to hit the endpoint, you will now see a stacktrace with the cause of the exception

java.lang.NullPointerException
  at io.swagger.jaxrs.listing.ApiListingResource.getListingJson(ApiListingResource.java:90)

如果你看看 源代码 ApiListingResource.java:90,你会看到

If you look at the source code for ApiListingResource.java:90, you will see

Swagger swagger = (Swagger) context.getAttribute("swagger");

这里唯一可能导致 NPE 的是 context,它向上滚动会告诉你它是ServletContext.现在这就是它为空的原因.为了使成为ServletContext,应用程序需要在 Servlet 环境中运行.但是看看你的设置:

The only thing here that could cause the NPE is the context, which scrolling up will show you it's the ServletContext. Now here's the reason it's null. In order for there to even be a ServletContext, the app needs to be run in a Servlet environment. But look at your set up:

HttpServer server = GrizzlyHttpServerFactory
        .createHttpServer(uri, new ApplicationConfig(ab));

这不会创建 Servlet 容器.它只创建一个 HTTP 服务器.您具有创建 Servlet 容器所需的依赖项 (jersey-container-grizzly2-servlet),但您只需要使用它即可.所以代替之前的配置,你应该做

This does not create a Servlet container. It only creates an HTTP server. You have the dependency required to create the Servlet container (jersey-container-grizzly2-servlet), but you just need to make use of it. So instead of the previous configuration, you should do

ServletContainer sc = new ServletContainer(new ApplicationConfig(ab));
HttpServer server = GrizzlyWebContainerFactory.create(uri, sc, null, null); 
// you will need to catch IOException or add a throws clause

查看GrizzlyWebContainerFactory 用于其他配置选项.

现在,如果您运行它并再次点击端点,您将看到 Swagger JSON.请注意,来自端点的响应只是 JSON,而不是文档接口.为此,您需要使用可以解释 JSON 的 Swagger UI.

Now if you run it and hit the endpoint again, you will see the Swagger JSON. Do note that the response from the endpoint is only the JSON, it is not the documentation interface. For that you need to use the Swagger UI that can interpret the JSON.

顺便说一句,感谢 MCVE 项目.

Thanks for the MCVE project BTW.

这篇关于使用 JAX-RS Jersey 2 和 Grizzly 的 Swagger 文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆