Swagger UI导致​​对生成除JSON之外的内容类型的操作的HTTP 406不可接受的响应 [英] Swagger UI causing HTTP 406 Not Acceptable response for operations producing content types other than json

查看:392
本文介绍了Swagger UI导致​​对生成除JSON之外的内容类型的操作的HTTP 406不可接受的响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个发布于Jersey并由Swagger记录的REST API,也有一个使用该API的Swagger UI安装.

I have a REST API published with Jersey and documented with Swagger, I also have a Swagger UI installation consuming that API.

几乎我所有的操作都会产生application/json并按预期工作,除了一个GET操作会产生:'text/plain; charset = utf-8'

Almost all my operations produce application/json and work as expected, except for one GET operation that produces: 'text/plain;charset=utf-8'

当我尝试从Swagger UI调用服务时,服务器记录一个javax.ws.rs.NotAcceptableException并返回406响应.如果我从REST客户端调用相同的服务,它将按预期工作.

When I try to call the service from the Swagger UI, the server logs a javax.ws.rs.NotAcceptableException and returns a 406 response. If I call the same service from a REST client it works as expected.

@GET
@Path("/text")
@Produces(MediaType.TEXT_PLAIN + ";charset=utf-8")
@ApiOperation(value= "Return text")
public Response getText(@QueryParam("user") String user) {
    return Response.ok(textService.getTextForUser(user)).build();
}

如果我更改为@Produces(MediaType.APPLICATION_JSON +; charset = utf-8"),则可以正常使用,但我不想设置错误的内容类型.

If I change to @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8") then it works fine, but I don't want to set a wrong content type.

问题似乎是Swagger UI错误地将Accept标头设置为application/json,这可以通过观察请求来看到:

The problem seems to be that Swagger UI is wrongly setting the Accept headers to application/json as can be seen by observing the request:

GET /supertext/text?user=1
...
Accept: application/json

使用其余客户端时,Accept标头为:

When using the rest client the Accept header are:

GET /supertext/text?user=1
...
Accept: */*

为什么Swagger UI无法正确设置Accept标头?

Why is Swagger UI not setting the Accept headers properly?

可以配置吗?

推荐答案

当发现@Produces批注包含单个值时,swagger ui似乎将接受标头设置为application/json,否则将显示一个下拉列表在用户界面中列出,以从可用的内容类型中进行选择.

It seems that swagger ui sets the accept header to application/json when it finds that the @Produces annotation contains a single value, otherwise it renders a drop-down list in the ui to choose from the available content types.

在swagger-ui.js中:

In swagger-ui.js:

opts.responseContentType = $("div select[name=responseContentType]", $(this.el)).val();

当下拉列表不存在时,该属性将变为未定义.

When the drop-down list doesn't exist, the property becomes undefined.

稍后在代码中,如果属性为null或未定义,则将响应内容类型设置为application/json:

Later in the code, the response content type is set to application/json if the property is null or undefined:

在swagger.js中:

In swagger.js:

if (this.type === "POST" || this.type === "GET" || this.type === "PATCH") {
    if (this.opts.responseContentType) {
      responseContentType = this.opts.responseContentType;
    } else {
      responseContentType = "application/json";
    }
  }

因此,我的解决方案是修改swagger-ui.js中的代码,以确保设置了正确的内容类型,方法是探索Produces数组并选择第一个元素作为响应内容类型:

So my solution was to modify the code in swagger-ui.js to make sure that the correct content-type was set, by exploring the produces array and choosing the first element as the response content type:

在swagger-ui.js中替换以下行:

In swagger-ui.js replace the line:

opts.responseContentType = $("div select[name=responseContentType]", $(this.el)).val();

使用:

if($("div select[name=responseContentType]", $(this.el)).val() === undefined) { 
    opts.responseContentType = opts.parent.model.produces[0];
}

else {
    opts.responseContentType = $("div select[name=responseContentType]", $(this.el)).val();
}

这篇关于Swagger UI导致​​对生成除JSON之外的内容类型的操作的HTTP 406不可接受的响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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