Sun's JavaFX 1.0 platform opens a vast global market for developers and content authors who want to deploy their content, services and experiences across all the screens of their customers' lives. Worldwide industry estimates show that Java technology is already on more than 90 percent of desktops and laptops, 85 percent of mobile devices and is a technology leader in next-generation televisions, Blu-ray disc players and TV set-top boxes.
05 декабря 2008
Java FX 1.0 релиз состоялся
Вчера, 04.12.2008, состоялся релиз Java FX 1.0. Посмотреть примеры работы, изучить туториалы и скачать SDK можно с сайта http://www.javafx.com/
Множественные уязвимости в Sun Java JDK и JRE
Обнаруженные уязвимости позволяют удаленному пользователю обойти некоторые ограничения безопасности, получить доступ к важным данным, вызвать отказ в обслуживании и скомпрометировать целевую систему.
Всего 23 уязвимости(SecurityLab)
Всего 23 уязвимости(SecurityLab)
Решение: Установите исправление
JDK and JRE 6 Update 11:
http://java.sun.com/javase/downloads/index.jsp
JDK and JRE 5.0 Update 17:
http://java.sun.com/javase/downloads/index_jdk5.jsp
SDK and JRE 1.4.2_19:
http://java.sun.com/j2se/1.4.2/download.html
SDK and JRE 1.3.1_24:
http://java.sun.com/j2se/1.3/download.html
- ZDI-08-080: Sun Java AWT Library Sandbox Violation Vulnerability
- ZDI-08-081: Sun Java Web Start and Applet Multiple Sandbox Bypass Vulnerabilities
- iDefense Security Advisory 12.04.08: Sun Java JRE TrueType Font Parsing Heap Overflow Vulnerability
- iDefense Security Advisory 12.04.08: Sun Java Web Start GIF Decoding Memory Corruption Vulnerability
- iDefense Security Advisory 12.04.08: Sun Java JRE Pack200 Decompression Integer Overflow Vulnerability
- iDefense Security Advisory 12.04.08: Sun Java JRE TrueType Font Parsing Integer Overflow Vulnerability
- The Java Runtime Environment Creates Temporary Files That Have "Guessable" File Names
- Java Runtime Environment (JRE) Buffer Overflow Vulnerabilities in Processing Image Files and Fonts May Allow Applets or Java Web Start Applications to Elevate Their Privileges
- Multiple Security Vulnerabilities in Java Web Start and Java Plug-in May Allow Privilege Escalation
- The Java Runtime Environment (JRE) "Java Update" Mechanism Does Not Check the Digital Signature of the JRE that it Downloads
- A Buffer Overflow Vulnerability in the Java Runtime Environment (JRE) May Allow Privileges to be Escalated
- A Security Vulnerability in the Java Runtime Environment (JRE) Related to Deserializing Calendar Objects May Allow Privileges to be Escalated
- A Buffer Overflow Vulnerability in the Java Runtime Environment (JRE) "Unpack200" JAR Unpacking Utility May Lead to Escalation of Privileges
- The Java Runtime Environment UTF-8 Decoder May Allow Multiple Representations of UTF-8 Input
- Security Vulnerability in Java Runtime Environment May Allow Applets to List the Contents of the Current User's Home Directory
- Security Vulnerability in the Java Runtime Environment With Processing RSA Public Keys
- A Security Vulnerability in Java Runtime Environment (JRE) With Authenticating Users Through Kerberos May Lead to a Denial of Service (DoS)
- Security Vulnerabilities in the Java Runtime Environment (JRE) JAX-WS and JAXB Packages may Allow Privileges to be Escalated
- A Security Vulnerability in Java Runtime Environment (JRE) With Parsing of Zip Files May Allow Reading of Arbitrary Memory Locations
- A Security Vulnerability in the Java Runtime Environment may Allow Code Loaded From the Local Filesystem to Access LocalHost
Sun News Radio
Узнать новости Sun Microsystems можно из первых уст http://www.blogtalkradio.com/stations/sunradio/SunNews
28 ноября 2008
Работа со строками в oracle
Наиболее частая операция, которую необходимо выполнять - это выбор подстроки из строки. Для этого в oracle присутствует специальная встроенная функция substr
например : substr('test string #1', 5, 11 ) , где 1й параметр - это задана строка, 2й - позиция с которой начинается подстрока, 3й(не обязательный) - длинна подстроки.
Если точна позиция начала подстроки не известна , можно воспользоваться функцией instr
Например instr('test string #1', ' ' ) - будет найдено первое вхождение пробела в строку. В функции instr есть ещё третий параметр, который задаёт начало поиска, причём если указать -1 начало будет производится с конца строки.
Другие полезные функции:
ascii('S') - ascii код символа
upper / lower / initcap - преобразования регистра букв в большие / маленькие / первая большая все остальные маленькие.
chr(168) - получения символа по заданному ascii коду
concat('s1','s2') - соединение строк
trim / rtrim / ltrim - отбрасывание пробелов
reverse('12345') - получение строки с символами в обратном порядке
length - длинна строки
например : substr('test string #1', 5, 11 ) , где 1й параметр - это задана строка, 2й - позиция с которой начинается подстрока, 3й(не обязательный) - длинна подстроки.
Если точна позиция начала подстроки не известна , можно воспользоваться функцией instr
Например instr('test string #1', ' ' ) - будет найдено первое вхождение пробела в строку. В функции instr есть ещё третий параметр, который задаёт начало поиска, причём если указать -1 начало будет производится с конца строки.
Другие полезные функции:
ascii('S') - ascii код символа
upper / lower / initcap - преобразования регистра букв в большие / маленькие / первая большая все остальные маленькие.
chr(168) - получения символа по заданному ascii коду
concat('s1','s2') - соединение строк
trim / rtrim / ltrim - отбрасывание пробелов
reverse('12345') - получение строки с символами в обратном порядке
length - длинна строки
23 ноября 2008
Паттерн поведения Observer (наблюдатель)
Наблюдатель (Observer) - паттерн поведения объектов, устанавливающий систему оповещения объектами своих соседей в процессе их деятельности.
Известен также под именами: Dependents (подчиненные), Publish-Subscribe (издатель-подписчик).
В процессе функционирования и взаимодействия объектов системы нужно оповещать других участников по завершении какой-нибудь значимой операции. Конечно же, можно в каждый такой класс, производящий значимые действия добавлять обращение к этим всем другим заинтересованным объектам, но таким образом мы дублируем связи между объектами (система становится все менее и менее гибкой) – это еще и в разы затруднит последующую модификацию каких либо участников, т.к. необходимо будет перекомпилировать этот код обращения ко всем заинтересованных субъектам.
В этом случае очень подошло бы иметь такую структуру, в которой каждый участник, если он заинтересован в каких-либо событиях системы, мог бы самостоятельно «подписаться» на эти изменния независимо от других заинтересованных участникам – и, таким образом, получая уведомления об этих событиях – выполнять требуемые ответные действия.
В результате – не создается лишних связей: есть источник значимых действий, есть заинтересованные в фактах выполнения этих действий субъекты, никак не связанный друг с другом, количество которых при этом – также неограниченно.
Паттерн-наблюдатель описывает именно такой подход: определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом и автоматически обновляются.
Реализация паттерна поведения Наблюдатель (Observer).
Итак, у нас есть класс Child , который описывает модель ребёнка, основное действие - ребёнок растёт : childGrow, и в зависимости от возвраста ребёнка необходимо менять одежду, еду, игрушки - эти сущности описываются классами Clothes, Food, Toys соответственно. Эти три сущности реалиузют интерфейс Observer через класс BaseObserver.
После создания экземпляра класса ребёнка мы можем добавить или удалить специфических наблюдателей, и при достижении ребёнком какого то возраста (вызов childGrow) автоматически произойдёт обновление зарегистрированных в это время слушателей.
Источники:
Ппаттерн наблюдатель
Observer pattern
Speaking on the Observer pattern
Известен также под именами: Dependents (подчиненные), Publish-Subscribe (издатель-подписчик).
В процессе функционирования и взаимодействия объектов системы нужно оповещать других участников по завершении какой-нибудь значимой операции. Конечно же, можно в каждый такой класс, производящий значимые действия добавлять обращение к этим всем другим заинтересованным объектам, но таким образом мы дублируем связи между объектами (система становится все менее и менее гибкой) – это еще и в разы затруднит последующую модификацию каких либо участников, т.к. необходимо будет перекомпилировать этот код обращения ко всем заинтересованных субъектам.
В этом случае очень подошло бы иметь такую структуру, в которой каждый участник, если он заинтересован в каких-либо событиях системы, мог бы самостоятельно «подписаться» на эти изменния независимо от других заинтересованных участникам – и, таким образом, получая уведомления об этих событиях – выполнять требуемые ответные действия.
В результате – не создается лишних связей: есть источник значимых действий, есть заинтересованные в фактах выполнения этих действий субъекты, никак не связанный друг с другом, количество которых при этом – также неограниченно.
Паттерн-наблюдатель описывает именно такой подход: определяет зависимость типа «один ко многим» между объектами таким образом, что при изменении состояния одного объекта все зависящие от него оповещаются об этом и автоматически обновляются.
Реализация паттерна поведения Наблюдатель (Observer).
/** Observer design pattern sample
*/
import java.util.ArrayList;
import java.util.List;
public class Child {
// --
List list = new ArrayList();
void addObserver(Observer o){
list.add(o);
}
void removeObserver(Observer o){
list.remove(o);
}
void notifyObservers(){
for (Observer o:list){
o.update();
}
}
// --
void childGrow(int newAge){
System.out.println("Age of child changed to " + newAge);
notifyObservers();
}
public static void main(String []s){
Child ot = new Child();
ot.childGrow(1);
ot.addObserver(new Food());
ot.addObserver(new Toys());
ot.addObserver(new Clothes());
ot.childGrow(3);
ot.removeObserver(new Food());
ot.childGrow(10);
ot.removeObserver(new Toys());
ot.childGrow(15);
ot.addObserver(new Food());
ot.childGrow(20);
ot.removeObserver(new Food());
ot.removeObserver(new Clothes());
ot.childGrow(25);
}
}
interface Observer {
void update();
}
abstract class BaseObserver implements Observer {
public boolean equals(Object obj) {
return this.getClass().equals(obj.getClass());
}
}
class Clothes extends BaseObserver {
public void update() {
System.out.println("Change childs' clothes");
}
}
class Toys extends BaseObserver {
public void update() {
System.out.println("Change childs' toys");
}
}
class Food extends BaseObserver {
public void update() {
System.out.println("Change childs' food");
}
}
Итак, у нас есть класс Child , который описывает модель ребёнка, основное действие - ребёнок растёт : childGrow, и в зависимости от возвраста ребёнка необходимо менять одежду, еду, игрушки - эти сущности описываются классами Clothes, Food, Toys соответственно. Эти три сущности реалиузют интерфейс Observer через класс BaseObserver.
После создания экземпляра класса ребёнка мы можем добавить или удалить специфических наблюдателей, и при достижении ребёнком какого то возраста (вызов childGrow) автоматически произойдёт обновление зарегистрированных в это время слушателей.
Источники:
Ппаттерн наблюдатель
Observer pattern
Speaking on the Observer pattern
22 ноября 2008
Перенаправление системного вывода в файл
Для того что бы выводить информацию из Java программы в файл не обязательно использовать навороченные системы логгирования.
Можно просто перенаправить стандартный поток вывода и стандартный поток для ошибок в файл.
Сделать это можно с помощью следующего фрагмента кода:
Можно просто перенаправить стандартный поток вывода и стандартный поток для ошибок в файл.
Сделать это можно с помощью следующего фрагмента кода:
PrintStream st = new PrintStream(new FileOutputStream("output.txt"));
System.setErr(st);
System.setOut(st);
20 ноября 2008
Java EE справочник по русски
Java 2 Enterprise Eddition (J2EE)
Обзор J2EE:
- Введение
- Модель приложений
- Установленные стандарты
- J2EE. Обеспечение совместимости, переносимости и возможности сетевого взаимодействия (PDF)
Учебник по J2EE (PDF):
- Предисловие
- Обзор
- Введение
- Пример сессионного компонента
- Примеры управляемой компонентами персистентности
- Корпоративные компоненты
Разработчикам:
- Платформа Java (PDF)
- Руководство по Web-сервисам (PDF)
- Новое в спецификации Enterprise JavaBean 2.0
- Процесс разработки B2B-приложений (PDF)
- Корпоративные компоненты JavaBeans и клиенты CORBA: Руководство разработчика (PDF)
- Основы сервлетов Java
- Основы RMI
- Руководство: Сервлеты (PDF)
- Технология Java Servlet
- JavaServer Pages
- Средство связывания данных XML для платформы Java (PDF)
- Переносимые данные/переносимый код: технологии XML и Java (PDF)
- Архитектура коннектора J2EE (PDF)
- Архитектура J2EE Connector
- Язык описания интерфейсов Java (Java IDL)
- Java Transaction API (JTA)
- Java Transaction Service (JTS)
- JavaMail 1.2 API
- Основные паттерны J2EE
- Core J2EE Pattern Catalog (PDF)
- Business Delegate (PDF)
- Composite Entity (составная сущность) (PDF)
- Composite View (PDF)
- Data Access Object (объект доступа к данным) (PDF)
- Dispatcher View (PDF)
- Front Controller (PDF)
- Intercepting Filter (PDF)
- Service Activator (PDF)
- Service Locator (локатор службы) (PDF)
- Service to Worker (PDF)
- Session Facade (фасад сессии) (PDF)
- Transfer Object Assembler (сборщик объекта перемещения) (PDF)
- Transfer Object (объект перемещения) (PDF)
- Value List Handler (обработчик списка значений) (PDF)
- View Helper (PDF)
17 ноября 2008
JScience : Java научная библиотека
JSscience - всеобъемлющая Java библиотека предоставляющая API для научных вычислений. API включает функции для выполнения различных задач из таких областей науки, как : физика, биология, социология, астрономия, экономика, география и др.
Описание некоторых возможностей:
Документация(версия 4.3.1)
Скачать библиотеку(версия 4.3.1)
Описание некоторых возможностей:
- Модуль coordinates совместимый с OGC/ISO спецификацией для разработке географических
- linear algebra - модуль включающий параметризированный класс матрица , позволяющий решать линейные уравнения различной сложности.
- measurements - модуль для произведения измерений различной точности
- models - модуль поддерживающий различные физические системы.
- monetary- модуль для проведения валютных операций из заданой точностью.
Документация(версия 4.3.1)
Скачать библиотеку(версия 4.3.1)
SwisSQL - Oracle to Java Migration Tool
SwisSQL- утилита для преобразования Oracle PL/SQL кода в Java. SwisSQL на вход получает код пакетов, функций, процедур, тригеров и преобразует в Jdbc код.
Springmodules
Spring. Модули, дополнения и тулзы интеграции для Spring.
Документация
Последний релиз 0.8 содержит :
Документация
Последний релиз 0.8 содержит :
- Ant integration.
- Flux suite of products integration.
- HiveMind integration.
- Lucene integration.
- Apache OJB integration.
- O/R Broker integration.
- OSWorkflow integration.
- Tapestry integration.
- Support for declarative caching services including EHCache, JCS, OSCache, GigaSpaces and others.
- Support for db4o
- Support for JSR-94 Rules Engines such as Drools and Jess
- Support for various Jakarta Commons components such as Configuration, Lang, Chain and Commons Validator
- Support for JavaSpaces, including Gigaspaces and Blitz.
- Support for jBPM 3.0.x and 3.1.x
- Support for JSR-170 (Java Content Repository) including Jackrabbit and Jeceira.
- Support for web template engines like Freemarker, Groovy, Velocity, WebMacro and XSLT.
- Valang: Validation Language.
- Bean Validation Framework.
- Spring MVC add-ons.
- XT Framework: Domain-Driven Design oriented framework and Spring MVC AJAX support for developing richer domain models and richer user interfaces.
15 ноября 2008
Психологический барьер предодолён 100 уникальных посетителей в день.
14 ноября 2008 года Google Analytics показал, что сайт посетило ровно 100 уникальных посетителей. На данный момент это рекорд.
В среднем, за последних 2 месяца количество уникальных посетителей колеблется от 70 до 80 , постоянно увеличиваясь.
Так что продолжу добавлять востребованный контент, для достижения новых рекордов.
В среднем, за последних 2 месяца количество уникальных посетителей колеблется от 70 до 80 , постоянно увеличиваясь.
Так что продолжу добавлять востребованный контент, для достижения новых рекордов.
12 ноября 2008
Добавление элементов в Java масив
Написал 2 простые функции по добавлению одного или нескольких элементов в конец масива.
У кого есть более эффективный метод прошу поделиться.
public static String[] addToArray(String[] array, String s) {
String[] ans = new String[array.length+1];
System.arraycopy(array, 0, ans, 0, array.length);
ans[ans.length - 1] = s;
return ans;
}
public static String[] addToArray(String[] array, String[] s) {
String[] ans = new String[array.length + s.length];
System.arraycopy(array, 0, ans, 0, array.length);
System.arraycopy(s, 0, ans, array.length, s.length);
return ans;
}
У кого есть более эффективный метод прошу поделиться.
SpringSource покупает G2One
11 ноября, 2008, SpringSource объявили, что он приобрели G2One - компанию которая поддерживает Groovy и Grails технологии.
источник 1(en)
источник 2(ru)
источник 1(en)
источник 2(ru)
11 ноября 2008
Создание представления в PL/SQL c помощью execute immediate
Вот пытаюсь выполнить PL/SQL код, который должен создать представление в базе данных:
declare
begin
execute immediate 'create or replace force view test_view1 ("f1","F2") as select 0, sysdate from dual;';
end;
/
И получаю совершенно неожиданный результат, а именно исключение:
ORA-00911: invalid character
ORA-06512: at line 3
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than ...
И это при том, что SQL команда по созданию этого представления успешно протестированна и выполняется без ошибок.
В заблуждение вводит текст исключения, потому что хочется сразу проверить введённое имя представления, хоть оно и правильное. Методом проб и ошибок (точенее одной пробы) удалось установить что вызвало это исключение.
Причина - это точка с запятой указанная после ключевого слова dual ... всё логично, но при такой обработке исключение довольно сложно обнаружить такую ошибку.
И ещё одна заметка на эту тему : названия полей для представлений должны быть написаны большыми буквами!!! Такую ошибку также довольно сложно обнаружить, и притом не на этапе создания представления, а лишь на этапе тестирования, выполняя запросы к представлению.
Например в моём случае , запрос:
seleсt f2 from test_view1 успешно выполниться , в то время как
seleсt f1 from test_view1 сообщит мне что колонки f1 в таблице нету ...
Будьте бдительны).
declare
begin
execute immediate 'create or replace force view test_view1 ("f1","F2") as select 0, sysdate from dual;';
end;
/
И получаю совершенно неожиданный результат, а именно исключение:
ORA-00911: invalid character
ORA-06512: at line 3
00911. 00000 - "invalid character"
*Cause: identifiers may not start with any ASCII character other than ...
И это при том, что SQL команда по созданию этого представления успешно протестированна и выполняется без ошибок.
В заблуждение вводит текст исключения, потому что хочется сразу проверить введённое имя представления, хоть оно и правильное. Методом проб и ошибок (точенее одной пробы) удалось установить что вызвало это исключение.
Причина - это точка с запятой указанная после ключевого слова dual ... всё логично, но при такой обработке исключение довольно сложно обнаружить такую ошибку.
И ещё одна заметка на эту тему : названия полей для представлений должны быть написаны большыми буквами!!! Такую ошибку также довольно сложно обнаружить, и притом не на этапе создания представления, а лишь на этапе тестирования, выполняя запросы к представлению.
Например в моём случае , запрос:
seleсt f2 from test_view1 успешно выполниться , в то время как
seleсt f1 from test_view1 сообщит мне что колонки f1 в таблице нету ...
Будьте бдительны).
JavaFX 1.0 релиз в декабре
По сообщению The Planetarium официальный релиз JavaFX намечен на 2 декабря 2008 года.
Напомню, что в начале этого года Sun создал JavaFX Preview SDK для программирования на JavaFX.
о JavaFx
Напомню, что в начале этого года Sun создал JavaFX Preview SDK для программирования на JavaFX.
о JavaFx
08 ноября 2008
Новые функции в Java Math
Если в проекте много "математики" , то код получается не красивый и сложно понимаемый, приходиться писать множество комментариев , что бы было понятно что к чему.
Но SUN идёт на встречу разработчикам, и в каждой новой версии добавляет всё новые функции в основной математический класс - java.lang.Math
Новое в Java 1.5 :
log10(double a) - логарифм с основанием 10
cbrt(double a) - корень кубический
ulp(double d) - на сколько я понял это модуль разницы между параметром d преобразованным в float и ближайшим по возрастанию double значением. поправьте если я не прав!
signum(double d) - возвращает знак числа: 0, если d=0; -1.0 если d<0;>0;
sinh(double x) - \
cosh(double x) - - гиперболические синус, косинус и тангес
tanh(double x)- /
hypot(double x, double y) - гипотенуза
expm1(double x) - = exp(x) - 1
log1p(double x) - = ln(x+1)
Новое в 1.6
copySign(double magnitude, double sign)
getExponent(double d)
nextAfter(double start, double direction)
nextUp(double d)
scalb(double d, int scaleFactor)
Всё красиво, всё удобно - чего только стоит функция гипотенузы. Но всё имеет свои минусы, тут они также есть.
Если сравнить производительность, например той же функции hypot(x,y)
c более привычным способом получения значения гипотенузы Math.sqrt(x*x + y*y), то получим достаточно интересные результаты, а именно - разница в скорости выполнении различается почти в 100 раз!!! причём как это не удивительно , но не в пользу нововведённой функции.
Итак , мой тестовый класс:
public class RealType {
public static void main(String[] s) throws Exception{
long start1;
int counter = 0;
double temp = 0;
for (int k=0; k<5;>
start1 = System.currentTimeMillis();
for (int i=0; i<1000;>
for (int j=0; j<5000;>
temp = Math.sqrt(i*i + j*j);
counter++;
}
}
System.out.println("Spent time to run sqrt " + counter + " times : " + (System.currentTimeMillis() - start1));
counter = 0;
start1 = System.currentTimeMillis();
for (int i=0; i<1000;>
for (int j=0; j<5000;>
temp = Math.hypot(i, j);
counter++;
}
}
System.out.println("Spent time to run hypot " + counter + " times : " + (System.currentTimeMillis() - start1));
}
}
}
После выполнения я получил приблизительно следующие результаты:
Spent time to run sqrt 5000000 times : 63
Spent time to run hypot 5000000 times : 4109
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4172
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4140
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4157
Spent time to run sqrt 5000000 times : 46
Spent time to run hypot 5000000 times : 4172
Тоесть, скорость выполнения одного вызова функции на моём компьютере занимает 800 наносекунд для hypot и 9 наносекунд для sqrt.
Для того что бы понять откуда такая разница, пришлось порытся в исходниках и посмотреть что собой представляет нативная hypot . Поиски привели меня к hypot_e.c и выглядит он следующим образом:
/*----------------------*/
#include "fdlibm.h"
#ifdef __STDC__
double __ieee754_hypot(double x, double y)
#else
double __ieee754_hypot(x,y)
double x, y;
#endif
{
double a=x,b=y,t1,t2,y1,y2,w;
int j,k,ha,hb;
ha = __HI(x)&0x7fffffff; /* high word of x */
hb = __HI(y)&0x7fffffff; /* high word of y */
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
__HI(a) = ha; /* a <- |a| */
__HI(b) = hb; /* b <- |b| */
if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
k=0;
if(ha > 0x5f300000) { /* a>2**500 */
if(ha >= 0x7ff00000) { /* Inf or NaN */
w = a+b; /* for sNaN */
if(((ha&0xfffff)|__LO(a))==0) w = a;
if(((hb^0x7ff00000)|__LO(b))==0) w = b;
return w;
}
/* scale a and b by 2**-600 */
ha -= 0x25800000; hb -= 0x25800000; k += 600;
__HI(a) = ha;
__HI(b) = hb;
}
if(hb <>
if(hb <= 0x000fffff) { /* subnormal b or 0 */
if((hb|(__LO(b)))==0) return a;
t1=0;
__HI(t1) = 0x7fd00000; /* t1=2^1022 */
b *= t1;
a *= t1;
k -= 1022;
} else { /* scale a and b by 2^600 */
ha += 0x25800000; /* a *= 2^600 */
hb += 0x25800000; /* b *= 2^600 */
k -= 600;
__HI(a) = ha;
__HI(b) = hb;
}
}
/* medium size a and b */
w = a-b;
if (w>b) {
t1 = 0;
__HI(t1) = ha;
t2 = a-t1;
w = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
y1 = 0;
__HI(y1) = hb;
y2 = b - y1;
t1 = 0;
__HI(t1) = ha+0x00100000;
t2 = a - t1;
w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
t1 = 1.0;
__HI(t1) += (k<<20);
return t1*w;
} else return w;
}
Теперь всё становится ясным, такое количество дополнительных проверок не могут обойтись дёшево. Совсем другой вопрос всегда ли нужны они! Решать вам...
Но SUN идёт на встречу разработчикам, и в каждой новой версии добавляет всё новые функции в основной математический класс - java.lang.Math
Новое в Java 1.5 :
log10(double a) - логарифм с основанием 10
cbrt(double a) - корень кубический
ulp(double d) - на сколько я понял это модуль разницы между параметром d преобразованным в float и ближайшим по возрастанию double значением. поправьте если я не прав!
signum(double d) - возвращает знак числа: 0, если d=0; -1.0 если d<0;>0;
sinh(double x) - \
cosh(double x) - - гиперболические синус, косинус и тангес
tanh(double x)- /
hypot(double x, double y) - гипотенуза
expm1(double x) - = exp(x) - 1
log1p(double x) - = ln(x+1)
Новое в 1.6
copySign(double magnitude, double sign)
getExponent(double d)
nextAfter(double start, double direction)
nextUp(double d)
scalb(double d, int scaleFactor)
Всё красиво, всё удобно - чего только стоит функция гипотенузы. Но всё имеет свои минусы, тут они также есть.
Если сравнить производительность, например той же функции hypot(x,y)
c более привычным способом получения значения гипотенузы Math.sqrt(x*x + y*y), то получим достаточно интересные результаты, а именно - разница в скорости выполнении различается почти в 100 раз!!! причём как это не удивительно , но не в пользу нововведённой функции.
Итак , мой тестовый класс:
public class RealType {
public static void main(String[] s) throws Exception{
long start1;
int counter = 0;
double temp = 0;
for (int k=0; k<5;>
start1 = System.currentTimeMillis();
for (int i=0; i<1000;>
for (int j=0; j<5000;>
temp = Math.sqrt(i*i + j*j);
counter++;
}
}
System.out.println("Spent time to run sqrt " + counter + " times : " + (System.currentTimeMillis() - start1));
counter = 0;
start1 = System.currentTimeMillis();
for (int i=0; i<1000;>
for (int j=0; j<5000;>
temp = Math.hypot(i, j);
counter++;
}
}
System.out.println("Spent time to run hypot " + counter + " times : " + (System.currentTimeMillis() - start1));
}
}
}
После выполнения я получил приблизительно следующие результаты:
Spent time to run sqrt 5000000 times : 63
Spent time to run hypot 5000000 times : 4109
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4172
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4140
Spent time to run sqrt 5000000 times : 47
Spent time to run hypot 5000000 times : 4157
Spent time to run sqrt 5000000 times : 46
Spent time to run hypot 5000000 times : 4172
Тоесть, скорость выполнения одного вызова функции на моём компьютере занимает 800 наносекунд для hypot и 9 наносекунд для sqrt.
Для того что бы понять откуда такая разница, пришлось порытся в исходниках и посмотреть что собой представляет нативная hypot . Поиски привели меня к hypot_e.c и выглядит он следующим образом:
/*----------------------*/
#include "fdlibm.h"
#ifdef __STDC__
double __ieee754_hypot(double x, double y)
#else
double __ieee754_hypot(x,y)
double x, y;
#endif
{
double a=x,b=y,t1,t2,y1,y2,w;
int j,k,ha,hb;
ha = __HI(x)&0x7fffffff; /* high word of x */
hb = __HI(y)&0x7fffffff; /* high word of y */
if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
__HI(a) = ha; /* a <- |a| */
__HI(b) = hb; /* b <- |b| */
if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
k=0;
if(ha > 0x5f300000) { /* a>2**500 */
if(ha >= 0x7ff00000) { /* Inf or NaN */
w = a+b; /* for sNaN */
if(((ha&0xfffff)|__LO(a))==0) w = a;
if(((hb^0x7ff00000)|__LO(b))==0) w = b;
return w;
}
/* scale a and b by 2**-600 */
ha -= 0x25800000; hb -= 0x25800000; k += 600;
__HI(a) = ha;
__HI(b) = hb;
}
if(hb <>
if(hb <= 0x000fffff) { /* subnormal b or 0 */
if((hb|(__LO(b)))==0) return a;
t1=0;
__HI(t1) = 0x7fd00000; /* t1=2^1022 */
b *= t1;
a *= t1;
k -= 1022;
} else { /* scale a and b by 2^600 */
ha += 0x25800000; /* a *= 2^600 */
hb += 0x25800000; /* b *= 2^600 */
k -= 600;
__HI(a) = ha;
__HI(b) = hb;
}
}
/* medium size a and b */
w = a-b;
if (w>b) {
t1 = 0;
__HI(t1) = ha;
t2 = a-t1;
w = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
} else {
a = a+a;
y1 = 0;
__HI(y1) = hb;
y2 = b - y1;
t1 = 0;
__HI(t1) = ha+0x00100000;
t2 = a - t1;
w = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
}
if(k!=0) {
t1 = 1.0;
__HI(t1) += (k<<20);
return t1*w;
} else return w;
}
Теперь всё становится ясным, такое количество дополнительных проверок не могут обойтись дёшево. Совсем другой вопрос всегда ли нужны они! Решать вам...
Список наиболее часто используемых системных таблиц Oracle
Если быть точнее, то это не таблицы, а представления (view) .
Итак, поехали в алфавитном порядке:
ALL_ARGUMENTS - список всех аргументов по объектам
ALL_CATALOG - список всех table, view, synonym, sequence доступных пользователю*
ALL_COL_COMMENTS - список всех коментариев к колонкам для доступных таблиц и представлений
ALL_CONSTRAINTS - список всех внешних связей
ALL_DB_LINKS - дб линки достпные пользователю
ALL_ERRORS - недавние ошибки возникшие при создании хранимого объекта
ALL_INDEXES - индексы
ALL_IND_COLUMNS - колонки по индексам
ALL_LOBS - колоник по таблицам которые имеют тип LOB
ALL_OBJECTS - все доступные объекты
ALL_OBJECT_TABLES - все доступные таблицы
ALL_SEQUENCES - очереди
ALL_SNAPSHOTS - snapshot
ALL_SOURCE - код хранимых объектов
ALL_SYNONYMS - synonyms
ALL_TABLES - таблицы
ALL_TAB_COLUMNS - колонки для таблиц и представлений
ALL_TAB_COL_STATISTICS - статистика по обращениям к таблицам, представлениям
ALL_TAB_COMMENTS - коментарии к таблицам, представлениям
ALL_TRIGGERS - тригеры
ALL_TRIGGER_COLS - колонки таблиц используемые в тригерах
ALL_TYPES - типы
ALL_USERS - информация о пользователях
ALL_VIEWS - список представлений
DATABASE_COMPATIBLE_LEVEL - параметр совместимости бд, устанавливается в init.ora
DBA_DB_LINKS - все дб линки *
DBA_ERRORS - текущие ошибки при создании хранимых объектов
DBA_OBJECTS - все объекты в бд
DBA_ROLES- все существующие роли в бд
DBA_ROLE_PRIVS - все привилегии
DBA_SOURCE - исходные коды всех хранимых объектов
DBA_TABLESPACES - все пространства таблиц
DBA_TAB_PRIVS - все права доступа к таблицам
DBA_TRIGGERS - все тригеры
DBA_TS_QUOTAS - quotas
DBA_USERS - все пользователи
DBA_VIEWS- все представления
DICTIONARY - коментарии к таблицам и представлениям
DICT_COLUMNS - коментарии к колонкам таблиц и представлений
GLOBAL_NAME - глобальное имя бд
NLS_DATABASE_PARAMETERS - NLS параметры бд
NLS_INSTANCE_PARAMETERS - NLS параметры инстанса
NLS_SESSION_PARAMETERS - NLS параметры сессии
PRODUCT_COMPONENT_VERSION - версии компонентов продукта
ROLE_TAB_PRIVS - таблица привилегий по ролям
SESSION_PRIVS - доступные привилегии текущему пользователю
SESSION_ROLES - роли текущего пользователя
TABLE_PRIVILEGES - привилегии по таблицам
* Вероятно вы заметили что некоторые таблицы (точнее представления) имеют одинаковые названия, но разный префикс - DBA_ и ALL_
В чём же их отличия.
В представлении с префиксом ALL_ содержатся записи, которые доступны только текущему пользователю.
В представлении с префиксом DBA_ такого ограничения нет - тут содержатся абсолютно все записи, но зато к этому представлению имеют доступ только немногие привелигированные пользователи - с ролью SELECT_CATALOG_ROLE.
Итак, поехали в алфавитном порядке:
ALL_ARGUMENTS - список всех аргументов по объектам
ALL_CATALOG - список всех table, view, synonym, sequence доступных пользователю*
ALL_COL_COMMENTS - список всех коментариев к колонкам для доступных таблиц и представлений
ALL_CONSTRAINTS - список всех внешних связей
ALL_DB_LINKS - дб линки достпные пользователю
ALL_ERRORS - недавние ошибки возникшие при создании хранимого объекта
ALL_INDEXES - индексы
ALL_IND_COLUMNS - колонки по индексам
ALL_LOBS - колоник по таблицам которые имеют тип LOB
ALL_OBJECTS - все доступные объекты
ALL_OBJECT_TABLES - все доступные таблицы
ALL_SEQUENCES - очереди
ALL_SNAPSHOTS - snapshot
ALL_SOURCE - код хранимых объектов
ALL_SYNONYMS - synonyms
ALL_TABLES - таблицы
ALL_TAB_COLUMNS - колонки для таблиц и представлений
ALL_TAB_COL_STATISTICS - статистика по обращениям к таблицам, представлениям
ALL_TAB_COMMENTS - коментарии к таблицам, представлениям
ALL_TRIGGERS - тригеры
ALL_TRIGGER_COLS - колонки таблиц используемые в тригерах
ALL_TYPES - типы
ALL_USERS - информация о пользователях
ALL_VIEWS - список представлений
DATABASE_COMPATIBLE_LEVEL - параметр совместимости бд, устанавливается в init.ora
DBA_DB_LINKS - все дб линки *
DBA_ERRORS - текущие ошибки при создании хранимых объектов
DBA_OBJECTS - все объекты в бд
DBA_ROLES- все существующие роли в бд
DBA_ROLE_PRIVS - все привилегии
DBA_SOURCE - исходные коды всех хранимых объектов
DBA_TABLESPACES - все пространства таблиц
DBA_TAB_PRIVS - все права доступа к таблицам
DBA_TRIGGERS - все тригеры
DBA_TS_QUOTAS - quotas
DBA_USERS - все пользователи
DBA_VIEWS- все представления
DICTIONARY - коментарии к таблицам и представлениям
DICT_COLUMNS - коментарии к колонкам таблиц и представлений
GLOBAL_NAME - глобальное имя бд
NLS_DATABASE_PARAMETERS - NLS параметры бд
NLS_INSTANCE_PARAMETERS - NLS параметры инстанса
NLS_SESSION_PARAMETERS - NLS параметры сессии
PRODUCT_COMPONENT_VERSION - версии компонентов продукта
ROLE_TAB_PRIVS - таблица привилегий по ролям
SESSION_PRIVS - доступные привилегии текущему пользователю
SESSION_ROLES - роли текущего пользователя
TABLE_PRIVILEGES - привилегии по таблицам
* Вероятно вы заметили что некоторые таблицы (точнее представления) имеют одинаковые названия, но разный префикс - DBA_ и ALL_
В чём же их отличия.
В представлении с префиксом ALL_ содержатся записи, которые доступны только текущему пользователю.
В представлении с префиксом DBA_ такого ограничения нет - тут содержатся абсолютно все записи, но зато к этому представлению имеют доступ только немногие привелигированные пользователи - с ролью SELECT_CATALOG_ROLE.
Полезные запросы к системным таблицам
В системных таблицах оракл так много интересного и полезного. Поделюсь тем чем сам регулярно пользуюсь.
- Список всех оракловых объектов :
select * from all_objects /* where upper(object_name) like '%[NAME]%' and object_type in ('TABLE','VIEW') */;
- Список активных сессий и параметры подключённых пользователей к базе данных:
select sid, username, schemaname, osuser, machine, program,type from sys.V_$SESSION where status = 'ACTIVE';
- Список сессий находящихся в режиме ожидания :
select s.sid, s.username, s.schemaname, s.osuser, s.machine, s.program, s.type,
sw.event, sw.p1text, sw.seconds_in_wait, sw.wait_class,sw.state
from sys.V_$SESSION s, sys.V_$SESSION_WAIT sw
where s.sid = sw.sid
and s.status = 'ACTIVE';
- Последние выполненные запросы в базе:
select sql_text, sql_full_text from SYS.V_$SQL order by first_load_time desc; (первая колонка содержит только первую строку запроса, а вот во второй запрос представлен полностью.)
- SQL&PL/SQL код текущего пользователя в базе : скрипты создание всех таблиц, тригеров, процедур, пакетов и т.д. :
select * from sys.USER_SOURCE order by name , line
(форма представления конечно не слишком читабельная, но немного изменив вышеуказанный запрос можно легко найти где по всему коду встречается то или иное ключевое слово).
- Список всех оракловых объектов :
select * from all_objects /* where upper(object_name) like '%[NAME]%' and object_type in ('TABLE','VIEW') */;
- Список активных сессий и параметры подключённых пользователей к базе данных:
select sid, username, schemaname, osuser, machine, program,type from sys.V_$SESSION where status = 'ACTIVE';
- Список сессий находящихся в режиме ожидания :
select s.sid, s.username, s.schemaname, s.osuser, s.machine, s.program, s.type,
sw.event, sw.p1text, sw.seconds_in_wait, sw.wait_class,sw.state
from sys.V_$SESSION s, sys.V_$SESSION_WAIT sw
where s.sid = sw.sid
and s.status = 'ACTIVE';
- Последние выполненные запросы в базе:
select sql_text, sql_full_text from SYS.V_$SQL order by first_load_time desc; (первая колонка содержит только первую строку запроса, а вот во второй запрос представлен полностью.)
- SQL&PL/SQL код текущего пользователя в базе : скрипты создание всех таблиц, тригеров, процедур, пакетов и т.д. :
select * from sys.USER_SOURCE order by name , line
(форма представления конечно не слишком читабельная, но немного изменив вышеуказанный запрос можно легко найти где по всему коду встречается то или иное ключевое слово).
01 ноября 2008
Форма обратной связи
В блоге открыта обратной связи. Ваш вопрос немедленно будет доставлен непосредственно мне на почту.
Внимание, после отправки сообщения, вы будете переправлены на домашнюю страницу блога!!
Ваш вопрос/предложение/замечание:
Внимание, после отправки сообщения, вы будете переправлены на домашнюю страницу блога!!
31 октября 2008
DarkStar: разарботка MMORG ( онлайн игр ) на Java
Проект Darkstar это программное обеспечение, которое призвано упростить разработку и эксплуатацию массово масштабируемых онлайн игр(MMORG), виртуальных миров, и социальных сетей. Darkstar сам позаботиться об организации связей , обработке событий, слежением за целосностью данных и многое другое. Использование Darkstar вам позволит сконцентрироватся непосредственно на разработке игры.
И теперь главный плюс - это опен сорс проект, под GPL лицензией, так что вы можете получить его бесплатно. С использованием этого SDK разработка вашей игры может ускорится во много раз.
Так, расскажу немного о внутренностях. В целом это стандартный клиент сервер, который берёт на себя задачу управления. Основное понятие используемое в Darkstar проекте - это задача - Task. Любое действие можно описать с помощью задачи. Пример:
Атака (один игрок атакует - наносит удар другому игроку).
Итак происходит обращение к Task менеджеру с вызовом соотвующей задачи с указанными параметрами. TaskManager в свою очередь лезет в базу данных достаёт необходимые параметры (количество жизни у врага, мощность брони; мощность, ти оружия и т.д.) - за работу с базой данных отвечает PersistanceManager. На основе извлечённых данных производиться рассчёт силы удара и результат - нанесённое повреждение: опять обращение к PersistanceManager и сохранение в БД. Осталось разослать эту информацию игрокам участвующим в схватке - не проблема - TaskManager обращается к ChanelManagerу и обновлённые данные получают все игроки. Итак три слона держащие мир Darkstar это TaskManager , PersistanceManager и ChanelManagerу , можно и свой написать, но это только в очень искушённых проектах.
Подробности на сайте сообщества. Там много примеров, хорошая документация и всё что нужно для разработки.
Try it now.
Links:
About
Project Darkstar community
И теперь главный плюс - это опен сорс проект, под GPL лицензией, так что вы можете получить его бесплатно. С использованием этого SDK разработка вашей игры может ускорится во много раз.
Так, расскажу немного о внутренностях. В целом это стандартный клиент сервер, который берёт на себя задачу управления. Основное понятие используемое в Darkstar проекте - это задача - Task. Любое действие можно описать с помощью задачи. Пример:
Атака (один игрок атакует - наносит удар другому игроку).
Итак происходит обращение к Task менеджеру с вызовом соотвующей задачи с указанными параметрами. TaskManager в свою очередь лезет в базу данных достаёт необходимые параметры (количество жизни у врага, мощность брони; мощность, ти оружия и т.д.) - за работу с базой данных отвечает PersistanceManager. На основе извлечённых данных производиться рассчёт силы удара и результат - нанесённое повреждение: опять обращение к PersistanceManager и сохранение в БД. Осталось разослать эту информацию игрокам участвующим в схватке - не проблема - TaskManager обращается к ChanelManagerу и обновлённые данные получают все игроки. Итак три слона держащие мир Darkstar это TaskManager , PersistanceManager и ChanelManagerу , можно и свой написать, но это только в очень искушённых проектах.
Подробности на сайте сообщества. Там много примеров, хорошая документация и всё что нужно для разработки.
Try it now.
Links:
About
Project Darkstar community
25 октября 2008
Java презентации
Обнаружил тучу Java презентаций на сайте parleys.com . В презентациях охватывается большинство тем связанных с javа : от fundamentals до java ee фреймворков.
Взяты презентации из популярнейших Java конференций : JavaPolis, BeJUG, SpringOne, JaZoon, JavaZone and EclipseCon
У сайта есть также свой подкаст : parleys.libsyn.com где можно прослушать доклады по презентациям в mp3 формате.
Наслаждайтесь.
P.S. Всё оформлено очень красиво и по взрослому: в одном окне слайды презентации , во втором видно докладчика...как будто сам присутствуешь на конференции. Особенно удобное их десктоп приложение, которое скачивается на этом же сайте.
Взяты презентации из популярнейших Java конференций : JavaPolis, BeJUG, SpringOne, JaZoon, JavaZone and EclipseCon
У сайта есть также свой подкаст : parleys.libsyn.com где можно прослушать доклады по презентациям в mp3 формате.
Наслаждайтесь.
P.S. Всё оформлено очень красиво и по взрослому: в одном окне слайды презентации , во втором видно докладчика...как будто сам присутствуешь на конференции. Особенно удобное их десктоп приложение, которое скачивается на этом же сайте.
JAD : Java декомпилятор
Jad - java декомпилятор, программа которая читает один или больше Javaклассов и преобразует их в исходный код(по личной практике сообщу, чтокод получается почти такой же как и до компиляции), который можно будетповторно скомпилировать.
Jad написан на чистом С++, поэтому работает в несколько раз быстрее чем декомпиляторы написаны на Java.
Использовать просто:
jad example1.class
Но , jad по умолчанию выдает декомпилированным файлам расширение jad, что бы избежать этого , можно использовать опцию -s :
jad -sjava example1.class
Если надо декомпилировать набор классов, можно воспользоваться командой:
jad -o -r -sjava -dsrc tree/**/*.class
(**) - значит что декомпиляция будет производиться во всех поддиректориях папки tree.
JAD
Jad написан на чистом С++, поэтому работает в несколько раз быстрее чем декомпиляторы написаны на Java.
Использовать просто:
jad example1.class
Но , jad по умолчанию выдает декомпилированным файлам расширение jad, что бы избежать этого , можно использовать опцию -s :
jad -sjava example1.class
Если надо декомпилировать набор классов, можно воспользоваться командой:
jad -o -r -sjava -dsrc tree/**/*.class
(**) - значит что декомпиляция будет производиться во всех поддиректориях папки tree.
JAD
20 октября 2008
Spring Security : хранение пользователей в БД. часть 2
Предварительно прочитать:
SS: хранение пользователей в БД. часть 1
В этой части мы рассмотрим возможность объеденения ORM фреймворка (например hibernate) вместе со Spring Security. При этом будут использоваться аннотации.
Итак, lets go.
Если вы желаете хранить пользователей в своих таблицах, а не предлагаемых SS-ом и желаете обращатся к ним с помощью hibernate? тогда вам надо:
1) Реализовать интерфейс UserDetailsService, в котором аж одна функция loadUserByUsername. У меня этот интерфейс обращается к моим dao классам , с помощью которых и извлекает информацию о пользователях, например:
@Component
@Transactional
public class UserServiceImpl implements UserDetailsService {
@Autowired
UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
return userDao.get(username);
}
}
Особенность, обратите внимание , что функция loadUserByUsername возвращает не абы-шо , а некий объект UserDetails. Это между прочим тоже интерфейс.
2) Реализовать интерфейс UserDetails. SS рекомендует воспользоватся стандартным классом org.springframework.security.userdetails.User , в котором уже реализован этот интерфейс, но этот вариант далеко не всем подойдёт.
Если таки не подойдёт, надо реализовать несколько простых стандартных функций не представляющих большой интерес, аля: getUsername, getPassword, isEnabled, isCredentialsNonExpired, isCredentialsNonExpired, isAccountNonExpired. Причём последние 4 возвращают ложь или правду. Гораздо интересней функция getAuthorities(), а точнее то что она возвращает, а возвращает она массив GrantedAuthority... это между прочим тоже интерфейс, который нам придётся реализовывать :).
3) Реализовать интерфейс GrantedAuthority. Что это за интерфейс , и что это за единственная функция getAuthority() , которую надо реализовать? GrantedAuthority - это привилегия, роль, полномочие, ограничение которое получает пользователь на выполнение того или иного действия. Как задавать набор действий для каждой определённой роли в общем рассматривалось в первой заметке по SS , и более подробно будет рассматриватся в дальнейшем.
Основные используемые роли :
ROLE_ADMINISTRATOR, ROLE_USER, ROLE_SUPERVISOR, ROLE_WE_DONT_HAVE, ROLE_TELLER, ROLE_ANONYMOUS
Каждый пользователь может обладать не менее чем одной ролью. Поэтому в бд лучше всего иметь одну таблицу для данных пользователя и вторую для ролей. Первая таблица связана со второй в отношении один ко многим.
4) Последний штрих. Все классы написаны, осталось только настроить конфигурацию, для того, что-бы использовался нужный сервис получения пользователей. Это можно сделать в applicationContext-security.xml сделующим образом:
Регистрируем бин с классом реализующем UserDetailsService интерфейс:
<beans:bean id="myUserDetailsService" class="path.to.UserServiceImpl" />
В authentication-provider указываем какой сервис использовать для получения данных о пользователях:
<authentication-provider user-service-ref='myUserDetailsService'/>
Это всё.
SS: хранение пользователей в БД. часть 1
В этой части мы рассмотрим возможность объеденения ORM фреймворка (например hibernate) вместе со Spring Security. При этом будут использоваться аннотации.
Итак, lets go.
Если вы желаете хранить пользователей в своих таблицах, а не предлагаемых SS-ом и желаете обращатся к ним с помощью hibernate? тогда вам надо:
1) Реализовать интерфейс UserDetailsService, в котором аж одна функция loadUserByUsername. У меня этот интерфейс обращается к моим dao классам , с помощью которых и извлекает информацию о пользователях, например:
@Component
@Transactional
public class UserServiceImpl implements UserDetailsService {
@Autowired
UserDao userDao;
@Override
public UserDetails loadUserByUsername(String username)
throws UsernameNotFoundException, DataAccessException {
return userDao.get(username);
}
}
Особенность, обратите внимание , что функция loadUserByUsername возвращает не абы-шо , а некий объект UserDetails. Это между прочим тоже интерфейс.
2) Реализовать интерфейс UserDetails. SS рекомендует воспользоватся стандартным классом org.springframework.security.userdetails.User , в котором уже реализован этот интерфейс, но этот вариант далеко не всем подойдёт.
Если таки не подойдёт, надо реализовать несколько простых стандартных функций не представляющих большой интерес, аля: getUsername, getPassword, isEnabled, isCredentialsNonExpired, isCredentialsNonExpired, isAccountNonExpired. Причём последние 4 возвращают ложь или правду. Гораздо интересней функция getAuthorities(), а точнее то что она возвращает, а возвращает она массив GrantedAuthority... это между прочим тоже интерфейс, который нам придётся реализовывать :).
3) Реализовать интерфейс GrantedAuthority. Что это за интерфейс , и что это за единственная функция getAuthority() , которую надо реализовать? GrantedAuthority - это привилегия, роль, полномочие, ограничение которое получает пользователь на выполнение того или иного действия. Как задавать набор действий для каждой определённой роли в общем рассматривалось в первой заметке по SS , и более подробно будет рассматриватся в дальнейшем.
Основные используемые роли :
ROLE_ADMINISTRATOR, ROLE_USER, ROLE_SUPERVISOR, ROLE_WE_DONT_HAVE, ROLE_TELLER, ROLE_ANONYMOUS
Каждый пользователь может обладать не менее чем одной ролью. Поэтому в бд лучше всего иметь одну таблицу для данных пользователя и вторую для ролей. Первая таблица связана со второй в отношении один ко многим.
4) Последний штрих. Все классы написаны, осталось только настроить конфигурацию, для того, что-бы использовался нужный сервис получения пользователей. Это можно сделать в applicationContext-security.xml сделующим образом:
Регистрируем бин с классом реализующем UserDetailsService интерфейс:
<beans:bean id="myUserDetailsService" class="path.to.UserServiceImpl" />
В authentication-provider указываем какой сервис использовать для получения данных о пользователях:
<authentication-provider user-service-ref='myUserDetailsService'/>
Это всё.
Spring Security : хранение пользователей в БД. часть 1
В предыдущей заметке по Spring Security (SS) я рассмотрел пример использования SS. Пример был примитивный, ориентированный исключительно на знакомство с SS.
Теперь более подробно рассмотрим вопрос хранения данных о пользователях. В первом примере эти данные были забиты раз и навсегда в xml файл и как либо оперировать ними было невероятно трудно. Более привычный способ хранения пользователей - это база данных.
В SS реализован UserDetailsService, который позволяет получать информацию о пользователях посредством jdbc подключения к базе данных, для этого достаточно в конфигурации зарегистировать бин:
<bean id="userDetailsService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>
Где в качестве dataSource используется бин настроек подключения к бд, например:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
При это в базе данных должна существовать следующая схема: таблицы users и authorities, а также внешний ключ.
CREATE TABLE users (
username VARCHAR(50) NOT NULL PRIMARY KEY,
password VARCHAR(50) NOT NULL,
enabled BIT NOT NULL
);
CREATE TABLE authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL
);
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users(username);
В общем случае этот вариант вполен пригоден для использования, но что делать если вы используете какой то высокоуровневый фрэймворк, или если у вас уже есть свои таблицы для хранения пользователей... тогда читайте следующую заметку
Теперь более подробно рассмотрим вопрос хранения данных о пользователях. В первом примере эти данные были забиты раз и навсегда в xml файл и как либо оперировать ними было невероятно трудно. Более привычный способ хранения пользователей - это база данных.
В SS реализован UserDetailsService, который позволяет получать информацию о пользователях посредством jdbc подключения к базе данных, для этого достаточно в конфигурации зарегистировать бин:
<property name="dataSource" ref="dataSource"/>
</bean>
Где в качестве dataSource используется бин настроек подключения к бд, например:
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
При это в базе данных должна существовать следующая схема: таблицы users и authorities, а также внешний ключ.
CREATE TABLE users (
username VARCHAR(50) NOT NULL PRIMARY KEY,
password VARCHAR(50) NOT NULL,
enabled BIT NOT NULL
);
CREATE TABLE authorities (
username VARCHAR(50) NOT NULL,
authority VARCHAR(50) NOT NULL
);
ALTER TABLE authorities ADD CONSTRAINT fk_authorities_users foreign key (username) REFERENCES users(username);
В общем случае этот вариант вполен пригоден для использования, но что делать если вы используете какой то высокоуровневый фрэймворк, или если у вас уже есть свои таблицы для хранения пользователей... тогда читайте следующую заметку
18 октября 2008
Пример использования Spring Security в Web приложениях
Вступление
Не так давно Spring анонсировала свою новую разработку Spring Security. Это модуль для услуг безопасности, который должен заменить Acegi Security для всех Spring приложений.
Acegi очень популярный фреймворк для безопасности, обладающий обширной функциональностью:
- аутентификация и авторизация пользователей
- контроль доступа
Spring Security унаследовало всё лучшее от Acegi, а также обзавелось новыми фичами(features) :
- совместимость с OpenID, NTLM, LDAP аутентификация;
- поддержка аннотаций согласно стандарту JSR-250;
- упрощения в использовании;
- поддержка дополнительных языков;
и многие другие.
Пример
Что бы показать на сколько просто использовать Spring Security рассмотрим простой пример.
Для начала вам понадобиться любое простое Spring MVC веб приложение. В одном из более ранних постов я приводил примеры туториалов. Хотя, идеальной подойдёт пример petclinic , который поставляется в zip архиве spring-framework with dependencies.
Также нам понадобиться zip архив Spring Security 2.0.X , а точнее библиотеки из него.
Из которого надо в WEB-INF\lib скопировать следующие библиотеки:
spring-security-core-2.0.4.jar
spring-security-core-tiger-2.0.4.jar
spring-security-acl-2.0.4.jar
spring-security-taglibs-2.0.4.jar
И ещё одна библиотека от apache:
commons-codec-1.3.jar
Ещё необходимо создать конфигурационный файл для Spring Security в папке WEB-INF :
<!-- applicationContext-security.xml -->
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-2.0.1.xsd">
<!-- alot of config will be here -->
</beans:beans>
Шаг следующий - настройка web.xml , где мы должны подключить конфиг для Spring Security:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/applicationContext-security.xml
</param-value>
</context-param>
Здесь же в web.xml сразу после закрытия тега /context-param добавляем фильтр:
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
И последний шаг - настраиваем доступ к страницам, указываем для SpringSecurity на какие странице можно заходить анонимно, а на которые доступ получат только авторизированные пользователи. Добавляем в aplicationContext-security.xml следующий код:
<http auto-config="true">
<intercept-url pattern="/*.do" access="ROLE_USER" />
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" />
</http>
В этом же файле создадим парочку пользователей:
<authentication-provider>
<password-encoder hash="md5"/>
<user-service>
<user name="rod" password="a564de63c2d0da68cf47586ee05984d7" authorities="ROLE_SUPERVISOR, ROLE_USER, ROLE_TELLER" />
<user name="dianne" password="65d15fe9156f9c4bbffd98085992a44e" authorities="ROLE_USER,ROLE_TELLER" />
</user-service>
</authentication-provider>
Можно тестировать. Запускаем сервер и пытаемся открыть домашнюю страницу, ваш запрос должен быть перехвачен и вместо данных вывестись форма с предложением ввести свои данные. Вы можете попробовать ввести
логин: rod , пароль: koala
либо
логин: dianne , пароль: emu
и увидеть ожидаемую страницу.
Ещё не помешает добавить кнопку для выхода из аккаунта, лучше всего в шаблон, например в header :
<table class="header">
<tr>
<td><a href="<c:url value="/welcome.do"/>">Home</a></td>
<td align="right"><a href="<c:url value="/j_spring_security_logout"/>">Logout</a></td>
</tr>
</table>
Оригинал: статья 1 , статья 2.
17 октября 2008
Open Source - сборники народных сказок
Решил поискать в истории некоторые аналоги для "open source" и os сообщества. И такой аналог нашёлся - народный фольклор: песни, танцы, музыка, притчи, истории, баллады и многое другое то что народ копил многие годы, передавая от родителей к детям. И творили люди свои шедевры не за деньги, а потому что им по настоящему нравилось то что они делают. Гениальные произведения мало вероятно, что удастся найти среди народных, но много хорошего, приятного для души очень много. Хорошо что кроме творящих ещё находятся люди, которые собирают эти произведения воедино, только благодаря ним к нам доходят сборники сказок, притч, песен ... творчества народа.
В опен сорсе наблюдается кое что аналогичное, только вот слово народ заменили более модным "комьюнити". А сборники народного творчества в опен сорсе пользуются особой популярностью. И что-бы некоторым пост не показался абсолютно бесполезным, размещу ка я ссылки на такие народные опен-сорс сборники:
http://sourceforge.net/
http://koders.com/
http://code.google.com/
http://java2s.com/
http://java-source.net/
http://www.exampledepot.com/
http://www.planet-source-code.com/
http://www.codebeach.com/
http://www.osalt.com/
Ну, думаю достаточно.
P.S. Жаль только что в список не попал не один славянский сайт, хоть люди у нас далеко не последние творят , а получается как и с народным фольклором - за-рубежом считается что русская народная музыка - это хор Красной армии.
В опен сорсе наблюдается кое что аналогичное, только вот слово народ заменили более модным "комьюнити". А сборники народного творчества в опен сорсе пользуются особой популярностью. И что-бы некоторым пост не показался абсолютно бесполезным, размещу ка я ссылки на такие народные опен-сорс сборники:
http://sourceforge.net/
http://koders.com/
http://code.google.com/
http://java2s.com/
http://java-source.net/
http://www.exampledepot.com/
http://www.planet-source-code.com/
http://www.codebeach.com/
http://www.osalt.com/
Ну, думаю достаточно.
P.S. Жаль только что в список не попал не один славянский сайт, хоть люди у нас далеко не последние творят , а получается как и с народным фольклором - за-рубежом считается что русская народная музыка - это хор Красной армии.
16 октября 2008
Бесплатные тесты от Sun по Java
The following pre-assessments will assist you in determining whether you have acquired the knowledge taught in each of the Sun Microsystems' training courses listed below each pre-assessment. Sun offers each free pre-assessment to help you determine which course is best suited to your current level of skill and knowledge.
- Sun Certified Associate for the Java Platform, Standard Edition, Exam Version 1.0 (CX-310-019)
- Sun Certified Programmer for the Java 2 Platform, Standard Edition 5.0 (CX-310-055)
- Sun Certified Business Component Developer for the Java Platform, Enterprise Edition 5 (CX-310-091)
- Sun Certified Mobile Application Developer for the Java 2 Platform, Micro Edition, Version 1.0 (CX-310-110)
- Sun Certified Developer for Java Web Services (CX-310-220)
15 октября 2008
Динамический HTML список c использованием jQuery библиотеки
Допустим есть у вас html список (или таблица) с несколькими элементами , например:
<ul id="list_cheloveg">
<li id="174">
<a class="link_cheloveg" href="read.html?id=174">Andrej Vanjiradjan1</a>
<a class="dialog_edit" href="edit.html?id=174">Edit</a>
<a class="delete" href="delete.html?id=174">Del</a>
</li>
<li id="175">
<a class="link_cheloveg" href="read.html?id=175">Andrej Vanjiradjan2</a>
<a class="dialog_edit" href="edit.html?id=175">Edit</a>
<a class="delete" href="delete.html?id=175">Del</a>
</li>
<li id="176">
<a class="link_cheloveg" href="read.html?id=176">Andrej Vanjiradjan3</a>
<a class="dialog_edit" href="edit.html?id=176">Edit</a>
<a class="delete" href="delete.html?id=176">Del</a>
</li>
</ul>
И вам надо добавить в конец ещё один элемент , либо отредактировать какой то из существующих. Найболее часто такая задача встречается при отправке запросов через Ajax, и ответ как раз и должен обновить таблицу.
Из 10 статей найденых в гугл, 9 предлагают использувать функцию getElementById, и с помощью неё установить HTML код конкретного элемента, например:
document.getElementById("176").innerHTML = '<li id=177> <a class . и т.д. копи пастим весь html c новыми атрибутоами.. </a></li>';
способ достаточно простой, но очень не красивый, тем более если это не список, а таблица в которой больше 10 столбиков.
Библиотека jQuery, позволяет эту задачу выполнить гораздо элегантней.
Шаг 1. скачиваем библиотеку и подключаем к странице:
<script type="text/javascript" src="jquery.js"></script>
Шаг 2.пишем javascript функцию, которая будет получать новые аттрибуты, обрабатывать их и обновлять таблицу.
Например, в моём случае список - это люди: уникальный id, имя и фамилия:
<script type="text/javascript">
function updateList(id,firstName,lastName) {
var oldId = $('#list_cheloveg li').attr('id');
var oldText = $('#list_cheloveg li:last .link_cheloveg').text();
var oldHtml = $('#list_cheloveg li:last').html();
for (i=0;i<3;i++) { // id used 3 times in row
oldHtml = oldHtml.replace(''+oldId,''+id);
}
oldHtml = oldHtml.replace(oldText,firstName + ' ' + lastName);
var newHtml = '<li id=' + id + '>' + oldHtml + '</li>';
if ( document.getElementById(id) == null ) {
$('#list_cheloveg').append(newHtml);
} else {
document.getElementById(id).innerHTML=newHtml;
}
}
</script>
Что же делает эта функция? Она выбирает последнюю строку(последниц элемент списка) из таблицы,
создаёт 3 переменных, в которых сохраняет уникальный id, имя+фамилию , и старый html код который мы будем редактировать.
Панализировав список, можно увидеть, что нам надо заменить 3 раза уникальный id и один раз имя+фамилия. Это мы и сделали с помощью стандартной функции replace. Далле мы проверяем весь документ и исчем запись с новым id , если не находим, значит добавляем элемент в конец списка, как новую строку, если находим значит заменяем его.
Протестировать єтот пример можно с помощью двух ссылок:
<a href=# onclick="updateList(194,'textA','textB');">add</a>
<a href=# onclick="updateList(174,'textAA','textBB');">update</a>
P.s. Если скопируете весь html код из этого сообщения в один файл , и сохраните его в какую то папку, и в эту же папку добавите jQuery библиотеку jquery.js , то сможете успешно протестировать то что я описал в посте.
Получение в Java коде номер строки и имя выполняемого файла
Во время отладки приложения наиболее часто используется вывод с помощью System.out.println(). Иногда, приходиться добавлять достаточно большое количество таких выводов, что бы понять процесс выполнения приложения и для каждого из выводов надо придумывать свой уникальный текст, что бы потом по тексту найти нужное место в коде.
А что если выводить на экран имя файла, метода и номер строки который в данный момент выполняется. Это автоматически обеспечит уникальные сообщения для каждого вывода System.out , а также позволит легко и быстро размножать такие выводы в коде. Вывод будет выглядеть приблизительно так:
System.out.println(getCodePoint());
Но самое интересное будет происходить в методе getCodePoint его можно сделать общим и статическим в каком то классе утилит , содержимое его будет следующим:
public static String getCodePoint() {
StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
return ste.getFileName() + ":" +
ste.getClassName() + ":" +
ste.getMethodName() + ":" +
ste.getLineNumber();
}
Магия и ничего более :).
А что если выводить на экран имя файла, метода и номер строки который в данный момент выполняется. Это автоматически обеспечит уникальные сообщения для каждого вывода System.out , а также позволит легко и быстро размножать такие выводы в коде. Вывод будет выглядеть приблизительно так:
System.out.println(getCodePoint());
Но самое интересное будет происходить в методе getCodePoint его можно сделать общим и статическим в каком то классе утилит , содержимое его будет следующим:
public static String getCodePoint() {
StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
return ste.getFileName() + ":" +
ste.getClassName() + ":" +
ste.getMethodName() + ":" +
ste.getLineNumber();
}
Магия и ничего более :).
14 октября 2008
Как получить состояние любого локального / удалённого java процесса
Данная задача является особенно актуальной для серверной части, где у вас на одной машине может в фоновом режиме выполнятся несколько Java процессов.
Для того что бы определить как выполняется определённый процесс надо знать его pid (process Id). Вы можете получить его из диспечера задач (в windows) , команд ps или top в линуксе, но поиски этим методом могут занять не мало времени.
Существует специальная команда, получающая список всех работающих процессов на определённой JVM :
$JAVA_HOME/bin/jps
Первая колонка - это и есть pid запущенных Java процессов.
C помощью следующей команды мы сможем получить stacktrace (характеристику текущего состояния) всех запущенных процессов, либо определённого процеса :
$JAVA_HOME/bin/jstack [pid]
Для того что бы определить как выполняется определённый процесс надо знать его pid (process Id). Вы можете получить его из диспечера задач (в windows) , команд ps или top в линуксе, но поиски этим методом могут занять не мало времени.
Существует специальная команда, получающая список всех работающих процессов на определённой JVM :
$JAVA_HOME/bin/jps
Первая колонка - это и есть pid запущенных Java процессов.
C помощью следующей команды мы сможем получить stacktrace (характеристику текущего состояния) всех запущенных процессов, либо определённого процеса :
$JAVA_HOME/bin/jstack [pid]
GWT & Spring MVC & Hibernate(JPA). Web приложения из 3х частей
Нашёл интересный пример (аля туториал) как собирать веб приложение в связке : GWT + Spring + Hibernate c JPA .
Пример достаточно прост , но довольно подробный. Разработка приложения разбита на 3 части.
Первая часть. Создаём в нашей IDE GWT проект. Создаём нужные конфиг файлы, пишем GWT код , и компилируем в две JavaScript библиотеки.
Вторая часть. Создаём Spring MVC + Hibernate проект. MVC приложение - создаём нужные конфиг файлы, контроллеры, представления. Интегрируем библиотеки из части 1 в проект.
Часть 3. Создаём классы по работе с БД. Используем Hibernate проект с JPA аннотациями.
Повторюсь, всё расписано очень подробно , код полностью предоставлен, в коде достаточно много коментариев.
Я сам этот проект в кучу не собирал, просто из за банального отсутствия времени, хотя интересно было бы попробовать.
туториал смотреть тут (язык англ.)
Пример достаточно прост , но довольно подробный. Разработка приложения разбита на 3 части.
Первая часть. Создаём в нашей IDE GWT проект. Создаём нужные конфиг файлы, пишем GWT код , и компилируем в две JavaScript библиотеки.
Вторая часть. Создаём Spring MVC + Hibernate проект. MVC приложение - создаём нужные конфиг файлы, контроллеры, представления. Интегрируем библиотеки из части 1 в проект.
Часть 3. Создаём классы по работе с БД. Используем Hibernate проект с JPA аннотациями.
Повторюсь, всё расписано очень подробно , код полностью предоставлен, в коде достаточно много коментариев.
Я сам этот проект в кучу не собирал, просто из за банального отсутствия времени, хотя интересно было бы попробовать.
туториал смотреть тут (язык англ.)
13 октября 2008
Интернационализация и локализация в Spring MVC
Интерфейс ApplicationContext расширяет интерфейс называемый MessageSource , который предоставляет функциональность по интернационализации приложений. (Подробней)
Существует две реализации описанного интерфейса : StaticMessageSource и
ResourceBundleMessageSource . Если быть точнее они реализуют не сам MessageSource, а его дочерний класс HierarchicalMessageSource, который кроме прочего позволяет иерархически обрабатывать сообщения.
StaticMessageSource - тяжёлый в использовании, но позволяющий програмно добавлять сообщения в список заготовленных сообщений, что далеко не всегда нужно.
ResourceBundleMessageSource рассмотрим болле подробно с помощью примера:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
</list>
</property>
</bean>
Тут мы зарегистрировали бин, который будет искать messages в двух файлах:
format.properties
errors.properties
Это файлы используемые по умолчанию, но если в вашем броузере установлена какая то специфическая локализация ,
то сначала будут искатся файлы характерные для этой локализации ,
например для украинского языка:
format_uk.properties
errors_uk.properties
для немецкого
format_de.properties
errors_de.properties
и так далее ..
Все выше перечисленные файлы необходимо разместить в CLASSPATH.
В каждом из файлов в столбик записаны код сообщения и их значения для определённого языка.
Например
# в файле 'format.properties'
message=Hello world message!
Или пример по сложнее:
# в файле 'errors_uk.properties'
argument.required=Поле '{0}' є обов`язковим для заповнення
Для того что бы вывести эти сообщения на jsp странице используется тег spring:message .
В результате получаем вполне понятное сообщение об ошибке для украинской локализации:
Пример из файла error_uk :
Поле Address є обов`язковим для заповнення
Существует две реализации описанного интерфейса : StaticMessageSource и
ResourceBundleMessageSource . Если быть точнее они реализуют не сам MessageSource, а его дочерний класс HierarchicalMessageSource, который кроме прочего позволяет иерархически обрабатывать сообщения.
StaticMessageSource - тяжёлый в использовании, но позволяющий програмно добавлять сообщения в список заготовленных сообщений, что далеко не всегда нужно.
ResourceBundleMessageSource рассмотрим болле подробно с помощью примера:
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames">
<list>
<value>format</value>
<value>exceptions</value>
</list>
</property>
</bean>
Тут мы зарегистрировали бин, который будет искать messages в двух файлах:
format.properties
errors.properties
Это файлы используемые по умолчанию, но если в вашем броузере установлена какая то специфическая локализация ,
то сначала будут искатся файлы характерные для этой локализации ,
например для украинского языка:
format_uk.properties
errors_uk.properties
для немецкого
format_de.properties
errors_de.properties
и так далее ..
Все выше перечисленные файлы необходимо разместить в CLASSPATH.
В каждом из файлов в столбик записаны код сообщения и их значения для определённого языка.
Например
# в файле 'format.properties'
message=Hello world message!
Или пример по сложнее:
# в файле 'errors_uk.properties'
argument.required=Поле '{0}' є обов`язковим для заповнення
Для того что бы вывести эти сообщения на jsp странице используется тег spring:message .
В результате получаем вполне понятное сообщение об ошибке для украинской локализации:
Пример из файла error_uk :
Поле Address є обов`язковим для заповнення
10 октября 2008
UKраина или UnitedKingdom. Правильная локализация
Каждый современный браузер предоставляет возможность выбрать язык по умолчанию или даже несколько языков, и проставить среди них приоритеты.
В FF это можно сделать с помощью меню Инструменты - Настройка - Содержимое - Языки - Выбрать.
В Опере - Инструменты - Настройки - Языки - Настройки
В ИЕ : Свойства обозревателя - Общие - Языки
В общем то ничего необычного, удобно и практично. Но это предистория, фишка в другом. Доменные имена для страны Украина заканчиваются на .UA, на номерах присутствуют буквы UA.
Так почему же в настройках локализации, сокращение для украинской локализации UK ? Мне не понятно. Видимо в разработке этого стандарта из Украины никто не участвовал , да из Великобритании тоже.
P.S. Возможно некоторым этот пост показался глупостью, не имеющим значения. Но это не так, почему это не так, я опишу в одном из следующих сообщений где буду рассказывать как происходит локализациия приложений в современных веб фрэймворках, в частности в Spring Framework.
В FF это можно сделать с помощью меню Инструменты - Настройка - Содержимое - Языки - Выбрать.
В Опере - Инструменты - Настройки - Языки - Настройки
В ИЕ : Свойства обозревателя - Общие - Языки
В общем то ничего необычного, удобно и практично. Но это предистория, фишка в другом. Доменные имена для страны Украина заканчиваются на .UA, на номерах присутствуют буквы UA.
Так почему же в настройках локализации, сокращение для украинской локализации UK ? Мне не понятно. Видимо в разработке этого стандарта из Украины никто не участвовал , да из Великобритании тоже.
P.S. Возможно некоторым этот пост показался глупостью, не имеющим значения. Но это не так, почему это не так, я опишу в одном из следующих сообщений где буду рассказывать как происходит локализациия приложений в современных веб фрэймворках, в частности в Spring Framework.
09 октября 2008
Spring MVC. Преобразование данных
Spring MVC: Failed to convert property value of type [java.lang.String] to required type ...
Вот такую ошибку вы получите если захотите создать html форму с текстовым полем , а пожелаете сохранить этот текст, в класс Date (например).
Сделать это можно с помощью следующего кода
Контроллер:
//...
setupFormWithDate(ModelMap model){
java.util.Date nowDate = new Date(System.currentTimeMillis());
model.addAttribute("someDate",nowDate);
return "form";
}
//...
Представление:
<!-- ... -->
<form:input path="${someDate}" />
<!-- ... -->
Решается такая проблема довольно просто. При инициализации необходимо рассказать спрингу как реагировать на поля в которых мы вводим данные типа дата.
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
В SpringFramework существует специальный класс CustomDateEditor , в котором реализована логика преобразования нашего объекта типа Date в строку и наоборот. Первый параметр в конструкторе CustomDateEditor формат представления даты как строки, в нешем случае год-месяц-день. Этот класс позаботиться что-бы nowDate из первого примера, преобразовался в
указанный формат и вывелся на форму, при отправке формі на сервер, текстовое значение поля someDate будет также обрабатывать класс CustomDateEditor и преобразует его в правильную дату.
Второй параметр определяет допускаются ли пустые значения в этом поле.
Более сложный вариант, когда мы хотим вывести в текстовое (либо другое) поле значение, которое не принадлежит к классу созданному нами.
Например у нас есть класс Address:
class Address {
int zip;
String country;
String region;
String city;
String street;
String house;
int floor;
int flat;
public String toString(){
return ""+zip+":"+country+":"+region // + ...
}
}
и есть класс User у которого есть домашний и рабочий адреса. Предположим, что выделять 16 полей на форме под адресса мы не хотим, потому что они будут занимать слишком много места.
Не проблема, создадим 2 поля, назовём их workAddress и homeAddress.
Теперь нам нужен некий Custom Editor, который будет знать как преобразовывать из тектового значения в класс Address и наоборот.
Так как стандартного такого для нашего класса нет и не будет, то создадим свой. Этот класс должен расширять java.beans.PropertyEditorSupport и перегрузить один из его методов , а именно : setAsText. Назовём наш редактор : AddressPropertyEditor.
P.s. обратите внимание, в классе Address я уже создал стандартный метод (toString) , который преобразует объект Address в строку, где все члены разделены двоеточием. Но это же можно было сделать и в классе AddressPropertyEditor, с помощью перегрузки метода getAsText.
Наш редактор свойств будет выглядеть приблизительно так:
class AddressPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) {
Address address;
// начало логики преобразования из строки в Address
// TODO text.split(':')
// check if text is correct , throw exceptions if it's not
// TODO address set properies
// конец логики преобразования из строки в Address
setValue(address); // устнавливаем значения типа Address
}
Остался последний штрих. По аналогии с регистрацией CustomDateEditor, надо зарегистировать редактор для преобразования нашего адресса:
@InitBinder
//...
binder.registerCustomEditor(Address.class, new AddressPropertyEditor());
P.s. Пример с адресом я выбрал конечно яркий, но не реальный.
Другой хороший пример(который я только что придумал).
В одно текстовое поле добавляется List<String> - список текстовых значений. Например список тегов к сообщению в блоге вводиться именно таким образом.
Вот такую ошибку вы получите если захотите создать html форму с текстовым полем , а пожелаете сохранить этот текст, в класс Date (например).
Сделать это можно с помощью следующего кода
Контроллер:
//...
setupFormWithDate(ModelMap model){
java.util.Date nowDate = new Date(System.currentTimeMillis());
model.addAttribute("someDate",nowDate);
return "form";
}
//...
Представление:
<!-- ... -->
<form:input path="${someDate}" />
<!-- ... -->
Решается такая проблема довольно просто. При инициализации необходимо рассказать спрингу как реагировать на поля в которых мы вводим данные типа дата.
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
В SpringFramework существует специальный класс CustomDateEditor , в котором реализована логика преобразования нашего объекта типа Date в строку и наоборот. Первый параметр в конструкторе CustomDateEditor формат представления даты как строки, в нешем случае год-месяц-день. Этот класс позаботиться что-бы nowDate из первого примера, преобразовался в
указанный формат и вывелся на форму, при отправке формі на сервер, текстовое значение поля someDate будет также обрабатывать класс CustomDateEditor и преобразует его в правильную дату.
Второй параметр определяет допускаются ли пустые значения в этом поле.
Более сложный вариант, когда мы хотим вывести в текстовое (либо другое) поле значение, которое не принадлежит к классу созданному нами.
Например у нас есть класс Address:
class Address {
int zip;
String country;
String region;
String city;
String street;
String house;
int floor;
int flat;
public String toString(){
return ""+zip+":"+country+":"+region // + ...
}
}
и есть класс User у которого есть домашний и рабочий адреса. Предположим, что выделять 16 полей на форме под адресса мы не хотим, потому что они будут занимать слишком много места.
Не проблема, создадим 2 поля, назовём их workAddress и homeAddress.
Теперь нам нужен некий Custom Editor, который будет знать как преобразовывать из тектового значения в класс Address и наоборот.
Так как стандартного такого для нашего класса нет и не будет, то создадим свой. Этот класс должен расширять java.beans.PropertyEditorSupport и перегрузить один из его методов , а именно : setAsText. Назовём наш редактор : AddressPropertyEditor.
P.s. обратите внимание, в классе Address я уже создал стандартный метод (toString) , который преобразует объект Address в строку, где все члены разделены двоеточием. Но это же можно было сделать и в классе AddressPropertyEditor, с помощью перегрузки метода getAsText.
Наш редактор свойств будет выглядеть приблизительно так:
class AddressPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) {
Address address;
// начало логики преобразования из строки в Address
// TODO text.split(':')
// check if text is correct , throw exceptions if it's not
// TODO address set properies
// конец логики преобразования из строки в Address
setValue(address); // устнавливаем значения типа Address
}
Остался последний штрих. По аналогии с регистрацией CustomDateEditor, надо зарегистировать редактор для преобразования нашего адресса:
@InitBinder
//...
binder.registerCustomEditor(Address.class, new AddressPropertyEditor());
P.s. Пример с адресом я выбрал конечно яркий, но не реальный.
Другой хороший пример(который я только что придумал).
В одно текстовое поле добавляется List<String> - список текстовых значений. Например список тегов к сообщению в блоге вводиться именно таким образом.
08 октября 2008
File Uploading with Spring Framework
Наверное ни один веб портал не может обойтись без такой операции как загрузка файлов на сервер.
Особенно актуальная єта задача для больших веб приложений, которые разрабатываются в основном на java ee.
В этой заметке я рассмотрю как осуществляется аплоад файлов при использовании Spring фрэймоврка 2.5 (с использованием аннотаций).
Сначала нам необходимо зарегистрировать специальный бин - MultipartResolver, который будет сканировать все запросы к серверу и искать формы с типом multipart (т.е. с файлом для загрузки на сервер). Если такая форма найдётся этот бин передаст её для дальнейшей специальной обработки в сервлет MultipartHttpServletRequest, который и закачает наш файл.
<!-- MultipartResolver for parsing file uploads, implementation for Commons FileUpload -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
Всё это Spring сам делать не умеет, но хорошо это умеет делать Apache Commons FileUpload,
функциональность которого и вызывается через Spring Framework. Так что необходимо подключить commons-fileupload.jar и commons-io.jar библиотеки.
Настройка завершена, теперь код.
Создаём jsp страничку с multipart формой и единственным параметром file типа file. Назовём её например uploadFile.jsp:
<form action="uploadFile.html" method="post" encType="multipart/form-data">
<tr>
<td>Content</td>
<td><input type="file" name="file"><br></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Upload file"></td>
</tr>
</form>
Создаём класс контроллера.
Нам необходимо обрабатывать минимум 2 запроса. Первый - для отображения формы, через которую будет производиться загрузка файла, второй для обработки непосредственной загрузки файла (submit формы).
Например:
@Controller
class UploadController {
@RequestMapping(value = "/file.html", method = RequestMethod.GET)
public String setupUploadFile(){
return "uploadFile";
}
@RequestMapping(value = "/uploadFile.html")
public String processUploadPreview(
@RequestParam("file") MultipartFile file
){
// Сохраняем файл на диск...
// Содержание загруженного файла можно получить с помощь:
// file.getInputStream()
// имя и расширения файла можно извлечь из свойств
// file.getName() , file.getContentType()
return "redirect:index.html";
}
}
Это всё. Можно переходить к тестированию.
Особенно актуальная єта задача для больших веб приложений, которые разрабатываются в основном на java ee.
В этой заметке я рассмотрю как осуществляется аплоад файлов при использовании Spring фрэймоврка 2.5 (с использованием аннотаций).
Сначала нам необходимо зарегистрировать специальный бин - MultipartResolver, который будет сканировать все запросы к серверу и искать формы с типом multipart (т.е. с файлом для загрузки на сервер). Если такая форма найдётся этот бин передаст её для дальнейшей специальной обработки в сервлет MultipartHttpServletRequest, который и закачает наш файл.
<!-- MultipartResolver for parsing file uploads, implementation for Commons FileUpload -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
Всё это Spring сам делать не умеет, но хорошо это умеет делать Apache Commons FileUpload,
функциональность которого и вызывается через Spring Framework. Так что необходимо подключить commons-fileupload.jar и commons-io.jar библиотеки.
Настройка завершена, теперь код.
Создаём jsp страничку с multipart формой и единственным параметром file типа file. Назовём её например uploadFile.jsp:
<form action="uploadFile.html" method="post" encType="multipart/form-data">
<tr>
<td>Content</td>
<td><input type="file" name="file"><br></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Upload file"></td>
</tr>
</form>
Создаём класс контроллера.
Нам необходимо обрабатывать минимум 2 запроса. Первый - для отображения формы, через которую будет производиться загрузка файла, второй для обработки непосредственной загрузки файла (submit формы).
Например:
@Controller
class UploadController {
@RequestMapping(value = "/file.html", method = RequestMethod.GET)
public String setupUploadFile(){
return "uploadFile";
}
@RequestMapping(value = "/uploadFile.html")
public String processUploadPreview(
@RequestParam("file") MultipartFile file
){
// Сохраняем файл на диск...
// Содержание загруженного файла можно получить с помощь:
// file.getInputStream()
// имя и расширения файла можно извлечь из свойств
// file.getName() , file.getContentType()
return "redirect:index.html";
}
}
Это всё. Можно переходить к тестированию.
Аспектно ориентированное программирование: Основы
В своём блоге Антон Наумов подробно рассказывает о основах АОП и принципах его применения вместе со Spring Framework. link
Если этого вам оказалось мало, более развёрнутый взгляд на AOP можно услышать в интервью с исследователями из Siemens (Christa Schwanninger & Iris Groher ) : link2
Если этого вам оказалось мало, более развёрнутый взгляд на AOP можно услышать в интервью с исследователями из Siemens (Christa Schwanninger & Iris Groher ) : link2
We discuss the fundamentals of AOP, define many of the relevant termsP.s. если вы не поняли что написано выше, на ссылку2 нет смысла нажимать, интервью на англ. языке.
and also look at how and where AOP is used in practice, as well as at
some current research trends.
06 октября 2008
Java подкасты
Теперь скучать во время поездок в транспорте любителям Java не придётся. Вашему вниманию предоставляется список подкастов, которые могут быть интересны Java программисту.
The Art of programming - подкаст о программировании на русском языке, много внимание уделяется Java и сопутствующим технологиям.
Java Posse - известнейший Java подкаст на англ. языке, уже более 200 выпусков.
ZDot podcast - ещё один подкаст на англ. языке посвящённый в основном Java EE технологиям (есть несколько интересных выпусков по JSF и hibernate).
JavaOne podcast - подкаст на англ. языке посвящённый конференции JavaOne
Радио-Т - подкаст на русском языке об ИТ в целом, тут можно услышать достаточно проффесиональный взгляд на новинки технического мира.
The Art of programming - подкаст о программировании на русском языке, много внимание уделяется Java и сопутствующим технологиям.
Java Posse - известнейший Java подкаст на англ. языке, уже более 200 выпусков.
ZDot podcast - ещё один подкаст на англ. языке посвящённый в основном Java EE технологиям (есть несколько интересных выпусков по JSF и hibernate).
JavaOne podcast - подкаст на англ. языке посвящённый конференции JavaOne
Радио-Т - подкаст на русском языке об ИТ в целом, тут можно услышать достаточно проффесиональный взгляд на новинки технического мира.
05 октября 2008
Поиск обновлён
Строка поиска размещённая на этом сайте в колонке справа теперь ищет только по ресурсам имеющим непосредственное отношение к Java и сопутствующим технологиям. Список сайтов постоянно обновляется.
P.s. Если хотите что-бы и ваш сайт/блог попал в избранный список, пишите об этом в комментариях.
P.s. Если хотите что-бы и ваш сайт/блог попал в избранный список, пишите об этом в комментариях.
01 октября 2008
Разместить баннер бесплатно!
Если вы владелец информационного ресурса, каким либо образом связанного с ИТ в целом и с программированием (java) в частности, я готов разместить ссылку или красивый баннер на ваш сайт в своём блоге, причём совершенно безвозмездно, тоесть даром. Пишите.
22 сентября 2008
Программировать весело. Утилиты для знакомства с Java
В этой заметке расскажу о двух утилитах, которые помогут начинающим программистам познакомиться с Объектно ориентированным программированием в целом и с Java в частности.
Первая утилитка - Greenfoot. Предназначена для школьников средних и старших классов. Программа делает программирование весёлой забавой. В ней вы можете создать простенькое 2D приложение с помощью красивого и удобного графического интерфейса. С большой вероятностью она породит интерес к программированию даже у тех детей, которые раньше им не увлекались.
Более подробный Greenfoot туториал на английском языке.
BlueJ - интегрированная Java среда разработки для студентов ВУЗов, которые только начали изучать Java. Основной упор в утилите сделан на построение ООП приложения. C помощью BlueJ вы познакомитись с понятиями объекта, метода, поля. BlueJ предоставляет простой графический интерфейс для построение диаграммы классов. Также в приложение встроен редактор кода, компилятор, дебаггер и даже виртуальная машина для тестирования вашего приложения.
Подробный туториал на русском языке по BlueJ

