|
||||||||||||
|
||||||||||||
|
|||||||||
МЕНЮ
|
БОЛЬШАЯ ЛЕНИНГРАДСКАЯ БИБЛИОТЕКА - РЕФЕРАТЫ - Огляд технології сервлетівОгляд технології сервлетів3 Міністерство освіти і науки України Чернівецький національний університет імені Юрія Федьковича Факультет комп'ютерних наук Кафедра комп'ютерних систем та мереж ОГЛЯД ТЕХНОЛОГІЇ СЕРВЛЕТІВ 482.362.70915-05 35 51-3 (курсова робота) 2007 Анотація Даний розділ містить основні відомості про історію розвитку мови JAVA, її основні технології та їх застосування для роботи з SQL-серверами. Розділ містить також опис основних особливостей мови, основних елементів мови пов'язаних побудовою та відображенням графіків, огляду та принципів функціонування сервлетів та JSP-сторінок, а також опис елементів для встановлення зв'язку та отримання даних з сервера баз даних. Опис мови займає 22 сторінок друкованого тексту, 3 рисунки. Зміст Вступ 1. Загальний огляд технологій Java 1.1 Огляд технології сервлетів 1.2 Технологія JSP 1.3 Огляд багатопоточного програмування в Java 2. Особливості взаємодії Java з SQL-серверами 2.1 Завантаження та реєстрація JDBC-драйвера 2.2 Формування JDBC-URL-рядка 2.3 Отримання екземпляра об'єкта класу Connection 2.4 Формування SQL запиту 2.5 Виконання і обробка SQL-запиту 2.6 Основні проблеми тестування баз даних 3. Робота з графікою в Java 3.1 Зміна розміру графічних об'єктів 3.2 Робота з кольорами в Java 3.3 Огляд компонентів Frame та Panel. Список літератури Вступ На сучасному етапі розвитку глобальних мереж в світі розвинулися і поширилося велика кількість мов програмування, які призначені для різних областей людської діяльності. До найбільш розповсюджених мов програмування Web-сторінок належать Java, мова гіпертекстової розмітки HTML, PHP, Perl, JavaScript та деякі інші. Визначальним моментом при виборі мови програмування додатків в більшості випадків являється досвід у використанні тієї чи іншої мови. Однак згідно технічного завдання нам необхідно використати технологію сервлетів і JSP, які представлені мовою програмування JAVA. 1. Загальний огляд технологій JavaДо найбільш потужних технологій Java, які дозволили піднятися їй з самих низів до таких вершин належать:1. Технологія платформенної незалежності.2. Технологія забезпечення захисту користувачів від потенційно небезпечних дії.3. Технологія аплетів.4. Технологія сервлетів.5. Технологія JSP-сторінок.6. Технологія багатопоточності.7. Технологія роботи з мережами.8. Технологія JavaBeans та інші.Технологія платформенної незалежності в Java будується на основі використання байт-коду, тобто проміжного представлення програм, яке не залежить від архітектури комп'ютера чи операційної системи, на які виконуватимуться додатки. Це проміжне представлення перетворюється у виконуваний код на комп'ютері користувача за рахунок віртуальної машини Java, яка на сьогоднішній день включається у всі операційні системи виробниками цих ОС. При цьому розробники нових ОС широко використовують самі технології Java для побудови своїх систем та надання їм більшої надійності.Технологія забезпечення захисту від потенційно небезпечних дій здійснюється на основі аналізу віртуальною машиною Java виконуваного коду, та дозволу чи забороні виконання цього коду. Java обмежує вас у декількох ключових областях, і в такий спосіб сприяє виявленню помилок на ранніх стадіях розробки програми. У той же час у ній відсутні багато джерел помилок, властивих іншим мовам програмування. Більшість використовуваних сьогодні програм відмовляють в одній із двох ситуацій: при виділенні пам'яті, або при виникненні виняткових ситуацій. У традиційних середовищах програмування при розподілі пам'яті програмісту приходиться самому стежити за усією використовуваною в програмі пам'яттю, не забуваючи звільняти її в міру того, коли вона стає лишньою. Найчастіше програмісти забувають звільняти захоплену ними пам'ять або, що ще гірше, звільняють ту пам'ять, що усе ще використовується якою-небудь частиною програми. Виняткові ситуації в традиційних середовищах програмування часто виникають у таких, наприклад, випадках, як ділення на нуль або спроба відкрити неіснуючий файл, і їх приходиться обробляти за допомогою складних конструкцій. Java фактично знімає обидві ці проблеми, використовуючи збирач сміття для звільнення незайнятої пам'яті й убудовані об'єктно-орієнтовані засоби для обробки виняткових ситуацій. Однією з найбільших переваг мови Java - можливість створення аплетів, маленьких програм, які працюють всередині WEB-броузера. Проте, на аплети накладені певні обмеження в зв'язку з тим, що вони виконуються на комп'ютері користувача.Обмеження аплету:1. Аплет не має доступу до жорсткого диску. Проте для них існує система цифрових підписів, за допомогою якої користувач може визначати чи дані аплети отримані з надійних джерел, а отже може зняти більшість обмежень.2. Аплетам необхідно певний час, щоб загрузитися з Інтернету. Для зменшення цього часу всі дані, які необхідно аплету для роботи, як правило включають в jar-архів, що дозволяє швидше загрузити аплет.Переваги мови Java:1. Для аплетів немає необхідності встановлювати їх як інші програми. Цим можна скористатися, коли необхідно постійно загружати обновлені версії програм.2. Немає необхідності хвилюватись, що загружений аплет виконає потенційно небезпечні дії. Основні дії, які можуть привести до втрати важливої інформації, пошкодження чи зміна вмісту файлів для аплетів є заборонені.1.1 Огляд технології сервлетівСервлети - це Java-програми, написані спеціальним чином (згідно специфікації), які виконуються на web-сервері. Їх запуск здійснюється з web-броузера за допомогою протоколу HTTP через web-сервер. Сервлети можуть виконувати ті ж самі функції, що й CGI-сценарії, але замість мов Perl, Python або C++ використовується мова Java, що дає багато переваг над CGI. Ці переваги полягають у зручності написання, підтримки та зміни коду, а також у самому способі виконання Java-програм на сервері.Сервлети - це програми, які виконуються на WEB-сервері, і діють у якості посередника між запитом, який поступає від Web-броузера або іншого клієнта HTTP, і базами даних або додатками на сервері. Вони можуть виконувати наступні дії: зчитувати дані, передані користувачем; проглядати всю інформацію про запит, яка вбудована в HTTP-запит; генерувати результати; встановлювати відповідні параметри HTTP-відповіді; повертати документ клієнту.Рис. 1.1 Загальна структура роботи технології сер влетівПри виконанні багатьох запитів клієнтам можуть повертатися попередньо створені (статичні) документи. Такі запити слід обробляти без використання сервлетів. Однак у багатьох випадках статичний результат не є достатнім, а сторінку слід генерувати при кожному запиті. Наприклад:1. сторінки, основані на даних, представлених користувачем;2. сторінки будуються на основі часто змінюваних даних;3. сторінки використовують інформацію корпоративних баз даних або інших джерел на боці сервера.Особливістю технології сервлетів являється те, що код HTML-сторінки вбудовується в код Java, і даний додаток працюючи на стороні сервера не вимагає від користувачів жодних додаткових витрат ресурсів. Він повністю виконується засобами Web-сервера, а результати своєї роботи у вигляді HTML-сторінки відсилає клієнту. Перевагою появи такого підходу до вирішення проблеми обмеженості ресурсів користувачів явилось і те, що HTML був визначений як основний стандарт передачі інформації в WWW.1.2 Технологія JSPНевдовзі після появи технології сервлетів розробники стикнулися з такою проблемою: для динамічної генерації HTML-сторінок за допомогою сервлета HTML-код доводиться розміщувати в самому сервлеті. При цьому HTML-код сторінки змішується з Java-кодом (при цьому логіка роботи програми змішується із зовнішнім виглядом web-сторінки), що ускладнює роботу як програміста, так і веб-дизайнера.Для вирішення цієї проблеми була розроблена технологія JavaServer Pages (JSP). Вона дозволяє розміщувати Java-код всередині HTML-коду web-сторінки. При першому зверненні до jsp-сторінки її код автоматично перетворюється в сервлет і компілюється. Після цього при наступних зверненнях web-сервер викликає не jsp-сторінку, а відкомпільований сервлет. При внесенні змін в jsp-сторінку web-сервер виявляє, що сторінка змінилась, і знову оновлює відповідний сервлет.На появу такої технології вплинуло також масовий вихід різноманітних редакторів, які спрощували написання статичних HTML-сторінок. Стало достатньо просто розробляти красиві за інтерфейсом та динамічні веб-додатки. Користувачі за допомогою будь-якого редактора створювали красиву HTML-сторінку, а потім поміщували всередині неї Java-код для забезпечення більшої інтерактивності сторінки. Схема функціонування Web-сервера з сервлетами та JSP-сторінками зображена на Рис.1.2.Рис.1.2. Java web - сервер додатків1.3 Огляд багатопоточного програмування в JavaБагатопоточна програма - це програма, в якій присутні декілька незалежних потоків команд. В різних мовах програмування спробували реалізувати багатопоточність до появи Java. Однак, хоча ці спроби і увінчалися успіхом, цього не вистачило для широкого поширення цих мов програмування. Пояснюється це тим, що способи реалізації цієї багатопоточності були занадто складними, або переобтяжені великою кількістю інформації, яку повинен був зробити програміст для правильної її реалізації.В мові Java реалізувати багатопоточність було достатньо легко. Для цього користувачу не потрібно було детальне знання роботи операційних систем чи реалізації достатньо складних алгоритмів. В Java навіть недостатньо досвідчений користувач міг створити багатопоточну програму, що дозволяло максимально використовувати ресурси комп'ютера. Модель багатопоточності та засоби роботи з потоками тут реалізована найбільш повно. Для реалізації багатопоточності в Java передбачено два способи:1. Використання успадкування від класу Thread.2. Використання інтерфейсу Runnable.Перший спосіб, коли програма запускається, в ній вже існує один потік, який називається основним. Як тільки він завершується, то завершуються всі підпотоки. Тому необхідно слідкувати за тим, щоб даний потік завершувався останнім. Отримати вказівник на даний потік можна з допомогою наступного коду:Thread t = Thread.currentThread(); Цей спосіб - використання реалізації інтерфейсу Runnable. Для цього необхідно визначити заголовок класу наступним чином: class NewThread implements Runnable Другий спосіб - використання наслідування від класу Thread. Переробимо програму для цього способу. При цьому необхідно змінити тільки заголовок класу NewThread. class NewThread extends Thread Клас Thread та інтерфейс Runnable містять метод run(), який програміст повинен перевизначити. Всередині даного методу необхідно розміщувати оператори, які будуть виконуватись в новому потоці. Оскільки головний потік повинен завершуватись останнім, то використовують метод join(), який очікує поки завершиться потік для якого даний метод викликаний. 2. Особливості взаємодії Java з SQL-серверами Java надає доступ до баз даних за допомогою інтерфейсу JDBC. Даний інтерфейс за своєю суттю нагадує ODBC, більш того, в Win32 є шлюз JDBC-ODBC . Пакет JDBC призначений для роботи з різноманітними диспетчерами СКБД від різних розробників. Для підключення до бази даних середовище виконання Java повинне завантажити відповідний драйвер вказаної бази даних. Завантаження і вивантаження таких драйверів здійснюється за допомогою класу DriverManager. Рис.2.1. Схема підключення додатків JAVA до SQL сервера На рис.2.1. показана схема підключення Java-програми до бази даних. Клас DriverManager має структуру даних, яка містить як самі драйвери у вигляді об'єктів Driver, так і інформацію про них. Отже розглянемо кроки які необхідно зробити для того, щоб обробити SQL запит: 1. Завантаження та реєстрація JDBC-драйвер (на етапі ініціалізації додатку). 2. Сформувати JDBC-URL-рядок для отримання з'єднання з базою. 3. Одержати екземпляр об'єкта класу Connection. 4. Сформувати SQL запит. 5. Виконання і обробка SQL-запиту. 6. Закрити одержані з'єднання (ResultSet, Statament, Connection). Тепер розглянемо ці кроки детальніше на приклад роботи з MySQL. 2.1 Завантаження та реєстрація JDBC-драйвераДрайвери JDBC звичайно створюються постачальниками СКБД. Їх робота полягає в обробці JDBC-підключень і команд, що поступають від Java-додатку, і в генерації машинно-залежних викликів по відношенню до бази даних. Далеко не всі постачальники СКБД пропонують драйвери JDBC, але як правило ними завжди поставляються драйвера ODBC (Open Database Connectivity), які задовольняють стандарту Microsoft. При роботі з СКБД на платформі Windows постачальник використовуваної СКБД майже завжди пропонує власний драйвер JDBC. Тому дані з баз даних можна легко отримати в Office проблем з підключенням Java-додатку до бази даних в середовищі Windows звичайно не виникає, необхідно тільки завантажити відповідний JDBC-драйвер.Завантаження драйвера може здійснюватися як з програми, так і з командного рядка. Для завантаження драйвера JDBC з командного рядка необхідно ввести наступну команду: Java -Djdbc.drivers=sun.odbc.JdbcOdbcDriver MyApplicationПри реєстрації драйвера-моста JDBC-ODBC з програми у Вас повинні бути:- JAR-файл з драйвером повинен бути підключений в CLASSPATH. - Ви повинні знати назву класу-драйвера, який ви збираєтеся підключати (цю інформацію шукайте на сайті виробника драйверів). JAR Ви підключили, тепер необхідно зареєструвати драйвер:String driver=" sun.odbc.JdbcOdbcDriver";try{Class.forName(driver).newInstance();DriverManager.registerDriver( (Driver)Class.forName(driver).newInstance());} catch(Exception e) { System.out.println("Exception while register driver: "+e); }2.2 Формування JDBC-URL-рядкаУ найзагальнішому випадку цей рядок має вигляд:jdbc:id_бази:параметриУ разі MySQL вона має вигляд:jdbc:mysql://хост/база?user=користувачНаприклад:jdbc:mysql://127.0.0.1/GENERAL?user=rootНеобхідний відступ з приводу "особливостей" роботи драйверів mysql. Для підключення необхідна передача login/password в JDBC драйвер, проте JDBC-драйвера MySQL, які зустрічалися під час виконання дипломного проекту сприймали тільки login, прописаний в рядку JDBC-URL і ніякими іншими способами примусити сприйняти драйвер необхідні параметри не вийшло.2.3 Отримання екземпляра об'єкта класу ConnectionДля отримання Connection необхідно викликати DriverManager. getConnection() і передати у всередину login/password/jdbc-url:String url="jdbc:mysql://127.0.0.1/GENERAL?user=root";String user="";String password="";Connection c=null;try{c=DriverManager.getConnection(url,user,password);} catch(SQLException e){ System.out.println("Exception getting connection: "+e); }2.4 Формування SQL запитуНа даному етапі необхідно сформувати звичайну SQL команду, наприклад: String str="select * from Mytable";String str="insert into Mytable (name,cnt) values ('"+name+"',"+cnt+"')";2.5 Виконання і обробка SQL-запитуДля виконання запиту необхідно отримати об'єкт Statement у екземпляра об'єкта класу Connection, і викликати один з його методів, залежно від типу запиту:public int executeUpdate(String sql) throws SQLExceptionЗастосовується для SQL команд INSERT, UPDATE або DELETE. Повертає кількість рядків над якими виконалася операція.public ResultSet executeQuery(String sql) throws SQLExceptionЗастосовується для SQL команди SELECT. Повертає ResultSet з якого можна витягнути інформація про шапку таблиці (ResultSetMetaData) і самі значення. Як це робиться буде показаний нижче в прикладі.public boolean execute(String sql) throws SQLExceptionДаний метод повертає true/false - виконався/не виконався запит. Застосовується в тих випадках коли SQL запит повертає декілька ResultSet'ів. Для їх отримання використовуйте getMoreResults().Закриття одержаних з'єднань (ResultSet, Statament, Connection)У кожного з вказаних об'єктів є методclose();При необхідності виконання схожих SQL-операторів декілька разів використання підготовлених операторів виявляється більш ефективнішим, ніж виконання кожного разу одного і того ж оператора із різними значеннями параметрів. Створюється параметризований оператор стандартного виду, який надсилається БД на компіляцію перед тим, як він використовуватиметься. Для позначення місць у запиті, де підставлятимуться реальні значення параметрів, використовують знаки питання. Кожного разу при використанні підготовлених операторів достатньо замінити один з параметрів за допомогою методів setXxx. Потім викликається метод executeQuery або executeUpdate.2.6 Основні проблеми тестування баз данихПри тестуванні баз даних можна виконувати надзвичайно велику кількість можливих тестів. Однак у нашій роботі ми розглянемо лише найбільш основні види тестів, які цікавлять більшість користувачів.При виході реляційних баз даних на ринок корпоративних пропозицій, до їх продуктивності стали пред'являти підвищені вимоги. Користувачі хотіли бути впевнені в тому, що вибрана ними СКБД не почне “задихатися” при збільшенні вимог додатків. Це занепокоєння користувачів, яка доповнювалась також зацікавленістю виробниками СКБД призвела до “холодної війни” за показники продуктивності між виробниками. Одних цікавила максимальна абсолютна продуктивність СКБД, інших - співвідношення ціна/продуктивність і відповідна економія коштів. У всіх випадках компанії рекламували контрольні тести, які доказували перевагу їх продукту над іншими, і робилися спроби дискредитувати контрольні тести інших виробників.Перш за все контрольні тести розроблялися самими виробниками. Однак виробники самі були зацікавлені в найкращих результатах цих тестів, що приводило до спотворення реально існуючої інформації про продуктивності роботи їх продуктів. Пізніше з'явились два незалежних теста “Дебет/кредит” та ТР1. Перший з них виконував прості бухгалтерські транзакції, а другий - вимірював продуктивність OLTP-систем. Однак ці тести були достатньо простими, і тому виробникам не складало великих труднощів маніпулювати результатами отриманих тестів, щоб представити свої продукти в найкращому світлі. Як правило маніпулювання даними тестами полягало у використанні більш продуктивніших та більш сучасних комп'ютерах, специфічно представлених даних, якими наповнювалися таблиці та інші.Спроби зробити результати тестів більш-менш стабільними та достовірними закінчились об'єднанням декількох виробників і консультантів по базах даних в організацію Transaction Processing Council, яка зайнялась створенням стандартного тесту для реляційних баз даних. Ця організація розробила серію офіційних контрольних тестів для реляційних баз даних, відомих як ТРС-А, ТРС-В, ТРС-С. Ця організація взяла на себе функцію збору, зберігання та публікації результатів контрольних тестів для різних СКБД, а також роботу по верифікації результатів тестів, про які інформують виробники СКБД.Однак, ці тести як правило втрачаються за горою рекламних кампаній нових продуктів, і кінцеві користувачі, як правило, не мають реальних даних про продуктивність тієї чи іншої СКБД в специфічних умовах (адже організація ТРС не може фізично протестувати всі можливі варіанти поєднання СКБД та різних видів програмного забезпечення). Тому в цій роботі ми спробуємо навести результати тестування певних функцій найбільш поширених СКБД при роботі з технологіями сервлетів та JSP. Ще однією причиною виконання роботи являється те, що компанія ТРС випустила тільки beta версію свого тесту ТРС-W, який орієнтований на оцінку продуктивності тестуючої СКБД у поєднанні з Internet-додатками, які працюють з базами даних через WWW [3].3. Робота з графікою в JavaВ Java аплети можуть малюватися на екрані, використовуючи метод paint(). Оскільки сам аплет явно ніколи не викликає метод repaint(), то це необхідно здійснювати програмісту вручну, або підключити аплет до слухача подій, який забезпечить перемалювання аплету при настанні визначеної події. У аплета є три різних способи, які можна використати для малювання: 1. repaint(перемалювання) викликається в будь-який час, коли аплет повинен заново вивести своє зображення на екран. 2. update (обновлення) викликається методом repaint(), указуючи, що настав момент для обновлення зображення; стандартний метод update () призводить очистку зображення і викликає метод paint().3. paint(малювання) призводить вивід зображення аплета у відведеному місці на екрані; методу paint() в якості параметра передається об'єкт Graphics, який аплет може використовувати для малювання різних фігур і зображень. Пакет AWT підтримує широкий вибір графічних методів. Всі графічні елементи пов'язані з вікнами. Це може бути головне або дочірнє вікно атлета чи окреме вікно додатку [4]. В Java використовується звичайна система координат (х, у), де х - кількість екранних точок від лівої границі екрану, у - кількість від верхньої границі екрану. Лівому верхньому куту відповідають координати (0,0). Така система координат використовується практично у всіх графічних системах. Координати задаються в пікселях. Вся інформація виводиться на екран з допомогою графічного контексту (graphics context), який інкапсульований в класі Graphics і отримується двома способами:1. Передається в аплет під час виклику одного з багаточисельних методів таких як paint() або update().2. Повертається методом getGraphics().В класі Graphics визначено деяку множину графічних функцій. Кожний графічний об'єкт може бути представлений як незаповнений, або заповнений в вигляді контура. Об'єкти відображаються і заповняються вибраним в даний момент кольором, а отже по замовчуванню - чорним. Якщо графічний об'єкт перевершує розмір вікна, то він автоматично обрізається. Клас Graphics забезпечує засіб для малювання наступних об'єктів: 1. Прямих.2. Прямокутників і багатокутників.3. Еліпсів і кругів.4. Дуг.5. Графічних зображень.6. Тексту (різними шрифтами) .3.1 Зміна розміру графічних об'єктівЧасто приходиться задавати розмір графічних об'єктів таким чином, щоб він відповідав розміру вікна, в якому буде відображатися даний об'єкт. Для цього потрібно спочатку викликати метод size() вікна. Його синтаксис має вигляд Dimension size(). Даний метод повертає розмір вікна, інкапсульовані в об'єкті Dіmension. Знаючи даний розмір вікна, можна відповідним образом масштабувати графічний об'єкт [3].Така технологія використовується в аплеті, яка спочатку представляє собою квадрат 200*200 пікселів, а потім може збільшуватися чи зменшуватися в результаті виникнення подій. Для вказання аплету, що йому необхідно змінити свій розмір, існує метод resize(Dimension size). Він призначений для встановлення нового розміру вікна аплету, і автоматично викликає метод repaint().3.2 Робота з кольорами в JavaJava підтримує роботу з кольором в режимі, не зважаючи від пристрою. Система кольорів пакета AWT дозволяє задавати будь-який бажаючий колір. Для цього вона знаходить найбільш відповідний колір з числа можливих для дисплея, на якому в даний момент працює програма чи аплет. Модель кольору HSB (Hue - відтінок, Saturation - насиченість, Brightness - яскравість ) являється альтернативною моделлю RGB. Відтінок, насиченість і яскравість задаються числами в діапазоні від 0 до 1. 1 - відповідає світлому кольору, 0 - чорному. За допомогою методів GetRed, GetGreen, GetBlue можна отримати червоні, зелені і сині кольори. Синтаксис цих методів наступний:int getRed()int getGreen()int getBlue()Кожний з цих методів повертає RGB - складову кольору об'єкта Color в молодших восьми розрядах цілого числа.3.2 Огляд компонентів Frame та PanelКлас Frame інкапсулює елемент, який утримує рядок заголовку, меню, границі і механізм зміни розміру. Цей клас являється підкласом Window. Якщо об'єкт Frame створюється з атлета, то в ньому буде міститися попереджуюче повідомлення про те, що дане вікно створене аплетом. Це повідомлення попереджає користувачів про те, що вікно, яке вони бачать на екрані було отримано з допомогою аплета, а не програми, яка працює на їх комп'ютері.Клас Panel є конкретним підкласом абстрактного підкласу Container. Він не містить нових методів, а лише реалізує методи класу Container. Panel можна представити собі як рекурсивний компонент екрану. Клас Panel являється суперкласом для класу Applet. Якщо вивід призначається аплету, то виводиться інформація, яка відображається на поверхні об'єкта Panel. Отже, панель - це вікно, яке не має рядка заголовка, меню і границі. Ось тому, при перегляді аплета з допомогою браузера ці елементи не видно. При запуску аплета з допомогою програми перегляду на екрані видно границі і заголовок, але вони відносяться лише до програми перегляду аплета. До об'єкту Panel можна добавляти й інші компоненти з допомогою методу add(), після чого можна вручну змінювати їх положення та розмір на екрані з допомогою методів move(), resize() чи reshape() [3].Список літературиХолл М. Сервлеты и JavaServer Pages. Библиотека програмиста. - СПб.:Питер, 2001. - 496. JavaServer Pages™ Specification version 2.0. - Sun Microsystems, 2003. - 765. Грофф Дж., Вайнберг П. SQL: Полное руководство: Пер.с англ. -К BHV, 2001. - 816. Вебер Д. Технология Java™ в подлиннике: Пер. с англ. - СПб.: BHV, 2000. - 1104. Эккель Б. Философия Java. Библиотека програмиста. - СПб: Питер, 2001. - 880. |
РЕКЛАМА
|
|||||||||||||||||
|
БОЛЬШАЯ ЛЕНИНГРАДСКАЯ БИБЛИОТЕКА | ||
© 2010 |