25 августа 2019 года    
Воскресенье | 20:26    
Главная
 Новости
Базы данных
Безопасность PC
Всё о компьютерах
Графика и дизайн
Интернет-технологии
Мобильные устройства
Операционные системы
Программирование
Программы
Связь
Сети
 Документация
Статьи
Самоучители
 Общение
Форум







Разделы / Программирование / Java

Servlet mini-FAQ.



Servlet mini-FAQ


Составитель Alex Chaffee (http://www.stinky.com/alex/)
Перевод Vladislav Kravchenko (http://www.chat.ru/~k_v_v/)

Оригинальная англоязычная версия здесь.

Переведенная версия 1.31 от 1999/06/11 22:36:08


Содержание

Вопросы

  1. Как я могу разрабатывать и использовать сервлеты без установки JDK 1.2?
  2. Какая правильная директория "servlets" или "servlet"?
  3. Почему не работает мой сервлет внутри <SERVLET> тега?
  4. Как я могу использовать оба протокола GET и POST из одного сервлета?
  5. Как полностью выключить сервер?
  6. Мой браузер выдает "the server returned an invalid or unrecognized response" - что случилось?
  7. Что такое - HelloWorld Servlet?
  8. Как я могу получить имя выполняемого скрипта?
  9. Как совместить JSP и SSI #include?
  10. Как я могу гарантировать, что мой сервлет - поточно безопасный?
  11. Как я могу использовать слежение за сессией (Session Tracking)?
  12. Как я могу независимо определить принял ли пользователь мою куку (cookie)?
  13. Как мне интегрировать HTML дизайн в мой сервлет?
  14. Как послать e-mail из сервлета?
  15. Есть здесь какие-либо провайдеры Интернет, которые разместят мои сервлеты у себя?
  16. Какая разница между URL encoding и URL rewriting?
  17. Как может мой апплет обмениваться данными с моим сервлетом?
  18. Как отлаживать сервлет?
  19. Как создавать изображение (GIF, JPEG, etc.) "на лету" при помощи сервлета?
  20. Как загружать файл в мой сервлет?
  21. Как получить доступ к базе данных из сервлета?

Ссылки

  • Домашняя страничка сервлетов
  • Спецификации и Whitepapers
  • FAQи, документация, уроки
  • Статьи
  • Листы рассылок и группы новостей
  • Компании обучающие созданию сервлетов
  • Web сервера поддерживающие сервлеты
  • Движки сервлетов
  • Более другие сервлет-ориентированные продукты
  • Шаблон HTML страницы
  • Классы генерирования HTML
  • Классы обработки изображений
  • Другие сервлеты

1. Как я могу разрабатывать и использовать сервлеты без установки JDK 1.2?

Добавь c:\JavaWebServer1.1\lib\jws.jar к своему CLASSPATH-у.

Замечание: это необходимо лишь для того, чтобы средства разработки типа javac могли находить его. Java веб сервер автоматически включает его библиотечную директорию.

2. Какая правильная директория "servlets" или "servlet"?

3. Почему не работает мой сервлет внутри <SERVLET> тега?

Если Вы используете свой сервлет внутри SSI, вы должны использовать res.getOutputStream() и не должны res.getWriter(). Проверьте файл протокола ошибок сервера для получения дополнительной информации.

4. Как я могу использовать оба протокола GET и POST из одного сервлета?

Самый наипростейший путь это просто поддерживать POST, а когда вам потребуется использовать метод doGet, просто вызывайте ваш метод doPost:

public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException
{	doPost(req, res);   }

Замечание: реализация имплементации метода service() обычно не то, что бы вы хотели сделать. С тех пор http-сервлеты обеспечивают свою собственную имплементацию метода service() который вызывает методы doGet(), doPost(), и т.д.

Lee Crocker [LCrocker@INFORMANT.COM]: "Вероятно очиститель не обнуляет метод service() когда расширяется http-сервлет. Существующий метод просто вызывает doGet(), doPost(), и т.д. как присвоение, так что вы можете обнулить его если вам так нравиться, но зато потом вы можете вызывать идентично не только GET и POST, но так же все другие HTTP-комманды, такие как HEAD, TRACE и OPTIONS. Если вы хотите что бы GET и POST делали один и те же вещи, просто используйте doGet() и doPost() вызовы тех же самых приватных методов которые делают все работу."

5. Как полностью выключить сервер?

Под Windows, нажатие Сontrol-C полностью не выключает сервер. Вы должны использовать административную утилиту и нажать в ней "Shut Down". Или вы можете нажать ctl-alt-del, найти в меню "JREW" и завершить эту задачу.

6. Мой браузер выдает "the server returned an invalid or unrecognized response" - что случилось?

Это вероятно происходит в время возникновения NullPointerException. В JWS 1.1 есть ошибка, в результате которой это исключение корректно не протоколируется.

Решение в помещении вашего метода doPost() внутри блока try и catch NullPointerException.

	res.setContentType("text/html");
	ServletOutputStream out = res.getOutputStream();
	try {
		// что-то делается
		...
	}
	catch (NullPointerException e) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		e.printStackTrace(pw);	
		out.println("<pre>");
		out.print(sw.toString());
		out.println("</pre>");		
	}
и теперь можно увидеть, где именно произошла ошибка.

Если вы увидите "Compiled Code" вместо номеров строк в сообщении исключения , тогда выключите JIT в вашем сервере.

Позже, я начал ловить исключения, просто в case. Я знаю, что это плохой стиль программирования, но что мне было делать?

7. Что такое - HelloWorld Servlet?

public class HelloHttpServlet extends HttpServlet
{
    public void doGet(HttpServletRequest req, HttpServletResponse res)
 	throws IOException, ServletException
    {
 		String name = req.getParameter("name");
 		if (name == null) name = "Joe";
 		res.setContentType("text/plain");
 		ServletOutputStream out = res.getOutputStream();
		out.println("Hello, " + name + "!");
    }
}

8. Как я могу получить имя выполняемого скрипта?

Используйте req.getRequestURI() или req.getServletPath(). Формирователь возвращает путь к скриптам, включая любую дополнительную информацию о пути, включая имя сервлета.
Например:

URL http://www.purpletech.com/servlets/HelloEcho/extra/info?height=100&width=200
getRequestURI /servlets/HelloEcho/extra/info
getServletPath /servlets/HelloEcho
getPathInfo /extra/info
getQueryString height=100&width=200

Это особенно полезно, если ваша форма является само-ссылочная. Это означает, что она генерируется формой, которая вызывает себя же.
Например:

	out.println("<FORM METHOD=POST ACTION=\"" + res.encodeURL(req.getServletPath()) + "\">");
	out.println("<INPUT NAME=value>");
	out.println("<INPUT TYPE=submit>");
	out.println("</FORM>");
(encodeURL добавляет сессионную информацию если это необходимо. Для разъяснений смотри Sun Servlet Tutorial и вопрос 11.
Замечание: наименование этого метода было изменено из "encodeUrl" в "encodeURL" где-то в районе версии 2.1 спецификации сервлетов.)

Замечание: ранние версии Java Web Server и некоторые движки сервлетов имели ошибку, в результате которой getRequestURI мог так же вернуть параметры GET следующие в дополнительном информационном пути.

9. Как совместить JSP и SSI #include?

Если вы просто хотите поместить чистый HTML, используйте директиву #include как обычно внутри вашего .jsp файла.

<!--#include file="data.inc"-->

Однако, если вы хотите заставить сервер выполнять любой JSP код находящийся внутри помещаемого файла, то необходимо схитрить. Ronel Sumibcay [ronel@LIVESOFTWARE.COM] вещает:

Если ваш файл data.inc содержит jsp код, который вы хотите использовать, поступайте так:
<%@ vinclude="data.inc" %>
<!--#include file="data.inc"--> используется для добавления не JSP файлов.

10. Как я могу использовать "слежение за сессией" (Session Tracking)?

Это действительно комплексная задача. Вот несколько направляющих:

  1. Метод init() гарантированно вызывается один раз на представление сервлета, когда он загружается. Вы можете не беспокоиться о безопасности потоков внутри этого метода. Основанием для этого является то, что он вызывается одиночным потоком, а Web сервер ожидает пока существует ваш поток и только после этого начинает пересылать другие потоки в ваш метод service().

  2. Каждый новый клиентский запрос генерирует новый поток. Этот поток вызывает метод service() вашего сервлета, который в свою очередь может вызывать методы doPost(), doGet() и т.д.).

  3. В некоторых обстоятельствах существует только одно представление вашего сервлета и никто не знает, как много клиентских запросов находятся в обработке. Это означает, что в каждый отдельный момент может быть запущенно несколько потоков внутри метода service() вашего единственного сервлета. Следует учесть, что вам необходимо быть осторожным с синхронизированным доступом к разделяемым данным, используйте для этого ключевое свлово synchronized .

  4. Замечание: вам нет необходимости синхронизировать доступ к локальным данным или параметрам. Но вы должны специально синхронизировать метод service()! (или doPost(), doGet() .)

  5. Простейшим решением синхронизации есть путь непременной синхронизации представления сервлета на него самого путем использования "synchronized (this) { ... }". Тем не менее, это может сказаться на критичных местах по производительности. Обычно лучше не синхронизировать объекты данных самих на себя .

  6. Если вы совершенно не хотите связываться с синхронизацией, вы можете объявить что ваш сервлет "implements SingleThreadModel". Этот пустой интерфейс заставляет Web сервер посылать только один запрос от клиента к вашему сервлету в один момент времени.
    Из документации к Java : " Если целевой сервлет сигнализирован с этим интерфейсом, то программист сервлета гарантирован, что не будут выполнятся два конкурирующих потока в методе service этого сервлета. Эта гарантия осуществляется поддержкой пулов представлений сервлетов и диспетчированием . Запрос будет передаваться первому свободному сервлету в пуле. В сущности если сервлет имплементирует этот интерфейс, то сервлет будет потоко-безопасным. "
    Замечание: это не идеальное решение. Производительность может и пострадать (в зависимости от размера пула представлений), да еще возникают затруднения по разделению данных между представлениями в отличии от случая, когда используется единственное представление сервлета.

  7. Для разделения данных между последовательными или конкурирующими запросами, вы должны также использовать представления переменных или статические переменные класса, или использовать слежение за сессией.

  8. Метод destroy() необязательно такой же "чистый" как метод init(). Сервер вызывает уничтожение (destroy), также после того как были завершены все сервисные вызовы, или после истечения определенного количества секунд, смотря, что наступит быстрее. Это означает, что другие потоки могут быть запущены сервисным запросом в тоже самое время когда вызывается ваш метод destroy()! Что бы быть уверенным в синхронизации, необходимо ожидать окончания всех остальных запрсов. Sun's Servlet Tutorial содержит пример как можно это реализовать.

  9. destroy() может не вызывать исключение, но если все же что-то плохое случиться - вызывайте log() с подробным сообщением (типа как исключение ). Смотри пример "закрытие JDBC соединения" в Sun's Tutorial.

