JAX/Jersey Пользовательский код ошибки в Response
В Джерси, как мы можем "заменить" строку состояния, связанную с известным кодом состояния?
например.
return Response.status(401).build();
генерирует HTTP-ответ, содержащий:
HTTP/1.1 401 Unauthorized
Я (а не я, но клиентское приложение) хотел бы видеть ответ как:
HTTP/1.1 401 Authorization Required
Я пробовал следующие подходы, но тщетно:
1) Это просто добавляет строку в тело ответа HTTP
return Response.status(401).entity("Authorization Required").build();
2) То же самое и с этим:
ResponseBuilder rb = Response.status(401);
rb = rb.tag("Authorization Required");
return rb.build();
Цените свою помощь!
-spd
Ответы
Ответ 1
Для этого в Джерси у вас есть концепция класса WebApplicationException. Один из методов заключается в том, чтобы просто расширить этот класс и весь один из методов, чтобы установить возвращаемый текст ошибки. В вашем случае это будет:
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.*;
public class UnauthorizedException extends WebApplicationException {
/**
* Create a HTTP 401 (Unauthorized) exception.
*/
public UnauthorizedException() {
super(Response.status(Status.UNAUTHORIZED).build());
}
/**
* Create a HTTP 404 (Not Found) exception.
* @param message the String that is the entity of the 404 response.
*/
public UnauthorizedException(String message) {
super(Response.status(Status.UNAUTHORIZED).entity(message).type("text/plain").build());
}
}
Теперь в вашем коде, который реализует службу останова, вы просто выкинете новое исключение этого типа, передав текстовое значение в конструкторе, например.
throw new UnauthorizedException("Authorization Required");
Это может создать класс, подобный этому для каждого из ваших интернет-исключений, и сделать подобным образом.
Это также объясняется в руководстве пользователя в Джерси - хотя код на самом деле немного неверен:
https://jersey.github.io/nonav/documentation/latest/user-guide.html/#d4e435
Ответ 2
Я не уверен JSR 339: JAX-RS 2.0: API Java для веб-служб RESTful уже охватывал это или нет.
Возможно, вам придется расширить Response.StatusType.
public abstract class AbstractStatusType implements StatusType {
public AbstractStatusType(final Family family, final int statusCode,
final String reasonPhrase) {
super();
this.family = family;
this.statusCode = statusCode;
this.reasonPhrase = reasonPhrase;
}
protected AbstractStatusType(final Status status,
final String reasonPhrase) {
this(status.getFamily(), status.getStatusCode(), reasonPhrase);
}
@Override
public Family getFamily() { return family; }
@Override
public String getReasonPhrase() { return reasonPhrase; }
@Override
public int getStatusCode() { return statusCode; }
public ResponseBuilder responseBuilder() { return Response.status(this); }
public Response build() { return responseBuilder().build(); }
public WebApplicationException except() {
return new WebApplicationException(build());
}
private final Family family;
private final int statusCode;
private final String reasonPhrase;
}
И вот несколько расширенных типов statust.
public class BadRequest400 extends AbstractStatusType {
public BadRequest400(final String reasonPhrase) {
super(Status.BAD_REQUEST, reasonPhrase);
}
}
public class NotFound404 extends AbstractStatusType {
public NotFound404(final String reasonPhrase) {
super(Status.NOT_FOUND, reasonPhrase);
}
}
Вот как я это делаю.
@POST
public Response create(final MyEntity entity) {
throw new BadRequest400("bad ass").except();
}
@GET
public MyEntity read(@QueryParam("id") final long id) {
throw new NotFound404("ass ignorant").except();
}
// Disclaimer
// I'm not a native English speaker.
// I don't know what 'bad ass' or 'ass ignorant' means.