Try English version of Quizful



Раздаем бесплатные Q! подробности в группе Quizful.Alpha-test
Топ контрибуторов
loading
loading
Знаете ли Вы, что

Вы можете подписаться на RSS ленту новых тестов сервиса Quizful, в том числе и отдельно по каждой категории

Лента обновлений
ссылка Dec 13 19:03
Комментарий от zrred:
list(range(3))[2]
Traceback (most recent call last):
Fil...
ссылка Dec 13 12:05
Комментарий от NinaMandarin:
Мені сподобався тест по CSS, що згадав, а що і взна...
ссылка Dec 13 09:14
Комментарий от toNtr:
Я думаю, смыст вопроса в том, что если нужно определить св...
ссылка Dec 12 21:09
Комментарий от nak13:
эммм... т.к. прототипа func нет и объявлена она после ma...
ссылка Dec 12 20:44
Комментарий от sherdi:
Хороший тест
Статистика

Тестов: 153, вопросов: 8597. Пройдено: 421956 / 2061294.

Нововведения в стандарте Servlet API 2.5

head tail Статья
категория
Java EE
дата17.07.2009
авторindegro
голосов8

[Disclaimer: Данная статья была переведена в рамках "Конкурса на лучший перевод статьи" на сервисе Quizful. Ссылка на оригинал находится внизу страницы.]

26 сентября 2005 года компания Sun Microsystems и экспертная группа по JSR-154 опубликовала релиз технической поддержки, который должен стать исправленной версией Servlet API версии 2,4. При нормальных условиях такие релизы экспертных групп по JSR включают лишь уточнения, улучшения и полезные решения существующих ошибок в сфере безопасности в предыдущих версиях. Однако, в данном случае было добавлено несколько нововведений, которые привели к пересмотру и выходу версии 2.5.

В данной статье покажу, что нового было добавлено в Servet API 2.5, опишу каждое нововведение и улучшение, объясню, почему изменения были так необходимы, и покажу Вам как пользоваться ими в Ваших программах, основанных на Servlet API.

При работе с нововведениями в стандарте Servlet API нужно иметь в виду версии контейнеров, которые поддерживает данный стандарт. На данный момент в последних версиях таких серверов как Tomcat, Jboss AS, Apache Geronimo реализована поддержка Servlet API 2.5.

Среди изменений и улучшений, которые были представлены в Servlet API версии 2.5, можно отметить следующие:

  • Зависимость от платформы J2SE 5.0.
  • Поддержка аннотаций.
  • Удобства при написании дескриптора приложения web.xml
  • Убраны некоторые ограничения, накладываемые предыдущими версиями Servlet API.
  • Уточнение принципов работы сервлетов для некоторых экстремальных ситуаций.

Давайте по порядку рассмотрим данные изменения и улучшения.

Зависимость от платформы J2SE 5.0.

При работе с Servlet API теперь нужно имметь в виду, что стандарт версии 2.5 требует J2SE 5.0 (JDK 1.5) как минимальное требование к платформе. Это означает, что все новые свойства языка, начиная с версии 5.0 (шаблоны, автоматическое преобразование встроенных типов в объекты, новые конструкции для написания цикла, новый еnum тип, статическое импортирование классов и аннотации для описания метаданных) будут доступны для программистов, работающих с Servlet API версии 2.5.

Традиционно сервлеты и JEE релизы поочерёдно использовали новые свойства JSE платформ. Но в этот раз в стандарте Servlet API 2.5 минимальным требованием стала платформа J2SE 1.5, таким образом миновав версию 1.4. Экспертная группа, которая занимается разработкой стандарта Servlet API, решила использвать J2SE 1.5 по одной такой причине: в J2SE 1.5 добавлена возможность описания метаданных – аннотации.

Аннотации

Аннотации – новая особенность языка, описанная как часть стандарта JSR-175 (Возможность описания метаданных для языка программирования Java). Аннотации предоставляют механизм для украшения конструкций языка (классы, методы, поля и т.п.) с помощью метаданных. Аннотации не являются исполняемым кодом, но помечают код таким образом, что процессоры байт-кода могут менять своё поведение, основываясь на метаинформации, которая описывается с помошью аннотаций.

