Читать «Java 7 (Наиболее полное руководство)» онлайн - страница 423

Ильдар Шаукатович Хабибуллин

Обращение к другим ресурсам

В некоторых случаях недостаточно вставить в сервлет фильтр или даже цепочку фильтров, а надо обратиться к другому сервлету, странице JSP, документу HTML, XML или иному ресурсу. Если требуемый ресурс находится в том же контексте, что и сервлет, который его вызывает, то для получения ресурса следует обратиться к методу

public RequestDispatcher getRequestDispatcher(String path);

описанному в интерфейсе ServletRequest. Здесь path — это путь к ресурсу относительно контекста. Например:

RequestDispatcher rd = req.getRequestDispatcher("CourseServlet");

Если же ресурс находится в другом контексте, то нужно сначала получить контекст методом

public ServletContext getContext(String uripath);

интерфейса ServletContext, а потом воспользоваться методом

public RequestDispatcher getRequestDispatcher(String path);

интерфейса ServletContext. Здесь путь path должен быть абсолютным, т. е. начинаться с наклонной черты /. Например:

RequestDispatcher rd = conf.getServletContext(). getContext("/product").

getRequestDispatcher("/product/servlet/CourseServlet");

Если требуемый ресурс — сервлет, помещенный в контекст под своим именем, то для его получения можно обратиться к методу

public RequestDispatcher getNamedDispatcher(String name);

интерфейса ServletContext.

Все три метода возвращают null, если ресурс недоступен или сервер не реализует интерфейс RequestDispatcher.

Как видно из описания методов, к ресурсу можно обратиться только через объект типа RequestDispatcher. Этот объект предлагает два метода обращения к ресурсу.

Первый метод,

public void forward(ServletRequest req, ServletResponse resp);

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

if (rd != null) rd.forward(req, resp);

else resp.sendError(HttpServletResponse.SC NO CONTENT);

Вызывающий сервлет не должен выполнять какую-либо отправку клиенту до обращения к методу forward ( ), иначе будет выброшено исключение класса IllegalStateException.

Если же вызывающий сервлет уже что-то отправлял клиенту, то следует обратиться ко второму методу,

public void include(ServletRequest req, ServletResponse resp);

Этот метод вызывает ресурс, который на основании объекта req может изменить тело объекта resp. Но вызванный ресурс не может изменить заголовки и код ответа объекта resp. Это естественное ограничение, поскольку вызывающий сервлет мог уже отправить заголовки клиенту. Попытка вызванного ресурса изменить заголовок будет просто проигнорирована контейнером. Можно сказать, что метод include () выполняет такую же работу, как вставки на стороне сервера SSI (Server Side Include).