Подтвердить что ты не робот

Различные способы получения сервлет-контекста

Может кто-нибудь объяснить мне, в чем разница между этими способами получения ServletContext HttpServlet?

doGet( HttpServletRequest request, ... ){
    getServletConfig( ).getServletContext( );
    request.getSession( ).getServletContext( );
    getServletContext( );
}

Есть ли разница в производительности или в самом контексте? Если это так, это лучший способ? Есть ли другой способ получения контекста?

4b9b3361

Ответ 1

Там еще один.

request.getServletContext();

Технически нет никакой разницы в производительности, только request.getSession() будет неявно создавать объект сеанса HTTP, если он еще не создан. Поэтому, если это еще не сделано, то захват контекста сервлета через сеанс может занять несколько наносекунд дольше, если сеанс еще не создан.

Там также нет различий в возвращаемом контексте. Эти методы предназначены только для удобства и какой метод для получения контекста зависит от контекста;) вы сейчас сидите.

Если вы сидите в методе, вызываемом сервлет service() (например, doGet(), doPost() и т.д.), то просто используйте унаследованный метод getServletContext(). Другие способы только излишне добавить больше символов в исходный код.

@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) {
    ServletContext context = getServletContext();
    // ...
}

Если вы сидите в сервлет init(ServletConfig), то унаследованный getServletContext() пока недоступен, пока вы 't называется super.init(config). Вам нужно взять его из ServletConfig.

@Override
public void init(ServletConfig config) {
    ServletContext context = config.getServletContext();
    // ...
}

Но гораздо лучше переопределить init(). В приличном сервлете вам обычно не нужно переопределять init(ServletConfig).

@Override
public void init() {
    ServletContext context = getServletContext();
    // ...
}

Если вы не сидите в сервлете, но, например, a filter, которому не хватает унаследованного метода getServletContext(), и у вас есть ServletRequest в руках, тогда вы можете схватить его оттуда.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = request.getServletContext();
    // ...
}

Обратите внимание, что это новое с сервлета 3.0. Раньше вам приходилось захватывать его из сеанса.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = request.getSession().getServletContext();
    // ...
}

Это, однако, не очень приятно, если вы беспокоитесь о ненужном создании сеанса. Следовательно, введение ServletRequest#getServletContext() — хотя вы также можете просто извлечь его из FilterConfig (эй, есть еще один способ!).

private FilterConfig config;

@Override
public void init(FilterConfig config) {
    this.config = config;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
    ServletContext context = config.getServletContext();
    // ...
}

И затем есть прослушиватели сеансов HTTP, где вы можете прослушивать a.o. сеанс уничтожить. Нет другого способа получить контекст сервлета, чем через HttpSession#getServletContext().

@Override
public void sessionDestroyed(HttpSessionEvent event) {
    ServletContext context = event.getSession().getServletContext();
    // ...
}

Здесь вам не нужно беспокоиться о ненужном создании сеанса, потому что в тот момент уже создано за долгое время. Обратите внимание на то, что там нет ServletRequest, так как необязательно средство активного HTTP-запроса во время ожидания сеанса на стороне сервера.

Как и в прошлом, также ServletContext#getContext(), который возвращает ServletContext другого веб-приложения, развернутого на тот же сервер (это работает только если сервер настроен на разрешение доступа к перекрестному контексту на целевом веб-сервере).

ServletContext otherContext = context.getContext("/otherContextPath");

Но для этого уже требуется текущий ServletContext, для которого вы уже должны знать, какой способ его использовать.