Новая возможность для написания метаинформации предоставляет очень простой механизм для аннотирования кода и движок для написания библиотек обработки метаинформации и классы для написания новых типов аннотаций.

Ниже приведён пример аннотации при написании веб-сервиса.

	import javax.jws.WebService;
	import javax.jws.WebMethod;

	@WebService
	public class HelloWorldService {

		@WebMethod
		public String helloWorld() {
			return "Hello World!";
		}
	} 

Две аннотации @WebService и @WebMethod, определённые в JSR-181 (Метаданные для веб-сервисов для Java платформы) импортируются как обычные классы, помечают данный класс как веб-сервис и помечают метод helloWorld() как метод веб-сервиса. Сами по себе аннотации ничего не делают. Они подобны меткам, которые оставлены на полях блокнота. Однако, когда контейнер во время загрузки классов увидит эти аннотации в байт-коде, он сможет создать веб-сервис и экпортирует метод веб-сервиса .

Аннотации могут принимать параметры, которые представляются собой пары значений типа имя/значение. Информациия о параметрах сохраняется вместе с аннотацией и может служить для изменения поведения контейнера в конкретной ситуации. Ниже приведён более сложный пример аннотирования кода:

@WebService(
	name = "PingService",
	targetNamespace="http://acme.com/ping"
)
@SOAPBinding(
	style=SOAPBinding.Style.RPC,
	use=SOAPBinding.Use.LITERAL
)
	public class Ping {
		@WebMethod(operationName = "Foo")
		public void foo() { }
	} 
}

Во время загрузки этого класса контейнер прочитает аннотации, содержащиеся в коде вместе с параметрами, и создаст веб-сервис с именем PingService и методом Foo, используя удалённый вызов процедур. По существу аннотации определяют поведение, согласно которому класс будет загружен контейнером и инициализирован в среде.

Язык Java определяет сравнительно небольшое количество аннотаций (согласно JSR-175). Интересные типы аннотаций определны в других JSR-ах:

  • JSR-250: Основные типы аннотаций для платформы Java
  • JSR-220: Аннотации для EJB 3.0
  • JSR-224: Аннотации для веб-сервисов, основанных на Java API for XML
  • JSR-181: Метаданные для веб-сервисов для платформы Java

Аннотации для Servlet API версии 2.5

Возвращаясь к Servlet версии 2.5, можно сказать, что стандарт описывает, как некоторые аннотации работают в среде, поддерживающей Servlet версии 2.5. Простые контейнеры сервлетов могут игнорировать эти аннотации, в то время как контейнеры, котороые соответсвуют стандарту JEE 5, обязаны поддержитвать работу с ними.

Некоторые аннотации предоставляют альтернативу для XML элементов, которые описывают стандартное поведение сервлета и которые должны находиться в дескрипторе веб-приложения web.xml. Некоторые аннотации служат как указания для контейнера выполнить определённые операции, которые, по существу, должен был сделать сам сервлет.

Точный список аннотаций полностью не утверждён, потому что стандарт Servlet API не определяет аннотаций, он лишь описывает, какое влияние оказывают аннотации на окружение, в котором выполняются сервлеты. Ниже приводится описание некоторых аннотаций, которые можно встретить при работе в среде JEE 5, а также их применение.

@Resourse и @Resources нужно располагать перед классом или переменной. Сервлет-контейнер при наличии таких аннотаций должен выполнить «resource injection» (инициализация источников данных). Когда контейнер видит такие аннотации, то он обязан инициализировать переменные нужными значениями перед тем, как сервлет сможет обрабатывать запросы. Используя такую аннотацию, вы можете не делать поиск объектов в JNDI в коде сервлета и не объявлять их в дескрипторе приложения. Всю необходимую работу выполнит контейнер сервлетов. Имя и тип переменной определяется автоматически с помощью механизма Reflection, однако это можно переопределить с помощью параметров, задаваемых в аннотациях. Объекты, которые можно таким образом задать, могут быть, например, источником базы данных или переменная окружения. Ниже приводится простой пример использвания данной аннотации.

