Как мне работать с HTTP-методами в Undertow?

Поэтому я решил начать использовать 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) Как правильно правильно использовать аннотации в приведенном выше случае?


person gryzlaw    schedule 23.09.2014    source источник


Ответы (1)


С помощью команды Redhat и участников Undertow удалось найти несколько ответов, надеюсь, это поможет кому-то еще:

1) Последняя версия Undertow имеет io.undertow.server.RoutingHandler, который делает то же самое, что я предлагаю, только без необходимости аннотаций.

2) Есть адаптер для RESTEasy от JBoss: resteasy-undertow или собственную структуру hammock, которая включает RESTEasy + Undertow + Weld.

3) Undertow уже поддерживает сервлеты 3, поэтому их можно комбинировать для использования аннотаций, если вы предпочитаете.

person gryzlaw    schedule 25.09.2014