Перед запуском перечисленных программ не забудьте скачать и установить J2SE 5 либо 6 версию.
Первая утилитка - Greenfoot. Предназначена для школьников средних и старших классов. Программа делает программирование весёлой забавой. В ней вы можете создать простенькое 2D приложение с помощью красивого и удобного графического интерфейса. С большой вероятностью она породит интерес к программированию даже у тех детей, которые раньше им не увлекались.
Более подробный Greenfoot туториал на английском языке.
BlueJ - интегрированная Java среда разработки для студентов ВУЗов, которые только начали изучать Java. Основной упор в утилите сделан на построение ООП приложения. C помощью BlueJ вы познакомитись с понятиями объекта, метода, поля. BlueJ предоставляет простой графический интерфейс для построение диаграммы классов. Также в приложение встроен редактор кода, компилятор, дебаггер и даже виртуальная машина для тестирования вашего приложения.
Подробный туториал на русском языке по BlueJ

Рис.1 BlueJ
Перед запуском перечисленных программ не забудьте скачать и установить J2SE 5 либо 6 версию.
Десктоп приложение со встроенной БД
Patrick Keegan подробно рассказывает как создать своё приложение со встроенной базой данных, в качестве среды разработки выбран NetBeans, в качестве базы данных Derby.
продолжение на английском...
продолжение на английском...
19 сентября 2008
Анализатор Java объектов
Когда код приложения превышает 100 тысяч строк, разобраться самостоятельно в чужом приложении будет затруднительно.
Objectreferenceanalyser (ORA) графическая утилита позволяющая :
- Рассмотреть архитектуру анализируемого приложения;
- Обнаружить ошибки или недочёты в архитектуре приложения;
- Обнаружить и предотвратить утечки памяти тем самім повісив производительность приложения;
- Увидеть зависимость между объектами/модулями в приложении.