@Resource javax.sql.DataSource catalog;

public getData() {
  Connection con = catalog.getConnection();
} 

В таком случае контейнер перед запуском сервлета сначала создаст экземпляр класса сервлета, найдет в JNDI сервисе переменную, которая будет именоваться catalog с типом DataSource, автоматически проинициализирет переменную catalog в сервлете найденным значением из JNDI.

Важно отметить, что в целях эффективности работы такого механизма только ограниченное число классов может поддерживать «resource injection». Ниже перечислены такие классы:

  • классы сервлетов
  • классы фильтров для сервлетов (servlet filters)
  • обработчики событий сервлетов
  • обработчики событий для JSP библиотек

@Resources аннотация очень похожа на @Resource. Она содержит в себе массив, состоящий из @Resource аннотаций. Обе аннотации определены в JSR-250 (Основные аннотации для Java платформы).

Рассмотрим @PostConstruct и @PreDestroy. Если эти аннотации присоединены к методам, тогда методы начинают служить как методы времени жизни. Метод, аннотированный с @PostConstruct, будет вызван после того, как создан класс, и после того, как все переменные проинициализированы. @PreDestroy метод вызывается перед разрушением сервлета, чтобы освободить ресурсы, которые он занимал. Методы времени жизни должны быть методами класса, которые ничего не возвращают (иметь тип void) и не выбрасывают никаких исключений. Для сервлетов такие методы могут служить заменой стандартным методам init() и destroy(). Такое поведение описано в JSR-250.

@EJB аннотация. Подобна @Resource. Она разработана для инициализации переменных, которые должны ссылаться на EJB компоненты. Данная аннотация определена в стандарте EJB 3.0 . Параметры, которыми она обладает, предназначены для поиска EJB объекта в контейнере.

@WebServiceRef. Подобна @Resource. Предназначена для поиска и инициализации переменных, которые указывают на объекты, работающих в роли веб-сервисов. Определена в стандарте JAX-WS 2.0

@PersistenceContext,@PersistenceContexts,@PersistenceUnit, and @PersistenceUnits. Аннотации предназначены для инициализации переменных, которые указывают на объекты, работающие с базами данных. Определена в стандарте EJB 3.0 для работы с объектами, которые могут быть сохранены в persistence хранилищах данных.

@DeclareRoles. Определяет роли безопасности в пределах работающего приложения.

@RunAs. Используется для указания роли, от имени которой может быть запущен класс.

Производительность при работе с аннотациями.

Использовать или нет аннотации – особенно если вы не собираетесь их использвать – вопрос не такой уж и сложный. Для начала нужно понять, какое они имеют влияние на производительность, в частности, какое влияние они имеют на старт сервера. Для того, что бы сервер смог увидеть, что в пределах класса имеются аннотации, ему нужно загрузить все классы из папок WEB-INF/classes, WEB-INF/lib (согласно стандарту, сервер не должен искать классы в других папках) и проанализировать их. Если вы не используете аннотации, то процесс проверки на наличие аннотации можно избежать. Для этого в дескрипторе веб-приложения в теге <web-app> нужно указать атрибут metadata-complete со значением равным true. Пример приведён ниже:

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         version="2.5" metadata-complete="true">
</web-app> 

Удобства при написании дескриптора приложения web.xml

Стандарт Servlet 2.5 ввёл некоторые изменения в формат дескриптора веб-приложения для более удобного описания необходимых зависимостей.

Использование в именах сервлетов групповых символов.

Во-первых, при написании элемента <filter-mapping> вы может использовать звёздочку (*) в элементе <servlet-name>, чтобы обозначить все сервлеты. В предыдущих версиях можно было назначить только один фильтр только одному сервлету примерно таким образом:

<filter-mapping>
	<filter-name>Image Filter</filter-name>
	<servlet-name>ImageServlet</servlet-name>
</filter-mapping> 

Сейчас это можно сделать вот так:

<filter-mapping>
	<filter-name>Image Filter</filter-name>
	<servlet-name>*</servlet-name>  <!-- New -->
</filter-mapping> 

Множественные шаблоны при задании соответствий.

