Разница между сеансами.getServletContext() и Session.getServletContext().getContext ("/SampleProject")

у меня есть экземпляр Tomcat 6, работающий на моей локальной машине.

я внес следующие изменения в его конфигурацию:

  • In/conf/context.xml – изменен тег следующим образом

    <Context crossContext="true">
    
  • In/conf/server.xml – изменен тег следующим образом

    <Connector port="8080" protocol="HTTP/1.1" emptySessionPath="true"
           connectionTimeout="20000" 
           redirectPort="8443" />
    

Предположим, у меня есть военный файл с именем SampleProject.war развернуть здесь извлечь в папку SampleProject.

в некоторых сервлет в этой войне, скажи SampleServlet, Я пишу два блока кода, как показано ниже :

ServletContext context1 = session.getServletContext();

и

ServletContext context2 = session.getServletContext().getContext("/SampleProject");

в чем разница между context1 и context2? Я думал, что оба относятся к контексту приложения. Но если я установлю какой-то атрибут в context1 и context2, Я не получаю значение в context2.

любая помощь будет оценили.

3 ответов


я чувствую, что ваш вопрос был немного неправильно понят и что у вас уже было базовое понимание API, т. е. когда веб-приложение устанавливает его crossContext="true" можно использовать getContext() чтобы получить доступ к контексту, который соответствует некоторому другому веб-приложению, развернутому на сервере.

getServletContext().getContext() equals NULL unless <Context crossContext="true">

насколько я понял, ваш вопрос на самом деле заключается в том, что в /SameWebApp почему

ServletContext context1 = session.getServletContext();
context1.setAttribute("contextAttribute", new Object());
ServletContext context2 = session.getServletContext().getContext("/SameWebApp");

System.out.println(context1.equals(context2)); // prints false, or 
System.out.println(context2.getAttribute("contextAttribute")); // prints null (at least they could have been clones)

всего одним словом, ответ- "безопасность". Представьте, если бы вы не могли гарантировать, что атрибут контекста "adminEmail" не был изменен зло веб-приложение, имеющее свой crossContext=true. Ваше приложение может потенциально помочь скомпрометировать себя, как только придет запрос "Забыли пароль"! :)

погружение в внутренности Tomcat

Tomcat 7 предоставляет class ApplicationContext implements ServletContext что возвращается из getContext("/context-root") as

    if (context.getCrossContext()) {
        // If crossContext is enabled, can always return the context
        return child.getServletContext();
    } else if (child == context) {
        // Can still return the current context
        return context.getServletContext();
    } else {
        // Nothing to return
        return (null);
    }

здесь context принадлежит текущему веб-приложению и child представляет другое веб-приложение. Но, подождите, что заставляет Tomcat называть это ребенок?

эти двое на самом деле не ApplicationContext но факты StandardContext класс implements Context но вместо конкретных вещей сервлета содержит определенные настройки конфигурации Tomcat для веб-приложения, такие как crossContext, hostname, mimeMappings и т. д. StandardContext.getParent() дает Container и, следовательно, он был упомянут как ребенок выше.

в любом случае, нас интересует случай, когда child == context - это правда, т. е. getContext() был вызван на "/SameWebApp". Вызов делегируется StandardContext.getServletContext() который был реализован, чтобы вернуть другой экземпляр of ApplicationContext.

вот почему атрибуты, которые вы установили в context1 не нашли в context2.

но подождите, есть еще кое-что. Почему StandardContext.getServletContext() вернуться как

return (context.getFacade());

экземпляр Tomcat в основном выполняет два типа Java код:

  • контейнеров, и
  • пользователь развернул

код контейнера является "доверенным" и иногда может потребоваться запуск с повышенными привилегиями. С другой стороны, код пользователя не является надежным и должен быть ограничен от компрометации внутренних компонентов Tomcat.

одна из вещей, которую Tomcat делает для достижения этого, всегда обертывает ApplicationContextFacade вокруг ApplicationContext (и, следовательно,StandardContext как хорошо). Итак, чтобы подытожить, что кажется, простой ServletContext реализация на самом деле StandardContext сопоставляется с ApplicationContext, который затем заворачивают в ApplicationContextFacade.

для получения дополнительной информации о том, как ApplicationContextFacade работает с использованием отражения в тандеме с Globals.IS_SECURITY_ENABLED и SecurityUtil.isPackageProtectionEnabled() настройки пожалуйста, взгляните на почему сервлеты получают доступ к Tomcat ApplicationContext через фасад на SO.

ссылки:
Исходный Код Tomcat 7 (Ссылка Для Скачивания)


абсолютно эти два объекта контекста отличаются от других.. Context1 объект дает текущий контекст сервлета веб-приложения obj. (ServletContext context1 = сеанс.getServletContext();)

и

объект context2 дает объект servletcontext указанного веб-приложения (ServletContext context2 = сеанс.getServletContext().getContext ("/SampleProject");)

вы устанавливаете объект в одном контексте и пытаетесь получить с помощью другого контекст, поэтому невозможно получить атрибут из другого контекста веб-приложения, поместив его в текущий контекст приложения. Но вы можете получить атрибут находится в другом контексте веб-приложения с помощью второго метода.


подумайте о стандартах платформы OO & java EE + безопасность.

первый вызов возвращает окончательно контекст сервлета для текущего приложения со всеми поддерживаемыми операциями.

второй вызов возвращает скопировать в контекст сервлета, который может быть для любого приложения. Как сказано (довольно туманно!) в Javadoc, это цель, чтобы позволить вам получить RequestDispatcher, поэтому вы можете отправлять на страницы других приложений. Это другое важное, но неявное требование чтобы сделать это безопасно и уважать спецификации Java EE, которые не позволяют обмениваться состоянием сеанса или контекстом сервлета между приложениями. Представьте себе, какой ужасный ущерб " rogue App B "может нанести" good App A", если он может просто изменить (или прочитать) данные контекста сервлета грубой силой. Вот почему это копия.

следовательно, установка атрибутов на копии не приводит к изменениям в оригинале. Вы можете утверждать, что копия должна вызвать некоторое "исключение, не поддерживаемое операцией". Кроме того, вы можно утверждать, что getRequestDispatcher должен быть рефакторирован либо в другой класс, либо разрешить передачу URL-адреса контекста приложения. ... Но, к сожалению, ни то, ни другое не является правдой. B^)