gpt4 book ai didi

java - Jersey 在抛出 WebApplicationException 时产生意外的默认媒体类型

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:05:45 25 4
gpt4 key购买 nike

我正在使用 JAX-RS API 开发一个 Web 服务,并将 Jersey 1.17 作为我的实现。

我希望客户可以在他们使用 Accept HTTP header 指定的 JSON 和 XML 之间进行选择。当客户端在请求中不包含 Accept header 时,我希望 JSON 成为默认值。我试图通过在 Produces 注释中将 MediaType.APPLICATION_JSON 放在 MediaType.APPLICATION_XML 之前来实现这一点。

这似乎在正常情况下有效:

$ curl 'http://localhost:8080/webservice/Bob'
{"text":"Hello, Bob"}

$ curl -H'Accept: application/json' 'http://localhost:8080/webservice/Bob'
{"text":"Hello, Bob"}

$ curl -H'Accept: application/xml' 'http://localhost:8080/webservice/Bob'
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Greeting text="Hello, Bob"/>

但是如果我从资源类的构造函数中抛出一个 WebApplicationException,响应媒体类型默认为 XML:

$ curl 'http://localhost:8080/webservice/Vader'
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Error message="Illegal name"/>

如果客户端包含 Accept header ,则媒体类型正确:

$ curl -H'Accept: application/json' 'http://localhost:8080/webservice/Vader'
{"message":"Illegal name"}

我如何配置 Jersey 以使用默认值,即使对于资源类构造函数抛出的错误也是如此?

这是我的资源类的代码(full example on GitHub):

package org.example.errorhandling;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;

import org.example.errorhandling.repr.Error;
import org.example.errorhandling.repr.Greeting;

@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@Path("/{name}")
public class Greeter {
private final String name;

public Greeter(@PathParam("name") String name) {
if ("Vader".equals(name)) {
Error error = new Error();
error.message = "Illegal name";
Response errorResponse = Response.status(Status.BAD_REQUEST).entity(error).build();
throw new WebApplicationException(errorResponse);
} else {
this.name = name;
}
}

@GET
public Response greet() {
Greeting greeting = new Greeting();
greeting.text = "Hello, " + name;
return Response.ok(greeting).build();
}
}

最佳答案

由于 suggestion,此问题有解决方法来自 usul_ .

解决方法是使用 selectVariant() 机制以编程方式选择与请求中的 Accept header 匹配的媒体类型。这使得以重复首选顺序为代价强制执行默认媒体类型成为可能。

这里是修改后的构造函数以使用此技术 (full code on GitHub):

public Greeter(@PathParam("name") String name, @Context Request request) {
if ("Vader".equals(name)) {
Error error = new Error();
error.message = "Illegal name";
List<Variant> variants = Variant.mediaTypes(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_XML_TYPE).add().build();
Variant variant = request.selectVariant(variants);
Response errorResponse = Response.status(Status.BAD_REQUEST).entity(error).variant(variant).build();
throw new WebApplicationException(errorResponse);
} else {
this.name = name;
}
}

关于java - Jersey 在抛出 WebApplicationException 时产生意外的默认媒体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21877409/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com