Во-вторых, при написании <servlet-mapping> или <filter-mapping>, вы можете указать множественный шаблон в одном и том же элементе. <servlet-mapping> ранее поддерживал только один элемент <url-pattern>. Теперь таких элементов можно задать несколько. Например,

<servlet-mapping>
	<servlet-name>color</servlet-name>
	<url-pattern>/color/*</url-pattern>
	<url-pattern>/colour/*</url-pattern>
</servlet-mapping> 

Тоже самое справедливо и для элемента <filter-mapping>:

<filter-mapping>
	<filter-name>Multipe Mappings Filter</filter-name>
	<url-pattern>/foo/*</url-pattern>
	<servlet-name>Servlet1</servlet-name>
	<servlet-name>Servlet2</servlet-name>
	<url-pattern>/bar/*</url-pattern>
</filter-mapping> 

Имена HTTP методов.

Ранее в элементе <http-method> можно было указать только те имена методов, которые описываются стандартом протокола HTTP версии 1.1. Если вспомнить, то элемент <http-method> определял методы, для которых действовало правило, задаваемое в элементе <security-constraint>. Исторически методы, которые можно задать, описываются стандартом протокола HTTP/1,1: GET, POST, PUT, DELETE, HEAD, OPTIONS, и TRACE . Однако, протокол HTTP/1.1 имеет возможность расширить набор существующих методов и WebDAV одна из популярных технологий, которая использует эту возможность.С использованием стандарта Servlet 2.5 можно применить ограничения по безопасности на любое возможное имя HTTP метода , стандартное или из раcширения, включая WebDAV : LOCK, UNLOCK,COPY, и MOVE.

Не ищите методы с названиями doLock() или doCopy(), когда будете писать WebDAV сервлет. Вы должны будете написать свой метод service(), в котором вызовете метод request.getMethod() и перенаправите обработку на ваш собственный метод. Благодаря этому вам не нужно самостоятельно реализовывать свою систему безопасности при работе с нестандартными HTTP методами.

В стандарте более точно объясняется поведение сервлетов в экстремальных ситуациях, что делает сервлеты более предсказуемыми и переносимыми.

Проблема при генерации ответа сервера.

Первое уточнение является банальным и, но очень интересными, так как является примером того, какие могут существовать побочные эффекты. Servlet 2.4 стандарт говорит, что ответ сервера должен быть отправлен клиенту в определённых ситуациях, включая «Когда указано количество информации методом setContentLength() и информация была записана в выходной поток клиенту». Это работает нормально, пока вы не напишите вот такой код:

response.setHeader("Host", "localhost");
response.setHeader("Pragma", "no-cache");
response.setHeader("Content-Length", "0");
response.setHeader("Location", "http://www.apache.org"); 

Сервлет технически должен игнорировать заголовок «Location», так как было указано значение ноль. Вся последующая информация должна быть отброшена. Servlet API 2.5 добавляет уточнение, что количество информации должно быть больше, чем ноль.

Проблемы с кодировкой.

Согласно стандарту Servlet 2.4 перед вызовом request.getReader() необходимо сначала задать кодировку методом request.setCharacterEncoding(). Однако ничего не говорится, что случиться если вызвать request.setCharacterEncoding() после вызова request.getReader(). Для переносимости, теперь задание кодировки является необязательным.

Заключение.

В новой версии Servlet API 2,5 было добавлено кроме аннотаций небольшие изменения в написание дескриптора приложения web.xml, которые позволяют писать более компактные дескрипторы. Большое влияние оказало появление аннотаций. Важно отметить, что сервлеты сами по себе не определяют новые типы аннотаций и контейнеры сервлетов не обязаны их поддерживать. Но если вы работаете с контейнерами, которые основываются на J2EE 5, то можно использовать практически все виды аннотаций, которые определены в других стандартах, таких как EJB 3.0 и JAX-WS 2.0.

----------
Оригинальный текст статьи: New features added to Servlet 2.5

Если Вам понравилась статья, проголосуйте за нее

Голосов: 8  loading...
globus   c0nst   indegro   asdfghjkl   admin   dreamx_max   oleger   dbtoken