Код: Выделить всё
@GET
@Path("/my-endpoint")
@Produces(MediaType.TEXT_PLAIN)
public Response myEndpoint(@QueryParam("mySuperParam") @NotNull final MyParamType myParam) {
return ok(myParam.toString());
}
Код: Выделить всё
// Simple wrapper around String. This is simplified for StackOverflow.
public record MyParamType(@Nullable String value) {
public MyParamType {
if(value == null)
return;
// Some custom validation
if(!value.contains("-")) {
throw new IllegalArgumentException("Is missing -");
}
}
@Override
public String toString() {
return value;
}
}
Код: Выделить всё
import javax.ws.rs.ext.ParamConverter;
import javax.ws.rs.ext.ParamConverterProvider;
import javax.ws.rs.ext.Provider;
@Provider
public class MyParamConverterProvider implements ParamConverterProvider {
@Override
public ParamConverter getConverter(
final Class rawType,
final Type genericType,
final Annotation[] annotations
) {
if (rawType.isAssignableFrom(MyParamType.class)) {
try {
return (ParamConverter) new MyParamConverter();
} catch (final IllegalArgumentException e) {
// Here I DO have access to the QueryParam's name
final @NotNull String paramName = /* extract "mySuperParam" from the annotations just above*/
// POSSIBLE THROW LOCATION #1
throw new IllegalArgumentException("bad param:" + paramName);
}
}
return null;
}
Код: Выделить всё
import javax.ws.rs.ext.ParamConverter;
public class MyParamConverter implements ParamConverter {
@Override
public MyParamType fromString(final String value) {
if (value == null) {
return null;
}
try {
return new MyParamType(value);
} catch (final IllegalArgumentException e) {
// Here I do NOT have access to the param's name
// POSSIBLE THROW LOCATION #2
throw new IllegalArgumentException(e.getMessage()); // Rethrowing. Keep reading to know why.
}
}
@Override
public @Nullable String toString(final @Nullable MyParamType value) {
if (value == null) {
return null;
}
return value.toString();
}
}
Я начинаю с написание ExceptionMapper:
Код: Выделить всё
import javax.ws.rs.BadRequestException;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;
@Provider
public class MyExceptionMapper implements ExceptionMapper {
@Override
public Response toResponse(final BadRequestException exception) {
return Response.status(Response.Status.BAD_REQUEST)
.entity("I wish I had the param name to show you!")
.build();
}
}
Неважно, все, что мне нужно сделать, это заменить любой из двух. strong> throw new IllegalArgumentException(...) сверху с помощью throw new BadRequestException(...).
Проблема: ни одно из двух местоположений не является полностью удовлетворительным.
- Если я выброшу исключение BadRequestException в «ВОЗМОЖНОМ МЕСТЕ № 2», оно будет перехвачено. сопоставителем исключений, но у меня нет доступа к имени параметра.
- Невозможно выполнить выброс из «ВОЗМОЖНОГО МЕСТА THROW #1», потому что RestEasy никогда не войдет в этот блок catch! Любое исключение, созданное в ВОЗМОЖНОМ МЕСТЕ #2, перехватывается RestEasy и преобразуется в некоторый HTTP-ответ.
Примечание : Я мог бы передать аннотации конструктору MyParamConverter, но мой инстинкт подсказывает мне, что мне не хватает более стандартного решения.
Подробнее здесь: https://stackoverflow.com/questions/790 ... st-message
Мобильная версия