Ръководството за Scala за разработчици на Java Scala и сървлети
Работа със сървлети в Scala
Серия съдържание:
Това съдържание е част # от поредица # статии: Ръководството за Scala за Java разработчици
Това съдържание е част от поредицата: Ръководство за Scala за Java разработчици
Очаквайте нови статии от тази серия.
Няма съмнение, че Scala е интересен език, много подходящ за демонстриране на атрактивни иновативни идеи в теорията на езика за програмиране. Това обаче не е достатъчно, за да се приложи на практика. За да направите това, е необходимо да демонстрирате приложимостта на Scala към проблеми от реалния живот, пред които са изправени разработчиците на софтуер.
Преглед на сервлет технологията
Както си спомняте, сервлет технологията се основава на клиент-сървър модел на взаимодействие чрез сокети по HTTP протокола (обикновено през порт 80). Клиентът може да бъде всеки потребителски агент (вижте дефиницията на "User-Agent" в HTTP спецификацията), а сървърът може да бъде сервлет контейнер, който отговаря за намирането, зареждането и изпълнението на класови методи, които имплементират интерфейса javax.servlet.Servlet.
Относно този сериал
Тед Нюуърд се гмурка в езика за програмиране Scala и ви води със себе си. В тази нова серия на developerWorks ще научите за какво е целият шум и ще видите някои от лингвистичните възможности на Scala в действие. Кодът на Scala и кодът на Java ще бъдат показани един до друг, ако такова сравнение е важно, но (както скоро ще разберете) много неща в Scala не могат да бъдат пряко свързани с нищо, с което сте запознати в програмирането на Java, но това е красотата на Scala! В крайна сметка, ако кодът на Java може да го направи, защо да се притесняватеучите ли Scala?
На практика Java разработчиците рядко трябва да пишат класове, които директно имплементират този интерфейс. Първоначално се смяташе, че спецификацията на сървлета трябва да предоставя общ API, който може да се използва при работа с протоколи, различни от HTTP, така че беше решено да се раздели пространството от имена на сървлета на следните две части:
- независим от протокол общ пакет (javax.servlet);
- HTTP ориентиран пакет ( javax.servlet.http ).
В резултат на това абстрактният клас javax.servlet.GenericServlet, който реализира основната функционалност на сървлета, беше включен в общия пакет, а дъщерният клас javax.servlet.http.HttpServlet, който реализира функционалност, специфична за HTTP протокола, беше включен в HTTP пакета. По правило този клас се използва като базов клас при създаване на сървлети. Той напълно внедрява интерфейса на Servlet, преобразувайки GET и POST заявките в извиквания съответно на методите doGet и doPut, които трябва да бъдат претоварени в наследствени класове.
Scala и сервлети
Тъй като въведението в сървлетите за всеки започва със създаването на сървлет, който отпечатва низа „Hello, world!“, ние няма да се отклоняваме от тази традиция в Scala. Спомнете си преди години, когато прочетохте първото си ръководство за писане на сървлети, което казваше, че низът "Hello, world!" можете да отпечатате директно към HTML отговора, както е показано в списък 1.
Листинг 1. Пример за прост HTML отговор
В Scala създаването на такъв сървлет е много просто и ще изглежда почти по същия начин като своя аналог в Java (списък 2).
Списък 2. Да живее първия сървлет на Scala!
Обърнете внимание на използването на псевдоними за импортиранекласове. Това се прави, за да се съкрати дължината на имената на типове. В противен случай този клас на Scala е идеално еквивалентен на Java сървлет. Когато компилирате, трябва да посочите файла servlet-api.jar (обикновено се доставя с контейнера на сървлета, например в случая на Tomcat 6.0 се намира в поддиректорията lib). В противен случай компилаторът няма да може да намери типовете, свързани с API на сървлета.
Докато нашият компилиран сървлет е готов за работа. Според спецификацията, той трябва да бъде внедрен в съответната директория на уеб приложението (или като част от .war файл), който включва файл web.xml. Този файл е дескриптор за разполагане и описва какви заявки трябва да обработва този сървлет. В нашия пример това е просто обикновен URL адрес, както е показано в списък 3.
Листинг 3. Файл Web.xml - дескриптор за разполагане
Можете да промените този дескриптор по свое усмотрение, като го адаптирате към нуждите на вашето приложение. В бъдеще няма да обръщаме внимание на това, тъй като тези въпроси нямат нищо общо със Scala.
Листинг 4. Да живее първия сървлет на Scala!
Този пример използва способността на Scala да оценява изрази, съдържащи XML литерали. Това значително опростява създаването на по-сложни сървлети. Например, ако искате да добавите текущата дата към съобщение, можете просто да включите календарния израз в XML, както следва:
Ако този израз изглежда твърде тромав, тогава е възможна алтернативна опция (списък 5).
Листинг 5. Подобрен сървлет, който отпечатва текущия час
Това, което се случва, е, че компилаторът на Scala представя XML съобщението като екземпляр на класа scala.xml.Node, който след това се преобразува в низmind и се предава на метода за печат на обекта Writer, който генерира отговора на сървлета.
Не подценявайте тази функция на Scala - това е гъвкав начин за отделяне на сървлет логиката от представянето на информация и само в рамките на сервлет клас. В този случай синтактичната коректност на съобщението по отношение на XML правилата ще бъде проверена на етапа на компилация на сервлета. Това не може да се постигне с помощта на стандартни Java сървлети или JSP страници. Също така, с извода за тип на Scala, можете да пропуснете информацията за типа на променливите съобщение и currentDate, така че кодът на сървлета да изглежда като написан на динамичен език като Groovy/Grails. За първия пример това не е никак лошо.
Разбира се, сървлетите, които не обработват заявки, не представляват голям интерес.
Scala и параметри на заявката
Функциите на повечето сървлети надхвърлят простото показване на статично съдържание или текущата дата. По правило те получават съдържанието на формата, предадено в тялото на POST заявките като вход, анализират го и извършват съответните действия. Да кажем, че уеб приложението трябва да знае самоличността на потребителя, така че иска името и фамилията на потребителя (списък 6).
Списък 6. Предизвикателство!
Разбира се, тази форма едва ли ще спечели награда като примерен потребителски интерфейс, но върши работата си - предава необходимите данни на сървлета на Scala, който обработва заявките към относителния URL адрес sayMyName. Според спецификацията на сървлета предадените данни ще бъдат представени като колекция от двойки ключ-стойност. Достъпът до параметрите се осъществява чрез извикване на метода HttpServletRequest.getParameter(), който приема като вход името на параметъра, съответстващо на иметоелемент на формата.
Достъпът до параметри от Scala изглежда подобно на начина, по който се прави в Java. Пример е показан в списък 7.
Листинг 7. Решение (първа версия)
Това обаче губи част от предимството на разделянето на логиката и представянето на съобщението, което беше споменато по-рано, тъй като сега трябва изрично да подадете параметрите firstName и lastName към съобщението. Този подход ще изглежда тромав, ако броят на параметрите е повече от три или четири. В допълнение, методът doPost ще трябва да извлече стойността на всеки параметър, преди да го предаде на публикацията - резултатът ще бъде дълъг и скучен код, който може да има грешки.
Едно решение на този проблем е да преместите кода, който извлича параметрите на заявката и извиква метода doPost, в основния клас, както е показано в списък 8.
Листинг 8. Решение (втора версия)
В този пример сървлетът, който показва съобщението, е много по-опростен от своя предшественик. В същото време допълнително предимство е, че асоциативните масиви param и header са неизменни. Обърнете внимание, че param може да бъде деклариран като метод за достъп до обекта на заявката, но в този случай заявката ще трябва да бъде поле на този метод. В контекста на едновременно извикване на сървлет това би било много рисковано решение, тъй като от гледна точка на контейнера на сървлета всички do методи позволяват повторно влизане.
Несъмнено важна функция на уеб приложението е обработката на грешки, които могат да възникнат при обработката на стойностите на формуляра. Тъй като в Scala, както във всеки функционален език, всички конструкции са изрази, е възможно да се създаде съобщение по такъв начин, че да е страница с резултати, акообработката е приключила успешно или, в противен случай, страница за грешка. В този случай функцията за проверка дали непразните низове са предадени като параметри firstName и lastName може да изглежда като в листинг 9.
Листинг 9. Решение (версия три)
Заключение
Въпреки че простата сървлет рамка на Scala, описана в тази статия, не може да се конкурира с богатите уеб рамки, изградени в Java, тя прави две неща:
Това приключва тази част от поредицата, до скоро!