我正在使用JAX-RS API开发一个Web服务,并将Jersey 1.17作为我的实现。
我希望客户端可以使用Accept
HTTP标头在JSON和XML之间进行选择。当客户端在请求中不包含Accept
标头时,我希望JSON成为默认值。我试图通过在MediaType.APPLICATION_JSON
注释MediaType.APPLICATION_XML
之前放置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
标头,则媒体类型正确无误:
$ 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();
}
}
答案 0 :(得分:1)
由于来自suggestion的usul_,此问题有解决方法。
解决方法是使用selectVariant()
机制以编程方式选择与请求中的Accept
标头匹配的媒体类型。这使得可以以重复首选订单为代价来强制执行默认媒体类型。
以下是修改为使用此技术的构造函数(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;
}
}
答案 1 :(得分:0)
您是否尝试过使用Jersey Exception Mappers? 以下是https://github.com/jersey/jersey/blob/master/examples/exception-mapping/src/main/java/org/glassfish/jersey/examples/exception/Exceptions.java
的示例