11. Как я могу использовать слежение за сессией (Session Tracking)?

Смотрите секцию 2.3 Servlet Essentials tutorial - http://www.novocode.com/doc/servlet-essentials/. Так же смотрите статьи из Java Servlet Programming: http://webreview.com/wr/pub/1999/01/08/bookshelf/index.html.

Вы должны добавлять только те объекты, которые сериализируются на HttpSession. Специально объект JDBC Connection является не сериализируемым , так он не может быть добавленным к сессии (несмотря на пример в Jason Hunter's Java Servlet Programming). Если вы захотите ассоциировать соединение с сессией, тогда сохраните несколько произвольных и уникальных хендлов сессии. Затем используйте их как ключ вашей хеш-таблицы соединений. Убедитесь так же, что если при поиске эта конструкция возвращает не нулевое соединение и это оно и есть, тогда уже можно создавать новое соединение.

Причина тому, то, что сессии могут по прихоти сервера быть отправлены в своп на диск, в режиме сохранения памяти (или память кончилась) или при перезагрузке сервера. Такое поведение сервера может быть исключено установкой конфигурационного параметра в вашем сервере или в движке сервлета (обратитесь к документации).
Из спецификации:

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

12. Как я могу независимо определить принял ли пользователь мою куку (cookie)?

Используйте сервлетную хитрость: перенаправление (redirect). Поместите куку в объект HttpServletResponse, затем совершите "вторую фазу" - вызов через resp.sendRedirect() другого сервлета. Сервлет "вторая фаза" проверит независимо, была ли ему послана кука назад. Если он ее принимает, это означает, что пользователь принял куку в первый раз. А еже ли нет, это означает, что мерзкий юзер не принял куку, или его не менее мерзкий браузер вообще в натуре не воспринимает куки.

Замечание: такая конструкция работоспособна, только если сервлет "вторая фаза" скрыт от пользователя. Если пользователь может переместиться напрямую на второй сервлет, тогда сервлет не сможет сообщить о особенностях свежеприбывшего клиента и о куко-ненавистниках. Это означает, что вы должны посылать редирект из тестовой фазы, что бы быть уверенным, что пользователь не имеет возможности установить закладку на этот тестовый URL.

Alex Chaffee написал специальный сервлет, который демонстрирует эту операцию, он доступен здесь: http://www.purpletech.com/code/CookieDetector.html.

13. Как мне интегрировать HTML дизайн в мой сервлет?

Этот вопрос может быть перефразирован "Как я могу спроектировать рабочий поток, чтобы включить HTML разработчиков и программистов в строительство динамически генерируемого веб сайта с сохранением возможности роста и развития со временем?" Это специальный случай из набора плохо совместимых проблем управления содержимым веб серверов. Настоящая проблема заключается в том, что бы обеспечить доступ HTML разработчикам (людям) к использованию их любимых примочек для редактирования HTML и без необходимости изучать Java, а так же обеспечить возможность управляющим людям (тоже человеки) изменять вид и наполнение сайта по своей прихоти, без возможности доступа и изменения кода доступа к БД внутри сервлета. А так же иметь возможность изменять логику поведения сервлета и доступа к данным без изменения пользовательского интерфейса.

Смотри статью на Servlet Central ( http://www.servletcentral.com/ ) для дальнейшего углубления в эти проблемы.

Далее в неком "списке-подборке" имеется немеряно возможностей для решения этих проблем... Список еще далеко не полон, но он может направить вас по одному из правильных путей.

A. Крутой HTML. Если вы достаточно круты вы можете просто поместить HTML внутрь вывода значений вашего сервлета методами doGet() или doPost(). Pro: легко программировать, легко понимаемо программерами. Con: с трудом понимаемо дизайнерами-разработчиками, когда было совершено изменение, программер ждет пока дизайнер-разработчик закончит свой HTML, после этого новый код должен быть помещен внутрь выводимых значений, затем необходимо убедиться, в том, что новый HTML код выполняет те же функции, что и оригинальный HTML код. Такой метод обычно хорошо применим для сервлетов уровня "Hello world!", и совсем плохо применим для реальных и натуральных (в натуре) веб серверов.

B. Server Side Includes (SSI). Используйте тег <SERVLET> внутри вашего HTML-файла (и заодно переименуйте его в .shtml). HTML дизайнеры могут создавать чудные странички, а ваш сервлет может выводить маленькие порции текста, это позволяет получить "совмещение" веб страницы с сервером. Pro: разделяются пользовательский интерфейс (HTML) и код. Con: У вас есть парочка возможностей работы с SSI: ваш сервлет выводит множество простых частиц текста не содержащих HTML тегов, или ваш сервлет выводит немерянные пакеты текста с внедренным HTML. В первом случае ваш код не может получить преимущество от его знаний о структуре выводимых данных. Например, вы не можете этим способом форматировать вывод HTML таблиц из баз данных. Во втором же случае вы возвращаетесь к накручиванию HTML (см. секцию "Крутой HTML"). Таким образом возвращаясь к затруднениям связанным со сменой внешнего вида ваших страничек.

C. Представительские шаблоны. Это хороший путь для помещения общих навигационных элементов (кнопки, кредиты и т.д.) на всех ваших страничках. Эта технология встроена в Java Web Server, и осуществлена в различных движках сервлетов (не во всех конечно) . Pro: вам не нужно вводить те же самые основные HTML составляющие ваших бесчисленных страничек веб сервера. Con: код вашего сервлета все еще включает крутой HTML, если хочется его сделать более мощным смотри пункт "B" этого ответа.

D. JSP - Java Server Pages. Вы пишите файлы в формате HTML, и внедряете актуальный Java код внутрь HTML. Это похоже на использование JavaScript-а, только код выполняется на сервере и это настоящая Java. Такой подход идентичен реализации Microsoft's ASP. Pro: круто. Вам необходим всего один файл, который осуществляет генерацию пользовательского интерфейса и формирует выполняемый код. При этом вам нет необходимости писать большое количество "println". Con: если вы смастерите что-то интересное, а затем передадите это вашему HTML-дизайнеру, он будет несколько смущен после просмотра перемежающихся Java и HTML кодов. Так что убедитесь, что сложный код помещен в JavaBean-ах, а не в JSP страницах.

Новая версия спецификации JSP имеет кучу возможностей для интеграции с JavaBeans. Это хороший путь для разделения пользовательского интерфейса (JSP) от данных и логики программы (beans).

Halcyon Software имеет продукт называемый Instant ASP, который позволит вам выполнять Microsft IIS ASP (включая код на VBScript, Jscript, Perl, Java и JavaScript) на любом движке сервлета. Так же Live Software имеет CF_Anywhere, который может выполнять Cold Fusion CFML странички. Смотри ссылки для получения более конкретных линков.

E. Написать свой собственный парсер страничек. Если по некоторым причинам вы не счастливы со стандартными механизмами, то вам тогда предстоит написать собственный парсер страничек. Серьезно. На самом деле это не так уж и сложно.

F. HTML библиотека классов объектной модели, например htmlKona, XML. С этими библиотеками классов вы пишите код и строите объектную модель, затем экспортируете объекты в HTML. Такой подход нормально со сложными "наборами" не работает. И забудьте о возможности работы ваших дизайнеров в их HTML редакторах. Однако, такой подход весьма удачен если у вас имеется динамический сайт с частым обновлением HTML, а вы мечтаете его автоматизировать. К несчастью вы все еще должны знать так же еще и HTML, но только для того, что бы понимать и исправлять его вывод. Смотрите секцию ссылки этого мини-FAQ-а для нахождения некоторых классовых библиотек, которые вам помогут.

G. Делать все это самому. Надо разработать систему управления содержимым управляемую СУБД. Подумайте о C|Net. Она имеет множество стандартных компонентов, но база данных - королевская. HTML дизайнеры имеют всего лишь кусочки страничек с которыми они могут работать. Но, в конце концов они просто помещают содержимое в базу данных и сервлет генерирует каждую страницу на запрос динамически. Такого рода системы очень трудны для разработки, но однажды созданная система - отплатит сторицей. Даже если вы имеете дюжину писателей, редакторов, дизайнеров и программеров - все они работают над одним и тем же сайтом над одной и той же базовой разработкой.

Для того, что бы получить короткий список альтернативных шаблонных систем смотри ссылочную часть этого мини-FAQ-а.

14. Как послать e-mail из сервлета?

От: pixel@bitmechanic.com (James Cooper)

GSP и GnuJSP оба поставляются с SMTP классами, которые могут посылать и-мейл не просто, а очень просто. Если вы пишете свой собственный сервлет, вы должны захватить один из многих SMTP имплементаций с www.gamelan.com (ищи здесь SMTP и java). Все они похожи друг на друга - открывают сокет на 25-м порту и кидают туда мейл. Так что вы должны иметь установленный мыльный сервер, который будет принимать почту от вашего сервлета.

Смотри так же:

15. Есть здесь какие-либо провайдеры Интернет, которые разместят мои сервлеты у себя?

Адреналиновой группой поддерживается список провайдеров, которые хостят Java Сервлеты. Список сам здесь http://www.adrenalinegroup.com/jwsisp.html. Кроме этих, имеется еще несколько заявивших, что они могут хостить Java приложения:

Daniel Kehoe kehoe@fortuity.com имел много "очень счастливого опыта " с Silicon Valley Web Hosting http://www.svwh.net .

http://www.servlets.net Еще один провайдер подключившийся к хостингу Java.

Пожалуйста, сообщайте о любом опыте (плохом или хорошем), который вы получили при работе с этими сервисами на faq@purpletech.com.

16. Какая разница между URL encoding и URL rewriting?

URL Encoding это процесс преобразования пользовательского ввода в форму CGI, так, что бы он мог свободно передаться по вычислительной сети. В основном это удаление пробелов и знаков препинания и замена их эскейп последовательностями. URL Decoding это обратный процесс. Для осуществления этих операций вызывайте java.net.URLEncoder.encode() и java.net.URLDecoder.decode() (последний был (окончательно!) добавлен в JDK 1.2, aka Java 2).

Пример: изменение "We're #1!" в "We%27re+%231%21"

URL Rewriting это технология для сохранения информационного состояния пользовательского браузера между переходами между страниц. Это разновидность кук, только информация сохраняется внутри URL-а, как дополнительный параметр. HttpSession API, которая является частью Servlet API, иногда использует URL Rewriting когда механизм работы с куками не доступен.

Пример: изменение <A HREF="nextpage.html"> в
<A HREF="nextpage.html;$sessionid$=DSJFSDKFSLDFEEKOE">

Так же есть возможность у Apache Web Server-а называемая URL Rewriting. Она включается mod_rewrite модулем. Она переписывает урлы внутри сервера, благодаря чему у вас имеется возможность автоматически добавлять завершающий слеш имени директории, или заменять имена старых файлов на новые. Эта возможность не имеет ничего общего с сервлетами. Для дополнительной информации смотри Apache FAQ на http://www.apache.org/docs/misc/FAQ.html#rewrite-more-config.

17. Как может мой апплет обмениваться данными с моим сервлетом?

Сама простота. Вы можете использовать классы java.net.URLConnection и java.net.URL для установления обычного HTTP соединения с веб сервером. Затем сервер переправляет эту информацию сервлету нормальным путем. В основном, апплет претендует быть веб браузером, а сервлет не различает разницы между ними. (Ессно, вы можете написать сервлет, который только и вызывается из вашего апплета, в таком случае он должен понимать разницу.)

Для большей информации вы можете посмотреть Sun Web Server FAQ, вопросы C8 и C9, на http://www.sun.com/software/jwebserver/faq/faq.html#c8 и http://www.sun.com/software/jwebserver/faq/faq.html#c9.

Так же Chad Darby написал статейку с исходным кодом. Они доступны на http://www.j-nine.com/pubs/applet2servlet/index.htm.

18. Как отлаживать сервлет?

Уууу парень, это не простая вещь.

Сперва, вы всегда должны обрабатывать ваши собственные исключения. Не пойманное исключение может пришибить ваш сервлет, а вы не знаете, куда смотреть в файлах протоколов, или если ваш сервлет имеет ошибку, посредством которой он тихонько спархнет на определенное исключение. А вы не знаете где возникает проблема. Смотри вопрос номер 6 в этом мини-FAQ-е для поиска некоторого исходного кода, который делает это.

В следующую очередь вам необходимо либерализировать использование метода log(), и вы должны сохранять так же свои собственные файлы протоколов. И снова: не доверяйте серверу, что бы выполнить правильные вещи. Так же печатайте в лог после каждого запроса, это поможет в отладке потому что вы сможете немедленно видеть вывод вашего сервлета без просмотра лог файлов сервера. (Но тут возникает другая проблема - не все сервлетные движки освобождают буфер вывода их лог файлов после каждого запроса. Так что если вы хотите увидеть распоследние сообщения в лог, придется изучать логи сервера.)

Здесь, ниже, есть некоторый исходный код, который вы можете добавить к любому HttpServlet, который сохраняет файл протокола:

    StringBuffer logBuffer = new StringBuffer();

    public void log(String s) {
        s = new Date().toString() + ": " + s;
        System.err.println(s);
        logBuffer.append(s);
        logBuffer.append("\n");
        super.log(s);
    }
А здесь есть некоторый код, который вы можете добавить к концу ваших методов doGet или doPost которые выводят целый лог после каждого запроса:
    out.println("<HR>\n<H3>Error log this session:</H3>\n<PRE>");
    out.println(logBuffer.toString());
    out.println("</PRE><P>");
Оба сорца должны быть отключены как только вы действительно отладите ваш сервлет, но они действительно полезны во время разработки и отладки.

Вы не должны забывать использовать servletrunner (переименованый "JSDK WebServer" с JSDK версии 2 -- запуская его со скриптом startserver) для отладки вашего сервлета. Это приблуда поставляемая с JSDK, которая в основе своей запускает миниатюрный веб сервер, который в свою очередь запускает ваш сервлет внутри себя. Это значит, что вам нет необходимости останавливать и перезапускать ваш настоящий веб сервер каждый раз, когда вы перекомпилируете ваш сервлет. Кстати, он так же предоставляет несколько боле чистую среду окружения. Так что вы можете быть уверенным, в том, что сервлет действительно соответствует спецификациям до того, как вы попытаетесь запустить его внутри (возможно нестандартного и содержащего ошибки) сервлетного движка.

Некоторые IDE-оболочки поддерживают отладку сервлетов. Symantec Cafe требует довольно таки живучую систему для отладки визуального уровня сервлетов (а так же RMI, CORBA, и EJB объекты). [Если кто либо имеет какой либо опыт работы с Cafe или другими IDE, пожалуйста мыльте faq@purpletech.com.] jRun так же с претензиями на наличие превосходной поддержки файлов протокола, а так же на наличие некоторых средств для отладки .

Eric Gilbertson (eric@bitsource.com) добавляет:

Другой путь для отладки сервлетов заключается в запуске JWS с java_g и затем присоединению к процессу любого дебаггера, который может подключаться к работающему Java процессу по даваемому ключу.
Что бы запустить JWS следуйте этим инструкциям:

java_g.exe -debug -Dserver.name="javawebserver" [extra args...] com.sun.server.ServerProcess
jdb password=[password]

Этим запускается процесс веб сервера и выводиться ключ. Ключ может быть затем использован в jdb для подключения к процессу. Замечание: это запускается только под Web сервером, но не под администратором сервера.

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

19. Как создавать изображение (GIF, JPEG, etc.) "на лету" при помощи сервлета?

Для создания изображения (картинки) или обработка изображения из Java существуют несколько пакетов и классов. Смотри секцию ссылки.

Однажды у вас появилась картинка в вашем сервлете и у вас теперь есть два пути:

  1. Записывать файл на диск и обеспечивать ссылку на него . Убедитесь, что вы пишите его в дерево директорий вашего веб сервера, а не в любое место диска. (Замечание: в некоторых сетапах сервлетных движков сервлетная директория недоступна для веб сервера, а доступна только для сервлетного движка. Это означает, что вы не можете получить к ней доступ через http://URL.) Вы так же можете посылать тег IMG в HTML вывод вашего сервлета , или посылать HTTP редирект для того, чтобы браузер мог загрузить картинку напрямую (в его собственную страницу). (CookieDetector имеет пример посылки через редирект - http://www.purpletech.com/code/CookieDetector.html)
    Pro: картинка может быть закеширована браузером, и последующий запрос не потребует выполнения сервлета еще раз, тем самым снижается загрузка сервера.
    Con: картинки не будут удаляться с вашего диска , так что вам необходимо так же написать скрипт, который периодически очищает директорию с картинками, или удалять их руками. (Или купить большой жесткий диск :-) ).

  2. Выводить картинку напрямую из сервлета. Вы можете сделать это при помощи установки заголовка Content-type в image/gif (для GIF), или image/jpeg (для JPEG). Затем вам необходимо открыть HttpResponse вывод в raw поток, но не как PrintStream, и послать байты напрямую по этому потоку используя метод write().

20. Как загружать файл в мой сервлет?

Из сервлетного фака Thomas-а Moor-а:

Загрузка основанная на формах - требует пары шагов.

Сервер должен поставляться с кодированным типом данных multipart/form. А клиент должен его поддерживать. Большинство современных браузеров это поддерживают, но не гарантировано. Во-вторых (и это обычная мудреная часть) , ваш сервлет должен разбирать двоичные данные и что-то делать с ними (например, записывать их в файл на сервер ).

Бесстрашный программер прочитает RFC 1867 для получения спецификаций, как разбирать эти данные. Менее храбрый может использовать так же имплементацию Jason-а Hunter-а относительно MultipartRequest (доступно с www.servlets.com), или CParseRFC1867 (доступно с www.servletcentral.com).

Замечание: сорсы доступны для обоих примеров, но оба основаны на том, что вам необходимо писать файл на сервер. Для другого применения (например, сохранение файла как бинарного объекта в базе данных) требуются применения адаптации кода.

JavaMail так же имеет MIME-разбирающие программы (смотри секцию ссылок).

Если кто-либо из читателей имеет пример HTML кода который поддерживает загрузку пожалуйста пришлите его faq@purpletech.com.

21. Как получить доступ к базе данных из сервлета?

Начиная с JDK 1.1, Java поступает с пакетом называемым JDBC (Java Database Connectivity). JDBC позволяет вам писать SQL запросы как строки Java, передавая их к СУБД, и получать назад результаты, которые вы можете в последствии обрабатывать . Что бы обучиться как писать JDBC код, просмотрите туториалы на сановском веб узле, и прочитайте документацию Javadoc API для пакета java.sql. Что бы установить JDBC на вашу систему, вам необходимо найти JDBC драйвер для вашей конкретной базы данных и поместить его в ваш classpath. К счастью большинство СУБД в наши дни поставляются со 100% чистым Java драйвером (так же известным как драйвер "Type IV"), включая Oracle, Sybase, Informix и т.д. Просмотрите документацию к СУБД для инструкций по установке.

Простое открытие соединения к БД может занять продолжительное время (вплоть до 10 секунд и даже более), вы вероятно не хотите создавать соединение в вашем методе doGet. Взамен, создайте соединение в методе init() и сохранение его в переменной. Не забудьте закрыть соединение в вашем методе destroy().

Альтернативно вы можете использовать пул соединений, который открывает несколько соединений к БД как одно, затем разделяет их на индивидуальные потоки, если это требуется. Такое решение имеет несколько проблем с методом одного соединения, описанного выше. В основном, этот метод хорошо для создания множественных запросов и транзакций . Хороший и бесплатный пул соединений как имплементация доступен с http://www.javaexchange.com/. Пул соединений так же поставляется с многими популярными серверами приложений, включая BEA WebLogic (раньше Tengah).


Ссылки

Домашние страницы сервлетов

Спецификации и уайтпейперсы (Whitepapers)

ЧАВО, документация, обучение

Статьи

Списки рассылок и новостные телеконференции

Компании обучающие сервлетостроению

Веб сервера поддерживающие работу с сервлетами

Сервлетные движки - Они позволяют выполнять сервлеты на уже существующих веб серверах

  • Live Software - JRun
    http://www.livesoftware.com/
    Поддерживает: Apache, Microsoft IIS and PWS, O'Reilly WebSite, Netscape FastTrack & Enterprise, StarNine WebSTAR, Apple AppleShare IP
  • New Atlanta Communications - ServletExec
    http://www.newatlanta.com/
    Поддерживает: Microsoft Internet Information Server (IIS), Netscape FastTrack & Enterprise servers, Apache (including on Linux) и все основные Mac OS веб сервера
  • Gefion Software - WAICoolRunner
    http://www.gefionsoftware.com/
    Поддерживает: Netscape сервера
  • IBM - WebSphere
    http://www.software.ibm.com/webservers/appserv/
    Поддерживает: Lotus Domino Go Webserver, Apache HTTP Server, Microsoft IIS и Netscape Enterprise Server
    Includes CORBA 2.0 совместимый с объектами брокера запросов и объектного сервера, поддерживает Enterprise Java Beans (EJB)
  • mod_jserv - Apache
    http://java.apache.org/
  • Locomotive - веб сервер приложений основанный на Java и имеющий открытые исходные тексты
    http://www.locomotive.org
    Locomotive построен на Java и обеспечивается интеграцией с Apache через Apache API, Netscape серверами через NSAPI и с IIS серверами через ISAPI. Locomotive на текущий момент поддерживает Oracle, Informix, MySQL, Cloudscape:JDBMS, SQL Server. Locomotive поддерживает Servlet API, имеет динамически загружаемую балансировку и возможности восстановления, а так же "умный темплейтный язык", STEAM.
  • Dynamo Web Application Server от ATG
    http://www.atg.com/

Другие сервлет-ориентированные продукты

  • Java модуль для Apache John-а Carnahan-а (mod_java)
    http://wright.biology.ucla.edu/java-module/
    Открывает новый процесс для каждого запроса сервлета
  • N-Ary Consulting
    http://www.n-ary.com/consultancy/servlets/
    Имеет несколько сервлетов для продажи, так же интересуется сервлетными интерфейсами в новостной конференции comp.lang.java.programmer на http://www.n-ary.com/consultancy/servlets/forum.html
  • Spin - авторский инструмент основанный на JavaBeans который может создавать сервлеты
    http://www.zat.com
  • Live Software Products
    http://www.livesoftware.com/products/
    ServletDebugger - помогает проверять и отлаживать сервлеты
    ServletWizard - визард проектов сервлетов для Symantec's Visual Cafe
    ServletKiller - стресс тест для вашего сайта и приложения
  • WebApp Framework
    http://www.webapp.de

Шаблоны систем HTML страниц

Здесь короткий при короткий список альтернативных шаблонов систем HTML страниц (вначале созданный Dan Stiefel dan@entago.com):

Классы генерации HTML

Другие сервлеты

  • Servlet Central архив
    http://www.servletcentral.com/common/archivelist.dchtml
  • Live Software Servlets
    http://www.livesoftware.com/products/
    CF_Anywhere - запускает страницы Cold Fusion CFML прямо в сервлете
    Servlet Pack One - сервлеты для отсылки мейла, поддерживаются файл-основанные счетчики, просмотр пользовательского доменного имени на основании его IP адреса, вывод информации о времени и дате, осуществляет запросы к СУБД, и загрузку файлов
    NewsServlet - осуществляет чтение и помещение сообщений при раде со стандартными NNTP новостными серверами
  • Tim McCune's Servlet Toolbox
    http://www.lib.ksu.edu/tim/servlets/
    WinCGI Servlet, PageCounter Servlet, WeatherBox Servlet, AtRandom Servlet
  • JavaExchange - брокер соединений с базами данных
    http://www.javaexchange.com/
  • Servc Servlet Authoring Tool
    http://www.geocities.com/SiliconValley/Pines/3185/
  • Mort Bay Tracker: WWW сервлет для слежения за передачами и дефектами
    http://www.mortbay.com/software/Tracker.html
  • Cookie Detector от Alex Chaffee
    http://www.purpletech.com/code/CookieDetector.html
    Пытается скинуть пользователю куку в его браузер и определить в конце концов его браузер принял ее или нет.
  • InstantOnline от Gefion - доступ к БД, посылка email, загрузка файлов и все такое
    http://www.gefionsoftware.com/InstantOnline/
    Сервлетная оболочка позволяющая разрабатывать динамический веб без программирования. Компоненты для доступа к базам данных, email, загрузка файлов, получение данных сессий и другое.
  • Aaron Porter написал GifServlet, который может изменять размер и цвет GIF-ов
    http://www.metawerx.com.au/aaron.porter

Классы обработки изображений

Если вы знаете любые другие графические библиотеки Java, в частности те, которые могут обрабатывать JPEG, пожалуйста, дайте нам знать о них на faq@purpletech.com.

 Servlet mini-FAQ.
Лента новостей


2006 (c) Copyright Hardline.ru