Apache Commons содержит много инструментов с открытым исходным кодом для решения проблем, которые часто встречаются при программировании и снижают повторяющийся труд. Ниже приводится краткое введение в инструменты, которые я использовал в процессе разработки в последние несколько лет.
| Компоненты | Функциональное введение |
| Бианхатура | Обеспечивает различные операции, клонирование объектов, свойства и т. Д. Для Javabeans. |
| Между | Преобразуйте объекты XML и Java друг другу. |
| Кодек | Инструменты, которые имеют дело с часто используемыми методами кодирования, такими как DES, SHA1, MD5, Base64 и т. Д. |
| Коллекции | Java Collection Framework Operation. |
| Компресс | Java обеспечивает библиотеку класса сжатия упаковки файлов. |
| Конфигурация | Библиотека классов управления конфигурацией для приложений Java. |
| DBCP | Предоставьте услуги объединения базы данных. |
| Dbutils | Обеспечивает операцию инкапсуляции JDBC для упрощения запросов данных и операций чтения записей. |
| Электронная почта | Java отправляет почту в инкапсуляцию Javamail. |
| FileUpload | Предоставляет функцию загрузки файла. |
| Httpclient | Предоставляет различные коммуникационные операции между клиентами HTTP и серверами. Теперь он был изменен на httpcomponents |
| Io | Инкапсуляция инструментов ввода -вывода. |
| Ланг | Пакеты классов инструментов для методов базовых объектов Java, таких как: StringUtils, Arrayutils и т. Д. |
| Регистрация | Он обеспечивает интерфейс журнала Java. |
| Валидатор | Предоставляет структуру проверки данных для клиента и сервера. |
1. Beanatils предоставляет различные операции для Javabeans, таких как объект, копирование атрибутов и т. Д.
// 1. Клонирование объекта // Создать новый обычный бон Java, который будет использоваться в качестве клонированного объекта Perforce Person {private String name = ";; частная строка Email =";; Private Int Age; // Опустить набор, METE} // Создать тестовый класс, где код в основном методе заключается в следующем: Import java.Lang.Reflect.InVocationTargetexception; импорт. java.util.map; import org.apache.commons.beanutils.beanutils; import org.apache.commons.beanutils.convertutils; открытый тест класса {/** * @param args */public void main (string [] args) {человек) Person2 = (person) beanutils.clonebean (person); system.out.println (person2.getName ()+">>"+person2.getage ());} catch (allodalaccessexception e) {e.printstacktrace ();} catch (instantiationexexexex e) {e.printStacktrace (); {e.printstacktrace ();} catch (nosuchmethodexception e) {e.printstacktrace ();}}} // Принцип также осуществляется с помощью механизма отражения Java. // 2. Преобразование объекта карты в боб // Ключ этого объекта карты должен соответствовать свойствам бобов. Map map = new hashmap (); map.put ("name", "tom"); map.put ("email", "tom@"); map.put ("age", "21"); // конвертировать Map в лицевую личность человека = new Person (); Beanutil. // конвертировать бон в объект карты следующим образом: map map = beanatils.describe (человек)2. Беговые объекты Betwixt XML и Java преобразованы.
// 1. Преобразовать Javabean в XML Content // Создать новый класс нового человека Person Class Percom ", age = '" + age + "']";}} // Создание класса WriteApp: import java.io.stringwriter; import org.apache.commons.betwixt.io.beanwriter; public class writeapp {/*** Создать пример Bean и конвертировать его в xml. */public static final void main (string [] args) бросает исключение {// Сначала создать строки, мы напишем его в качестве строки stringwriter outputWriter = new StringWriter (); // Betwixt здесь просто записывает боб как фрагмент // Так что, если мы хотим завершить контент XML, мы должны написать в формате «Заголовок». Encoding = 'UTF-8'?>/n "); // Создать автора, который будет записан в подготовленный нами поток. Beanwriter Beanwriter = New Beanwriter (outputWriter); // Настройка Betwixt // Для получения более подробной информации, пожалуйста, см. Документы Java или последнее документ beanwriter.getxmlintrospector (). getConfiguration (). setattributesforprimitives (false); beanwriter.getBindingConfiguration (). setMapids (false); Beanwriter.enableprettyprint (); // Если это место не проходит в примере, не так, как это не так, как именное. root node beanwriter.write («Person», New Personbean («John Smith», 21)); // System Result System.out.out.println (outputWriter.toString ()); // Betwixt записывает фрагменты, а не документ, так что вы не выводите автоматические авторы или потоки, //, но здесь просто пример и не будет делать больше, так что вы не можете отключить wutswriter. Преобразовать XML в Javabean Import Java.io.StringReader; Import org.apache.commons.betwixt.io.beanreader; Public Class ReadApp {Public Static Final void Main (String Args []) Throws Exception {// Сначала создать XML. Поскольку это только пример, мы жестко кодировали кусок XML Content StringReader XmlReader = new StringReader ("<? XML Version = '1.0' Encoding = 'UTF-8'?> <Cerson> <Age> 25 </Age> <mame> James Smith </name> </person>"); // create beanreader beanreader beanreader = beanreader =); beanreader.getxmlintrospector (). getConfiguration (). setattributesforprimitives (false); Beanreader.getBindingConfiguration (). SetMapids (false); // регистрация бобов, так что Betwixt знает, что Bean xml будет преобразован в Beanreadse.reger.creg.crecsclass (Personben.class); Personbean Person = (Personbean) beanreader.parse (xmlreader); // soutpture Result System.out.println (Person);}}3. Codec предоставляет некоторые реализации общедоступного кодека, такие как Base64, HEX, MD5, фонетический и URL и т. Д.
// base64 Codec Private Static String EncodeTest (String Str) {base64 base64 = new base64 (); try {str = base64.encodetoString (str.getbytes ("utf-8"));} catch (unsupportedEncodingexcept "+str); return str;} private static void decodetest (String str) {base64 base64 = new Base64 (); // str = arrays.toString (base64.decodebase64 (str)); str = new String (base64.decodebase64 (str)); System.out.println ("base64 Decoded:"+str);}4. Коллекции расширяют java.util и обрабатывают данные довольно гибкие.
org.apache.commons.collections Commons Collections Индивидуальный набор общих интерфейсов и классов инструментов
org.apache.commons.collections.bag Набор классов, которые реализуют интерфейс сумки
org.apache.commons.collections.bidimap Набор классов, которые реализуют интерфейсы серии Bidimap
org.apache.commons.collections.buffer Набор классов, которые реализуют интерфейс буфера
org.apache.commons.collections.collection Набор классов, которые реализуют интерфейс java.util.collection
org.apache.commons.collections.comparators Набор классов, которые реализуют интерфейс java.util.comparator
org.apache.commons.collections.fcomtors Commons Collections Индивидуальный набор функциональных классов
org.apache.commons.collections.iterators Набор классов, которые реализуют интерфейс java.util.iterator
org.apache.commons.collections.keyvalue реализует набор классов, связанных с сбором и картированием ключей/значения
org.apache.commons.collections.list Набор классов, которые реализуют интерфейс java.util.list
org.apache.commons.collections.map Набор классов, которые реализуют интерфейсы серии карт
org.apache.commons.collections.set Набор классов, которые реализуют серии Set Series
/** * Получить определенный ключ после ключа, хранящегося в наборе */orsumedMap Map = new LinkedMap (); map.put («пять», «5»); map.put («шесть», «6»); map.put («семь», «7»); map.firstkey (); // возвращает «пять» («семь» (пять »); Возвращает «семь»/** * Получить значение через ключ * Получить ключ через значение * Ключ и значение переключения и значение в карте */bidimap bidi = new Treebidimap (); Bidi.put («Six», «6»); Bidi.get («Six»); // Возвращает «6» bidi.getkey («6»); // возвращает «шесть» // bidi.removevue («6»); // Удаляет отображение bidimap upverse = bidi.inversebidimap (); // Возвращает карту с ключами и значениями замены System.out.println (обратно);/*** Получить один и тот же элемент в двух наборах*/list <string> list1 = Arraylist <string> (); list1.add ("1"); list1.add ("2"); list1.add ("3"); list1.add ("2"); list2); System.out.println (c);5. Compress Commons упакован и сжатые классовые библиотеки.
// Создать сжатый объект ZiparchiveEntry intrint = new ZiparchiveEntry ("compressTest"); // файл для сжатия f = new File ("E: //test.pdf"); FileInputStream FIS = new FileInputStream (f); // Файл, сжатый с помощью output ZiparchiveOutputput -ZipOutput = new Zipeam -Zipeam. File ("e: //test.zip")); zipoutput.putarchentry (entry); int i = 0, j; while ((j = fis.read ())! = -1) {zipoutput.write (j); i ++; System.out.println (i);} zipoutput.closearchiveentry ();6. Конфигурация используется для того, чтобы помочь обработать файлы конфигурации и поддержать многие методы хранения.
1. Свойства файлы
2. XML документы
3. Файлы списка свойств (.plist)
4. Jndi
5. ДАТА ДАТА
6. Свойства системы
7. Параметры апплета
8. параметры сервлета
// Приведите простой пример свойств #usergui.properties colors.background = #fffff colors.foreground = #000080 window.width = 500 window.height = 300 свойств config = new PropertiesConfiguration ("usergui.properties"); config.setproperty ("colors.background" #00.sperties "); config.save ("usergui.backup.properties); // Сохранить копию integer = config.getInteger (" window.width ");7. DBCP (Pool Connection Connection Pool)-это пул соединений базы данных, который опирается на механизм пула объектов Jakarta Commons-Pool. Источник данных Tomcat использует DBCP.
Импорт javax.sql.datasource; import java.sql.connection; импорт java.sql.statement; import java.sql.resultset; импорт java.sql.sqlaxception; импорт org.apache.commons.pool.objectpool; import.apache.commons. org.apache.commons.dbcp.connectionFactory; import org.apache.commons.dbcp.poolingDataSource; импорт org.apache.commons.dbcp.poolableconnectionFactory; Import org.apache.commons.dbcp.drivermanageNectionFactory; // Официальный пример public stricing straintas args) {System.out.println ("Загрузить драйвер jdbc); try {class.forname (" oracle.jdbc.driver.oracledriver ");} catch (classnotfoundexception e) {e.printstacktrace ();} system.out.println (" endhy ");// system.out. dataSource = setupDataSource ("jdbc: oracle: thin: @localhost: 1521: test"); system.out.println ("Dode."); // соединение conn = nul dataSource.getConnection (); System.out.println («Создание оператора»); stmt = conn.createStatement (); System.out.println («Выполнение оператора»); rset = stmt.executequery («select * from Person»); System.println ("Результаты:"); rset.getMetAdata (). getColumnCount (); while (rset.next ()) {for (int i = 0; i <= numcols; i ++) {System.out.print ("/t"+rset.getString (i));} system.out.println ("");}} QualeString (i); {try {if (rset! = null) rset.close ();} catch (exception e) {} try {if (stmt! = null) stmt.close ();} catch (Exception e) {} try {if (conn! Connecturi) {// Установить адрес подключения ConnectionFactory ConnectionFactory = new Driver ManagerConnectionFactory (connecturi, null); // Создать заводскую заводскую подключение PoolableConnectionFactory PoolableConnectionFactory = new PoolableConnectionFactory (ConnectionFactory); // Получить экземпляр geneicObjectobjectypool -poolpool -generiCobjectPool (pooleconconcefactacnectore); PoolingDatasource DataSource = New BoolingDataSource (ConnectionPool); return DataSource;}}8. Ресурс JDBC Tool Class Class Library предоставлена DbutilSapache Organization. Это простая инкапсуляция JDBC, вторичная инкапсуляция традиционных классов операционной базы данных, и может преобразовать результат, установленный в список. , и это не влияет на производительность программы.
Dbutils Class: класс стартапов
Результаты интерфейса: интерфейс типа преобразования
Класс MaplisThandler: класс реализации, конвертируйте записи в список
Beanlisthandler Class: реализует класс, преобразует записи в список и делает записи в объект типа Javabean
Класс QReryRunner: класс, выполняющий операторы SQL
Импорт org.apache.commons.dbutils.dbutils; импорт org.apache.commons.dbutils.queryrunner; import org.apache.commons.dbutils.handlers.beanlisthandler; импорт java.sql.connection; импорт java.sql.drivermanager; импорт. java.util.list; // конвертировать в список публичных класса Beanlists {public static void main (string [] args) {connect conn = null; string url = "jdbc: mysql: // localhost: 3306/ptest"; string jdbcdriver = "com.mysql.jdbc.driver"; string user = root "; root"; root "; root"; root "; root"; root "; root"; root "; root"; «ptest»; dbutils.loaddriver (jdbcdriver); try {conn = drivermanager.getConnection (url, пользователь, пароль); QueryRunner QR = новый QueryRunner (); Results = (List) QR.Query (Conn, «Select Id, имя от человека», New Beanlishandler (человек. i ++) {person p = (person) results.get (i); system.out.println ("id:" + p.getid () + ", name:" + p.getname ());}} catch (sqlexception e) {e.printstacktrace ();} наконец {dbutils.closequietly (conn); name; // пропустить набор, получить метод} import org.apache.commons.dbutils.dbutils; import org.apache.commons.dbutils.queryrunner; импорт org.apache.commons.dbutils.handlers.maplisthandler; импорт java.sql.connection; импорт. java.sql.sqlexception; import java.util.list; import java.util.map; // конвертирование в карту открытых классов Maplists {public static void main (string [] args) {connect conn = null; string url = "jdbc: mysql: // localhost: 3306/ptest"; "com.mysql.jdbc.driver"; string user = "root"; string password = "ptest"; dbutils.loaddriver (jdbcdriver); try {conn = drivermanager.getConnection (url, пользователь, пароль); Queryrunner Qr = new Queryrunner (). Maplisthandler ()); для (int i = 0; i <refuls.size (); i ++) {map map = (map) results.get (i); System.out.println ("id:" + map.get ("id") + ", name:" + map.get ("name")); {Dbutils.closequietly (conn);}}}9. API с открытым исходным кодом, предоставленный по электронной почте, является инкапсуляцией Javamail.
// Отправлять электронные письма с использованием Commons Email Public Static void Main (String Args []) {Email Email = new SimpleMail (); Email.SethostName ("smtp.googlemail.com"); email.setsmtpport (465); email.setauthenticator (new Defauthenticator ("UserName" "пароль")); email.setsslonconnect (true); email.setfrom ("[email protected]"); email.setsubject ("testmail"); email.setmsg ("Это тестовая почта ... :-)"); email.addto ("[email protected]");10. Функция загрузки веб -файлов Java.
// Официальный пример: //* Проверьте, что у нас есть запрос на загрузку файла Boolean Ismultipart = ServletFileUpload.ismultipartContent (запрос); // Теперь у нас есть список элементов // Если ваше приложение близко к самым простым случаям, приведенная выше обработка достаточно. Но иногда нам все еще нужно больше контроля. // Ниже приведены несколько параметров управления: // Создать завод для элементов файлов на основе дисков DiskFileItemfactory factory = new DiskFileItemFactory (); // Установить заводские ограничения factory.setSizeThroshold (yourmaxMemorysize); factory.setRepository (yourTempDirector ServletFileUpload (Factory); // Установить максимальную загрузку размера загрузки. Setsizemax (yourmaxRequestsize); // parse All запросов List/ * fileItem */items = upload.parserequest (запрос); // Создать завод для файлов на основе диска. yourtempdirectory); // После завершения анализа вам необходимо дополнительно обработать список элементов. // обработать загруженные элементы iterator iter = items.iterator (); while (iter.hasnext ()) {fileitem item = (fileitem) iter.next (); if (item.isformfield ()) {processformfield (item);} else {processuploadedFile (item);}} // различать, является ли данные простыми данными формы, если это простые данные: // processformfield if (item.iSformfield ()) {string name = item.getfieldname (); string value = item.getString ();//omit stears/yemt.getfieldname (); string = item.getString (); ProcessUploadedFile if (! item.isformfield ()) {String fieldName = item.getFieldName (); string fileName = item.getName (); string contentType = item.getContentType (); Boolean ISinmemory = item.isInmemory (); Long SizeInbyTes = item.getSize (); Файл, или преобразовать их в потоку // обработать загрузку файла if (writetofile) {file uploadedfile = new File (...); item.write (uploadedfile);} else {inputstream uploadedStream = item.getInptr В памяти Byte [] data = item.get (); // ... пропущенные шаги // Если этот файл действительно большой, вы можете сообщить пользователю, сколько он был передан на сервер, чтобы пользователь мог понять процесс загрузки // Создать прогресс в ProgressLister = new ProgressListener () {public void update. В настоящее время чтение пункта « + pitems); if (pcontentlength == -1) {System.out.println (« Пока что » + PbytesRead +« Байты были прочитаны read.11. HTTPClien-это HTTP/1,1-совместимый HTTP-клиент, реализованный на основе HTTPCore. Он предоставляет серию многоразовой аутентификации клиента, модулей HTTP статуса и модулей управления соединением HTTP.
// Получить метод импорт java.io.ioexception; import org.apache.commons.httpclient.*; Import org.apache.commons.httpclient.methods.getmethod; импорт org.apache.commons.httpclient.params.httpmethodparams; httpclient httpclient httpclient = new httpclient (); // Создать экземпляр метода Get getMethod getMethod = new getMethod ("http://www.ibm.com"); // Использовать политику восстановления по умолчанию, предоставленную системой для getmethod.getparams (). Defaulthttpmethodretryhandler ()); try {// выполнить getmethod int statuscode = httpclient.executemethod (getmethod); if (statuscode! = httpstatus.sc_ok) {system.err.println ("Метод не удастся:" + getmethod.getstatusline ());} // чтение контента byte [] responsebody = getmethod.getresponsebody (); // Обработка content. произошло, что может быть то, что протокол является неверным или возвращаемым контентом является проблематичной системой. getMethod.releeSeconnection ();}}}} // post Method import java.io.ioexception; import org.apache.commons.httpclient.*; импорт org.apache.commons.httpclient.postmethod; import org..commons.httpclient.postmethd; Postample {public static void main (string [] args) {// Создание экземпляра httpclient httpclient httpclient = new httpclient (); // Создание экземпляра метода Post url = "http://www.orcle.com/"; spostmethod postmethod = new postmethod (urll) formethod (urll); Namevaluepair [] data = {new namevaluepair ("id", "youusername"), new namevaluepair ("passwd", "yourpwd")}; // Поместите значение формы в постметод postmethod.setrequestbody (data); // exepute int int int inttemethode.exetemetdebodebodebodebodebode. Httpclient не может автоматически обрабатывать пересылку для запросов, которые требуют последующих услуг, таких как Post и put // 301 или 302 if (centrecode == httpstatus.sc_moven_permanly || centrecode == httpstatus.sc_temed_tementaly) {// Выбрать адрес управления из начального заголовка. postmethod.getResponseHeader ("location"); String location = null; if (locationHeader! = null) {location = locationHeader.getValue (); System.out.println ("Страница была перенаправлена на:" + location);} else {System.err.println ("Полевое значение местоположения не является нуль.12. IO очень удобен для java.io, чтобы расширить операционный файл.
// 1. Читать поток // Стандартный код: inputstream in = new URL ("http://jakarta.apache.org") .openstream (); try {inputStreamReader inr = new InputStreamReader (in); BufferedReader BUF = new BufferedReader (inr); String Line; while = Buf.Readline ()) nul). );}} наконец {in.close ();} // Использовать ioutils inputstream in = new url ("http://jakarta.apache.org") .openstream (); try {System.out.println (iOutils.ToString (in);}, наконец, {ioutilss.clesquietting (in); Читать файл файла файла = новый файл ("/commons/io/project.properties"); list lines = fileutils.readlines (файл, "UTF-8"); // 3. Посмотреть оставшееся пространство Long Freespace = fileSystemutils.freespace ("c:/");13. Ланг - это в основном набор публичных инструментов, таких как операции на персонажах, массивы и т. Д.
// 1 объединить два массива: org.apache.commons.lang. Arrayutils // Иногда нам нужно объединить два массива в массив, и очень удобно использовать арарутилы. Пример заключается в следующем: private static void testarr () {string [] s1 = new String [] {"1", "2", "3"}; string [] s2 = new String [] {"a", "b", "c"}; string [] s = (string []) arrayutils.addall (s1, s2); {System.out.println (s [i]);} string str = arrayutils.tostring (s); str = str.substring (1, str.length () - 1); system.out.println (str + ">>" + str.length ());} // 2 string, начинающийся с stringtilss.substringfter ("//} // 2 -й string -strings.substringfter (" //} // 2 struceperse.substringfter ("//} // 2 string st stringtils.substringafter (" //}; состоит ли строка из чисел (0 ~ 9). Если это так, верните True, но этот метод не распознает десятичные очки и обратите внимание, что stringUtils.isnumeric ("454534"); // return true // 4. Получить имени класса System.out.println (classutils.getShortClassName (test.class)); // Получите систему имен пакета. //5.numberutils System.out.println (numberutils.stringtoint ("6")); // 6. Пятизначные случайные буквы и числа System.out.println (randomStringutils.randomalphanumeric (5)); //7.StringScapeUtils System.out.println (stringScapeUtils.escapehtml ("<html>")); // Результат вывода - <html> system.out.println (stringescapeutils.escapejava ("string"); // 8. strisils, определить, является ли это космос -картин. ")); // отделить содержимое в массиве System.out.println (stringUtils.join (тест,", ")); // Добавить символы справа, чтобы сделать общую длину 6 System.out.println (StringUtils.rightPad (" ABC ", 6, 't')); // Первая буква капитализирована. System.out.println(StringUtils.capitalize("abc"));//Deletes all whitespaces from a String Delete all spaces System.out.println( StringUtils.deleteWhitespace("abc"));//Deletes all whitespaces from a String Delete all spaces System.out.println( StringUtils.contains("abc", "ba")); // обозначает два символа в левой системе.14. Регистрация предоставляет интерфейс журнала Java, который учитывает как легкий и не полагается на конкретные инструменты реализации журнала.
Импорт org.apache.commons.logging.log; import org.apache.commons.logging.logfactory; public class commonlogtest {private static log = logfactory.getlog (commonlogtest.class); // {log.error ("error"); log.debug ("Debug"); log.warn ("warn"); log.info ("info"); log.trace ("trace"); System.out.println (log.getClass ());}} 15. Validator - это общая система проверки, которая предоставляет структуру проверки данных для клиента и сервер.
Дата проверки
// Получить дату проверки datevalidator varidator = datevalidator.getInstance (); // проверка/преобразовать дату дату foodate = varidator.validate (foostring, "dd/mm/yyyy"); if (foodate == null) {// Ошибка не является датой возвратом;};Проверка выражения
// Установите параметр boolean caseensitive = false; string regex1 = "^([az]*) (?: //-) ([az]*)*$" string regex2 = "^([az]*) $"; string [] regexs = new String [] {regex1, regex1}; // create valdator regexvalator valyator = newexvalator = newexvalator = newexvalator = new. Regexvalidator (regexs, caseensity); // проверка возврата Boolean Boolean valive = validator.isvalid ("abc-def"); // проверка возврата строковой строки result = validator.validate ("abc-def"); // проверка возврата строки Array [] groups = validator.match ("abc-def");Используйте проверку в файлах конфигурации
<validation form> <laly> <validator name = "require" classname = "org.apache.commons.validator.testvalidator" method = "valyateRequired" methodparams = "java.lang.object, org.apache.commons.validator.field"/> </global> <formset> </formset> </form variation> </form-valiation. <validation form> <blodal> <validator name = "require" classname = "org.apache.commons.validator.testvalidator" method = "validateRequired" methodparams = "java.lang.object, org.apache.commons.validator.field"/> </global> <formset> <form name = "nameform. зависит = "требуется"> <arg0 key = "nameform.firstname.displayname"/> </field> <field property = "lastname" зависит = "требуется"> <arg0 key = "nameform.lastname.displayName"/> </formset> </validation> nameform.lastname.displayName "/> </formSet> </validation>
Проверка класса
Excelpts от org.apache.commons.validator.requirednametest // Загрузить файл конфигурации проверки inputstream in = this.getClass (). GetResourceasStream ("validator-me-required.xml"); validatorresources resources = new ValidorResources (in); // Это Bean, созданный. Я пропустил имя name = new name (); videalator valyator = new Validator (ресурсы, "nameform"); // Установить параметр validator.setParameter (validator.bean_param, name); map results = null; // Verify Results = validator.validate (); if (Results.get ("FirstName") = null) ((Integer) Results.get ("FirstName")). Intvalue ();}Суммировать
Выше приведено подробное объяснение кода набора инструментов Apache Commons в этой статье, я надеюсь, что это будет полезно для всех. Заинтересованные друзья могут продолжать ссылаться на другие связанные темы на этом сайте. Если есть какие -либо недостатки, пожалуйста, оставьте сообщение, чтобы указать это. Спасибо, друзья, за вашу поддержку на этом сайте!