Java EE 6. Что нового в Servlet API 3.0



    С выходом Java EE 6 на ряду со значительными изменениями в JPA 2.0 спецификации сервлетов 3.0 также притерпела ряд улучшений: упростилась разработка и процедура развертывания, конфигурирование стало более удобным, появилась поддержка асинхронных запросов и улучшилась модель безопасности. Далее я попытаюсь осветить основные изменения в API.

    Программирование и развертывание сервлетов упростилось главным образом за счет введения аннотаций для декларирования сервлет (@WebServlet), фильтров (@WebFilter), листнеров (@WebListener) и ограничений безопасности (@ServletSecurity). Таким образом, и дескриптор развертывания web.xml стал опциональным элементом. Обращаю внимание, что сами компоненты Servlet API не стали POJO, привычную иерархию интерфейсов и классов никто не отменял. Также добавилась аннотация для поддержки загрузки файлов @MultipartConfig и для установки параметров инициализации @WebInitParam.

    Пример Hello World сервлета
    package net.ismailov.tests;

    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;

    @WebServlet(name="hw", urlPatterns = "/hello_world")
    public class HelloWorld extends HttpServlet{

      public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        PrintWriter writer = response.getWriter();
        writer.println("<h1>Hello, World!</h1>");
        
      }

    }



    Хорошей новостью стало появление возможности динамической регистрации сервлетов:
    ServletRegistration.Dynamic dynamic =
    servletContext.addServlet(“DynamicTestServlet”, “net.ismailov.DynamicTestServlet”)
    dynamic.addMapping(“/dynamicServlet”);



    Для поддержки длительных операций добавилась возможность асинхронной работы сервлета. Для включения данной возможности необходимо:
    //Либо декларативно указать поддержку асинхронного режима
    @WebServlet(asyncSupported=true)
    //Либо установить при динамической инициализации сервлета
    dynamic.setAsyncSupported(true);

    После этого response не перестает существовать по завершении метода. Необходимо вызвать
    AsyncContext ctx = ServletRequest.startAsync(req, res)

    Теперь экземляры request и response будут сохранены, и, по завершении выполнения асинхронного метода, могут быть использованы для вывода пользователю одним из методов AsyncContext.dispatch(/*различные параметры*/)
      @WebServlet("/MyAsyncTestServlet" asyncSupported=true)
      public class TestServlet extends HttpServlet {
        public void doGet(HttpServletRequest req, HttpServletResponse res) {
          ...
          AsyncContext aCtx = request.startAsync(req, res);
          ScheduledThreadPoolExecutor executor = new ThreadPoolExecutor(10);
          executor.execute(new MyAsyncService(aCtx));
        }
      }

      public class MyAsyncService implements Runnable {
        private AsyncContext ctx;
        public MyAsyncService(AsyncContext ctx) {
          this.ctx = ctx;
        }
        public void run() {
          // Может быть вызвана долгая операция с последующим выводом
          ctx.dispatch("/result.jsp");
      }



    Как уже упоминалось, с новым API стало возможно задавать ограничения доступа, например:

    @WebServlet(name="hw", urlPatterns = "/hello_world")
    @ServletSecurity(@HttpConstraint(rolesAllowed = {"admin"}))
    public class HelloWorld extends HttpServlet{


    Естественно, задача задания ролей/пользователей, равно как и аутентификация, являются vendor-specific. К примеру, glassfish выдает basic http auth формочку:



    Также имеется возможность накладывания ограничений на методы доступа:
    @ServletSecurity(httpMethodConstraints={ @HttpMethodConstraint("GET"),
      @HttpMethodConstraint(value="POST", rolesAllowed={"user_group_1"})})



    Основные нововведения в api 3.0 я постарался отразить, осталось лишь отметить, что с декабря прошлого года доступна «эталонная реализация» спецификации Java EE6: Glassfish 3.0, в которой можно поэкспериментировать с новым API.

    Комментарии 34

      –14
      <?=«Hello, world!»;?>

      Простите, вырвалось.
        –6
        На современных PHP-фрймворках кода примерно так же будет, как и указано выше. Даже больше.
          –1
          Согласен.
          На самом деле я немного завидую людям, которые пишут на подобных языках ;)
        0
        А что за контейнер сервлетов используется в Glassfish? Tomcat 7.0 с поддержкой Servlet API 3.0 вроде как ещё не вышел.
          0
          Если мне не изменяет память, там таки модификация Tomcat.
            0
            Память вам наставила рога :) Там Grizzly
              0
              Не взаимоисключющие технологии, в общем-то. Используются связкой.
            0
            >Tomcat 7.0 с поддержкой Servlet API 3.0 вроде как ещё не вышел
            а, кстати, когда планируется? побегал по тырнетам, нигде не нашел сроков. может ищу плохо, или в рассылках каких анонсы проскакивали?
              0
              Полгядел я их roadmap
              Чета как-то невесело. Правда обновлялся 4 месяца назад, но работы оставалось — конь не валялся. Думаю, к осени осилят.
                0
                спасибо! странно что я сам его не заметил :")

                да, как то грустно всё у них… жаль :(
            +2
            Нравится мне новый API.
            Надеюсь услышать больше на sun tech days.
              0
              Судя по программе, на sun tech days будет обзор по различным нововведениям, не только Servlet API 3.0… Не удивлюсь если даже презентации будет с одного из официальных вебинаров, которые кстати были в декабре)… Хотя туда тоже собираюсь)
                0
                Интересно будет услышать информации о судьбе Glassfish вообще. Ведь теперь Oracle позиционирует его как «Reference design»… Уже скачал WebLogic, смотрю, что да как. Хотя, честно говоря, мне вполне хватает возможностей GlassFish.
                  0
                  Из глассфиша ушли фичи масштабирования (кластеризация и т.д.), теперь по сценариям Оракла за этими фичами надо идти к веблоджику.
                    0
                    А что, WebLogic уже подружили с Java EE 6.0 / Servlet API 3.0?
                      0
                      По-моему поддержки EE 6 в веблоджике еще нет.
                –2
                Эдак мы скоро на Spring забьем, за ненужностью.
                  +1
                  Не забьем. Пока в спецификации будет отсутствовать легкий MVC фреймворк, спрингам и стратсам ничего не угрожает.
                  0
                  Я так понял, что Servlet API 3.0 даёт возможность полностью отказаться от дескриптора развёртывания (web.xml и faces-config.xml) благодаря аннотациям Java-кода. Это так или несовсем?
                    0
                    От web.xml — да. Про faces-config.xml я ничего не говорил :-)
                      0
                      Не совсем. Есть ещё вещи, для которых нужен web.xml.
                        0
                        От этих вещей тоже можно уйти)
                          0
                          Ну, уходить, таки не есть самоцель, imho :-) Всё же хорошо, что без фанатизма.
                        0
                        jetty позволяет это уже несколько лет
                        0
                        Поправьте в статье responce -> response
                          0
                          fixed, thx
                          +1
                          Что-то мне кажется, что плюшек маловато для «3.0»…

                          Аннотации — давно пора было сделать, иногда полезно.
                          Динамическая регистрация сервлетов — зачёт, я даже знаю где это облегчит жизнь.
                          Асинхронная работа — наверняка полезно, хоть и не сталкивался с такой необходимостью.
                          Ограничение доступа по ролям — по сравнению с Spring Security (acegi), как трёхколёсный велосипед рядом с космическим кораблём.

                          Итого, 1.5 из 4 плюшек реально выглядят полезными. «Маловато будет!»
                            0
                            Про асинхронную работу непонятно.
                            Как в итоге результат работы прилетит к клиенту?
                              0
                              Или это просто для того, чтобы долгая операция не тормозила все на свете и выполнялась в отдельном потоке?
                                0
                                По сути для того, чтобы породить новый поток, который займется обработкой долгой операции со своей копией риквеста, а пользователю отдать сразу респонс. Как поступать по окончании долгой операции — решать Вам. В частности используя AsyncContext.complete() пыполнить нечто, что отразится на UI клиента.
                              +1
                              все таки в старом добром web.xml есть плюс — можно посмотреть какой сервлет на какой URL маппится в одном файле… То же самое касается и диспатчер сервлета для спринга. Да, аннотации в Spring 2.5+ — классно, но когда куча контроллеров, очень удобно видеть какой контроллер на какой URL повешан, опять же, в одном файле :)
                              Либо можно взять за правило давать схожие имена сервлетам (контроллерам в Spring MVC) очень близкие к URL паттернам :)
                                0
                                Ну тут как-бы извечная дилемма — кому-то удобнее метаданные хранить рядом с объектами, к которым они относятся, а кому-то — в отдельном, едином месте. На вкус и цвет…
                                0
                                простите за офтоп, но что это за прозрачные рыбки?
                                  0
                                  Кэп подсказывает, что glassfish :-)

                                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                Самое читаемое