Как стать автором
Обновить

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

Java *


С выходом 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.
Теги:
Хабы:
Всего голосов 47: ↑37 и ↓10 +27
Просмотры 21K
Комментарии Комментарии 34