Для того что бы увидеть демо пример, вам достаточно скачать приложение и запустить его.
Если же вы захотите протестировать свой код с помощью ORA, вам придётся найти ключевое место в своей программе - точка входа , где все объекты уже проинициализированны и созданы. Найти корневой класс/объект опираясь на который вы желаете произвести анализ и добавить три строчки в свой код:
//1. You have to instantiate a Analyser: AnalyserInterface ref = new ObjectReferencesCore("SomeIdentifier"); //2. You have to pass the to be analysed root object to the analyzer (mostly you pass some main components which hold important data): ref.addAndAnalyseRootObject(MyRootObject); //3. You have to start the visualizer to be able to see something new Visualizer(ref).start();
Более подробное описание и способы применения на страничке программы:
http://refanalyse.sourceforge.net/
Objectreferenceanalyser (ORA) графическая утилита позволяющая :
- Рассмотреть архитектуру анализируемого приложения;
- Обнаружить ошибки или недочёты в архитектуре приложения;
- Обнаружить и предотвратить утечки памяти тем самім повісив производительность приложения;
- Увидеть зависимость между объектами/модулями в приложении.

Для того что бы увидеть демо пример, вам достаточно скачать приложение и запустить его.
Если же вы захотите протестировать свой код с помощью ORA, вам придётся найти ключевое место в своей программе - точка входа , где все объекты уже проинициализированны и созданы. Найти корневой класс/объект опираясь на который вы желаете произвести анализ и добавить три строчки в свой код:
//1. You have to instantiate a Analyser: AnalyserInterface ref = new ObjectReferencesCore("SomeIdentifier"); //2. You have to pass the to be analysed root object to the analyzer (mostly you pass some main components which hold important data): ref.addAndAnalyseRootObject(MyRootObject); //3. You have to start the visualizer to be able to see something new Visualizer(ref).start();
Более подробное описание и способы применения на страничке программы:
http://refanalyse.sourceforge.net/
18 сентября 2008
Sametime Risk. Java стратегия
Sametime Risk
Жанр: стратегияМультиплеер: присутствует
Лицензия: бесплатно
Графика: 4/10
Играбельность: 9/10
Стратегия с простенькой графикой написанная полностью на Java. Целью игры является захват мира.
Изначально Земля пропорционально разделяется между всеми игроками. А дальше начинается самое интересное.
Каждый игрок поочерёдно ходит и пытается захватить территории соперника. Захват может осуществляться если на вашей территории больше 1 единицы войск. Как и в реальной войне, так и в этой игре имеет место случай. Но больше рассказывать не буду. Скачивайте бесплатно игрушку с SourceForge и наслаждайтесь замечательным гэймплеем.
22 августа 2008
Tips! События в Java FX
Рассмотрим следующий кусочек кода :
Ellipse
{
centerX: 10, centerY: 10
radiusX: 150, radiusY: 50
stroke: Color.GREEN
onMouseClicked: function( e: MouseEvent ):Void { // (1)do smth ... }
Если добавить этот код во Frame, будет нарисован эллипс с зелёным ободком, а при нажатии на него клавишей мыши выполниться некоторое действие (1). Но есть существенное НО : нажимать надо не в эллипс , а исключительно на зелёный ободок , что - бы что то произошло. Понятно, что это очень не удобно. Исправить данную "фичу" можно довольно просто:
Ellipse {
centerX: 10, centerY: 10
radiusX: 150, radiusY: 50
stroke: Color.GREEN
fill: Color.WHITE
onMouseClicked: function( e: MouseEvent ):Void { // (1)do smth ... }
Как видите я просто заполнил эллипс белой краской , визуально ничего не изменилось, но все собітия onMouseXxxx будут теперь отрабатывать не только для оботка, но и для всего эллипса.
Следующий рабочий пример, позволит легче усвоить данный урок.
import javafx.application.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;
import javafx.input.*;
var Rad:Integer = 10;
Frame {
title: "Test onMouseXx application"
width: 200 height: 200
closeAction: function() {
java.lang.System.exit( 0 );
}
visible: true
stage: Stage
{
content: [
Circle
{
centerX: 100, centerY: 100
radius: bind Rad stroke: Color.GREEN //fill: Color.WHITE onMouseClicked:
function( e: MouseEvent ):Void {
if (Rad == 50)
{ Rad = 10; }
else
{ Rad = 50; }
}
}
]
}
}
Ellipse
{
centerX: 10, centerY: 10
radiusX: 150, radiusY: 50
stroke: Color.GREEN
onMouseClicked: function( e: MouseEvent ):Void { // (1)do smth ... }
Если добавить этот код во Frame, будет нарисован эллипс с зелёным ободком, а при нажатии на него клавишей мыши выполниться некоторое действие (1). Но есть существенное НО : нажимать надо не в эллипс , а исключительно на зелёный ободок , что - бы что то произошло. Понятно, что это очень не удобно. Исправить данную "фичу" можно довольно просто:
Ellipse {
centerX: 10, centerY: 10
radiusX: 150, radiusY: 50
stroke: Color.GREEN
fill: Color.WHITE
onMouseClicked: function( e: MouseEvent ):Void { // (1)do smth ... }
Как видите я просто заполнил эллипс белой краской , визуально ничего не изменилось, но все собітия onMouseXxxx будут теперь отрабатывать не только для оботка, но и для всего эллипса.
Следующий рабочий пример, позволит легче усвоить данный урок.
import javafx.application.*;
import javafx.scene.geometry.*;
import javafx.scene.paint.*;
import javafx.input.*;
var Rad:Integer = 10;
Frame {
title: "Test onMouseXx application"
width: 200 height: 200
closeAction: function() {
java.lang.System.exit( 0 );
}
visible: true
stage: Stage
{
content: [
Circle
{
centerX: 100, centerY: 100
radius: bind Rad stroke: Color.GREEN //fill: Color.WHITE onMouseClicked:
function( e: MouseEvent ):Void {
if (Rad == 50)
{ Rad = 10; }
else
{ Rad = 50; }
}
}
]
}
}
15 августа 2008
JavaScript библиотека jQuery
Ни одно юзабельное веб приложение не сможет обойтись без богатого веб интерфейса, который легко реализовать с помощью JavaScript и, например библиотеки jQuery:
jQeury: плавающий dialog box,
jQuery и Ajax,
jQuery: drag-and-drop сортируемый список,
таблица с помощью jQuery,
colorPicker: выбор цвета,
jQuey Treeview - древовидное меню,
jQuery Ajax форма,
Валидация данных в Ajax форме
и много других интересных статей по jQuery тут.
jQeury: плавающий dialog box,
jQuery и Ajax,
jQuery: drag-and-drop сортируемый список,
таблица с помощью jQuery,
colorPicker: выбор цвета,
jQuey Treeview - древовидное меню,
jQuery Ajax форма,
Валидация данных в Ajax форме
и много других интересных статей по jQuery тут.
30 июля 2008
JavaFX - первое приложение
Для начала необходимо скачать и настроить компилятор.
Скачать последню версию компилятора можно по ссылке : archive.zip(12Мб)
- распакуйте архив в удобную для вас папку
- добавьте полный путь к папке openjfx-compiler\dist\bin\ в перменную PATH
Откройте текстовый редактор и создайте в нём файл HelloWorld.fx
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.text.Text;
Frame {
title: "Hello JavaFX Script"
width: 300
height: 100
stage:Stage {
content: [
Text {
x: 100, y: 30
content: "Hello world"
}
]
}
visible: true
}
Сохраните файл, скомпилируйте и выполните его с помощью следующих команд:
>javafxc HelloWorld.fx
>javafx HelloWorld
Внимание, на вашем компьютере должно быть установлено JDK версии не менее 1.6 для успешного работы Java FX.
Итак, приложение создало окно (Frame) указанных размров c заголовком Hello JavaFX Script и текстом Hello world посреди окна.
Другие римеры на Java FX
Tesla Demo
SVG to Java FX Translator Demo
(примеры загружаются через Java Web Start)
Source:
Open Java FX
JavaFX по русски
Скачать последню версию компилятора можно по ссылке : archive.zip(12Мб)
- распакуйте архив в удобную для вас папку
- добавьте полный путь к папке openjfx-compiler\dist\bin\ в перменную PATH
Откройте текстовый редактор и создайте в нём файл HelloWorld.fx
import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.text.Text;
Frame {
title: "Hello JavaFX Script"
width: 300
height: 100
stage:Stage {
content: [
Text {
x: 100, y: 30
content: "Hello world"
}
]
}
visible: true
}
Сохраните файл, скомпилируйте и выполните его с помощью следующих команд:
>javafxc HelloWorld.fx
>javafx HelloWorld
Внимание, на вашем компьютере должно быть установлено JDK версии не менее 1.6 для успешного работы Java FX.
Итак, приложение создало окно (Frame) указанных размров c заголовком Hello JavaFX Script и текстом Hello world посреди окна.
Другие римеры на Java FX
Tesla Demo
SVG to Java FX Translator Demo
(примеры загружаются через Java Web Start)
Source:
Open Java FX
JavaFX по русски
16 июля 2008
23 июня 2008
Spring MVC
Spring MVC - это реализация шаблона MVC (модель - представление - контроллер) в Spring Framework.
Используется для создания Web приложений.
Для создания приложения первого приложения вам не помешает скачать
необходимые библиотеки из оффициального сайта Spring.
Во время написания заметки самой новой версией была 2.5.4 ею и предлагаю воспользоваться.
Также вам на первых порах не помешают следующие библиотеки:
commons-logging-1.1.jar
jstl.jar, standard.jar
Свой "hello world" я создавать не буду, таких достаточно в интернете, напрмер
можно воспользоваться одним из следующих туториалов:
http://mhimu.wordpress.com/2007/11/27/spring-mvc-tutorial/ (англ.)
http://artamonov.ru/2006/03/15/prostoe-prilozhenie-na-spring/ (рус.)
Используется для создания Web приложений.
Для создания приложения первого приложения вам не помешает скачать
необходимые библиотеки из оффициального сайта Spring.
Во время написания заметки самой новой версией была 2.5.4 ею и предлагаю воспользоваться.
Также вам на первых порах не помешают следующие библиотеки:
commons-logging-1.1.jar
jstl.jar, standard.jar
Свой "hello world" я создавать не буду, таких достаточно в интернете, напрмер
можно воспользоваться одним из следующих туториалов:
http://mhimu.wordpress.com/2007/11/27/spring-mvc-tutorial/ (англ.)
http://artamonov.ru/2006/03/15/prostoe-prilozhenie-na-spring/ (рус.)
Подписаться на:
Сообщения (Atom)