Поэтому я решил начать использовать Undertow как в качестве эксперимента, так и из-за отличных результатов, достигнутых в тестах производительности. И хотя я думаю, что это фантастика, есть функция, которая либо отсутствует, либо я не могу найти.
Я хочу разработать веб-службу RESTful, поэтому мне важно определить, какой HTTP-метод вызывается. Теперь я могу получить это из RequestMethod в параметре HttpServerExchange, но если бы это было необходимо для каждого обработчика, это стало бы утомительно.
Мое решение, которое работает, но я знаю, что это неправильно, таково:
Создал интерфейс аннотации под названием HTTPMethod:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface HTTPMethod {
public enum Method {
OTHER, GET, PUT, POST, DELETE
}
Method method() default Method.OTHER;
"абстрактный" класс (который не является абстрактным):
public abstract class RESTfulHandler implements HttpHandler {
@Override
public void handleRequest(HttpServerExchange hse) throws Exception {
for (Method method : this.getClass().getDeclaredMethods()) {
// if method is annotated with @Test
if (method.isAnnotationPresent(HTTPMethod.class)) {
Annotation annotation = method.getAnnotation(HTTPMethod.class);
HTTPMethod test = (HTTPMethod) annotation;
switch (test.method()) {
case PUT:
if (hse.getRequestMethod().toString().equals("PUT")) {
method.invoke(this);
}
break;
case POST:
if (hse.getRequestMethod().toString().equals("POST")) {
method.invoke(this);
}
break;
case GET:
if (hse.getRequestMethod().toString().equals("GET")) {
method.invoke(this);
}
break;
case DELETE:
if (hse.getRequestMethod().toString().equals("DELETE")) {
method.invoke(this);
}
break;
case OTHER:
if (hse.getRequestMethod().toString().equals("OTHER")) {
method.invoke(this);
}
break;
}
if (test.method() == HTTPMethod.Method.PUT) {
method.invoke(this);
}
}
}
}
}
и реализация обоих вышеперечисленных:
public class ItemHandler extends RESTfulHandler{
@HTTPMethod(method=GET)
public List<String> getAllItems()
{
System.out.println("GET");
return new ArrayList<>();
}
@HTTPMethod(method=POST)
public void addItem()
{
System.out.println("POST");
}
@HTTPMethod
public void doNothing()
{
System.out.println("OTHERS");
}
}
Теперь, как я уже сказал, это работает, но я уверен, что абстрактному классу и его реализации чего-то не хватает, чтобы они правильно склеивались. Итак, мой вопрос состоит из двух частей:
1) Есть ли лучший/правильный способ фильтрации HTTP-запросов в Undertow? 2) Как правильно правильно использовать аннотации в приведенном выше случае?