Я разрабатываю веб-сервис с использованием JAX-RS API с Джерси 1.17 в качестве моей реализации.Джерси производит непредвиденный тип носителя по умолчанию при бросании WebApplicationException
Я хочу, чтобы у клиентов был выбор между JSON и XML, которые они задают, используя HTTP-заголовок Accept
. Я хочу, чтобы JSON был по умолчанию, когда клиент не включил заголовок Accept
в запрос. Я попытался достичь этого, разместив 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"}
Как настроить Джерси для использования по умолчанию даже для ошибок, которые возникают из конструктора класса ресурсов?
Вот код моего класса ресурса (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();
}
}
Почему вы используете конструктор, а не 'greet' метод получить' @PathParam («имя») '? –
@ LutzHorn В моем реальном веб-сервисе я захватываю '@PathParam (« имя »)' в конструкторе, чтобы выставить несколько подресурсов. В моем конструкторе я просматриваю объект, идентифицированный 'name' в бэкэнд-системе, и я хочу немедленно отправить исключение, если сбой поиска. – glerup