我正在使用 JAX-RS API 开发一个 Web 服务,并以 Jersey 1.17 作为我的实现。
我希望客户可以在 JSON 和 XML 之间进行选择,他们使用Accept
HTTP 标头。当客户端不包含以下内容时,我希望 JSON 成为默认值Accept
请求中的标头。我试图通过放置来实现这一点MediaType.APPLICATION_JSON
before MediaType.APPLICATION_XML
in the Produces
注解。
这似乎在正常情况下有效:
$ 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 配置为使用默认值,甚至对于从资源类构造函数引发的错误也是如此?
这是我的资源类的代码(GitHub 上的完整示例 https://github.com/glerup/jersey-error-handling-sample-app):
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();
}
}