Проверка данных класса (bean) в java тема не новая, но актуальная и здесь я объединю различные аспекты: валидацию данных в рамках JSR-303, покажу как это сделать чисто в Java и с использованием Spring, как делать в стандартном приложении и в Web.
Содержание: Валидация данных (JSR-303) в
Здесь в примере Size и @Digits готовые аннотации, а @PersonAgeConstraint собственная. Как сделать собственную:
— подготавливаем аннотацию
В message() указываем ключ (value.negative) из файла ресурса (ValidationMessages.properties) для сообщения
Моя собственная аннотация готова, добавляем ее к полю и уже можно проверить, все поля на которых есть аннотации будут проверены соответствующими правилами.
Результат в консоли
Сообщения для стандартных аннотаций можно указать в файле сообщений, по правилу:
Структура проекта
Поэтапная проверка. Для Class<?>[] groups() можно указывать типы классов по которым можно потом группировать, ограничивать список проверок, т.е. использовать как фильтр. Таким образом проверку можно сделать по этапам, 1) Например разделим проверку лица по состоянию здоровья, 2) а уже затем профессиональные данные. Подготовим две аннотации
HealthConstraint и ProfessionalConstraint и реализации для них. Первым проверим соответствие здоровью а затем если проходит по здоровью, проверим на профессиональные данные.
Пример:
Пример аннотации HealthConstraint
Пример реализации HealthConstraintValidator
для ProfessionalConstraint все аналогично
Далее проверять так:
Подобные проверки, например нужны когда мы загружаем данные из файла, web service и др. источников.
В Spring есть так же свой интерфейс Validator
Переопределив два метода, делаем валидацию
value.negative — так же является ключом в файле сообщений,
Проверка запускается через DataBinder
Пример:
Будут выполнены все проверки которые имплементировали org.springframework.validation.Validator для класса Person.
Можно добавить так же несколько валидаторов, dataBinder.addValidators, можно сделать композицию правил (вызов из одного правила, другого), пример:
Я почему то ожидал, Spring будет выполнять также проверки указанные в аннотациях, но нет, этот вызов надо делать самостоятельно.
Структура проекта
Очевидно я захочу использовать два подхода в проверки данных — Java и Spring, объединить их можно, а именно добавить в Spring validator вызов javax.validation.Validator.
Пример
С помощью spring делаем injection
далее на методе
выполняем декларативные проверки java, а затем выполняем все проверки для класса Person на spring org.springframework.validation.Validator.
Запускаем проверку также через spring
Теперь в коллекции будут проверки от аннотаций java и spring (org.springframework.validation.Validator) для Person
Вывод в консоли
Структура проекта
Конечно теперь это все можно применить в web приложении.
Добавляем в проект Controller, jsp страницу (тут кстати могут и другие варианты, например генерация страниц с помощью freeMarker, и др.), css стиль, pom зависимость. И так по порядку
1) MVC Controller
Здесь с помощью spring injection подключен PersonValidator
устанавливаем PersonValidator в initBinder
Проверка инициируется с помощью аннотации
В этом случае выполнится только spring проверка, декларативные проверки будут проигнорированы.
Если убрать из кода
то наоборот выполнятся все декларативные проверки, а spring будут проигнорированы.
Что бы выполнить все проверки и декларативные и spring, можно поступить так:
Убрать @InitBinder, оставить injection
и добавить вызов spring проверки вручную
Вот код:
т.е. в bindingResult будут добавлены еще проверки от spring :-), что и хотелось!
Привязка данных в jsp и модели, осуществляется атрибутом -
Остальные ресурсы этого примера:
Spring configuration
Структура проекта
Работа приложения
Материалы
Bean Validation specification
Содержание: Валидация данных (JSR-303) в
- стандартном Java приложении
- c использованием Spring
- объединение Java + Spring
- Spring MVC
Validation в стандартном Java приложении
Для проверки объекта используются аннотации на полях класса, т.е. декларативная модель. Аннотации есть уже готовые:Null, @DecimalMin, @Digits, Pattern, Email и др., а также можно делать и собственные. И так есть класс (bean)
import javax.validation.constraints.Digits;
import javax.validation.constraints.Size;
public class Person {
@Size(min=2, max=50)
private String Name;
@Digits(integer=3, fraction=0, message = "Не более 3-х знаков")
@PersonAgeConstraint
private Integer age;
public Person(String name, Integer age) {
Name = name;
this.age = age;
}
}
Здесь в примере Size и @Digits готовые аннотации, а @PersonAgeConstraint собственная. Как сделать собственную:
— подготавливаем аннотацию
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=PersonAgeConstraintValidator.class)
public @interface PersonAgeConstraint {
String message() default "{value.negative}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
В message() указываем ключ (value.negative) из файла ресурса (ValidationMessages.properties) для сообщения
value.negative=Отрицательное\u0020значениеи реализацию класса проверки — PersonAgeConstraintValidator.class
public class PersonAgeConstraintValidator implements ConstraintValidator<PersonAgeConstraint, Integer> {
@Override
public boolean isValid(Integer age, ConstraintValidatorContext constraintValidatorContext) {
return age > 0;
}
}
Моя собственная аннотация готова, добавляем ее к полю и уже можно проверить, все поля на которых есть аннотации будут проверены соответствующими правилами.
import javax.validation.Validator;
/**
* Test Validation
*/
public class DemoJValidationApplicationTests {
// Инициализация Validator
private static Validator validator;
static {
ValidatorFactory validatorFactory = Validation.buildDefaultValidatorFactory();
validator = validatorFactory.usingContext().getValidator();
}
@Test
public void testValidators() {
final Person person = new Person("Иван Петров", -4500);
Set<ConstraintViolation<Person>> validates = validator.validate(person);
Assert.assertTrue(validates.size() > 0);
validates.stream().map(v -> v.getMessage())
.forEach(System.out::println);
}
}
Результат в консоли
Не более 3-х знаков
Отрицательное значение
Сообщения для стандартных аннотаций можно указать в файле сообщений, по правилу:
AnnotationName.entity.fieldname=сообщение
Структура проекта
Поэтапная проверка. Для Class<?>[] groups() можно указывать типы классов по которым можно потом группировать, ограничивать список проверок, т.е. использовать как фильтр. Таким образом проверку можно сделать по этапам, 1) Например разделим проверку лица по состоянию здоровья, 2) а уже затем профессиональные данные. Подготовим две аннотации
HealthConstraint и ProfessionalConstraint и реализации для них. Первым проверим соответствие здоровью а затем если проходит по здоровью, проверим на профессиональные данные.
Пример:
public class Person {
@HealthConstraint(groups = Health.class)
private Documents healthDocuments;
@ProfessionalConstraint(groups = Professional.class)
private Documents ProfessionalDocuments;
//...
}
Пример аннотации HealthConstraint
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy=HealthConstraintValidator.class)
public @interface HealthConstraint {
String message() default "{health.documents}";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
Пример реализации HealthConstraintValidator
public class HealthConstraintValidator implements ConstraintValidator<HealthConstraint, Documents> {
@Override
public boolean isValid(Documents documents, ConstraintValidatorContext constraintValidatorContext) {
return documents.contains("справка 1");
}
}
для ProfessionalConstraint все аналогично
Далее проверять так:
@Test
public void healthAndProfessionalValidators() {
final Person person = new Person("Иван Петров", 45);
person.setHealthDocuments(new Documents(Arrays.asList("справка 1", "справка 3")));
person.setProfessionalDocuments(new Documents(Arrays.asList("тест 1", "тест 4")));
// проверка на здоровье
Set<ConstraintViolation<Person>> validates = validator.validate(person, Health.class);
Assert.assertTrue(validates.size() == 0);
// и если здоровье Ок, то проф. тест
validates = validator.validate(person, Professional.class);
Assert.assertTrue(validates.size() == 0);
}
Подобные проверки, например нужны когда мы загружаем данные из файла, web service и др. источников.
Validation c использованием Spring
В Spring есть так же свой интерфейс Validator
(org.springframework.validation.Validator)как и в Java
(javax.validation.Validator)и именно его имплементация выполняет проверку данных. Это уже не декларативный подход, но в нем есть своя гибкость и расширяемость. Для того же бина, сделаю туже проверку возраста.
Переопределив два метода, делаем валидацию
@Service
public class PersonValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return Person.class.equals(aClass);
}
@Override
public void validate(Object obj, Errors errors) {
Person p = (Person) obj;
if (p.getAge() < 0) {
errors.rejectValue("age", "value.negative");
}
}
}
value.negative — так же является ключом в файле сообщений,
public boolean supports
определяет тип поддерживаемого класса. Проверка запускается через DataBinder
Пример:
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoJValidationApplicationTests {
// указываем файл сообщений
private static final ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
static {
messageSource.setBasename("message");
}
@Autowired
private PersonValidator personValidator;
@Test
public void testValidators() {
final Person person = new Person("Иван Петров", -4500);
final DataBinder dataBinder = new DataBinder(person);
dataBinder.addValidators(personValidator);
dataBinder.validate();
Assert.assertTrue(dataBinder.getBindingResult().hasErrors());
if (dataBinder.getBindingResult().hasErrors()) {
dataBinder.getBindingResult().getAllErrors().stream().
forEach(e -> System.out.println(messageSource
.getMessage(e, Locale.getDefault())));
}
}
}
Будут выполнены все проверки которые имплементировали org.springframework.validation.Validator для класса Person.
Можно добавить так же несколько валидаторов, dataBinder.addValidators, можно сделать композицию правил (вызов из одного правила, другого), пример:
public class OtherValidator implements Validator {
@Override
public boolean supports(Class<?> aClass) {
return Person.class.equals(aClass);
}
@Override
public void validate(Object obj, Errors errors) {
// ...
}
}
//---------
@Service
public class PersonValidator implements Validator {
/**
* другое правила
*/
@Autowired
private OtherValidator otherValidator;
@Override
public void validate(Object obj, Errors errors) {
Person p = (Person) obj;
if (p.getAge() < 0) {
errors.rejectValue("age", "value.negative");
}
// из одного правила, вызываем другое
otherValidator.validate(obj, errors);
}
}
Я почему то ожидал, Spring будет выполнять также проверки указанные в аннотациях, но нет, этот вызов надо делать самостоятельно.
Структура проекта
Java & Spring
Очевидно я захочу использовать два подхода в проверки данных — Java и Spring, объединить их можно, а именно добавить в Spring validator вызов javax.validation.Validator.
Пример
import javax.validation.Validator;
@Service
public class PersonValidator implements org.springframework.validation.Validator {
// javax.validation.Validator
@Autowired
private Validator validator;
@Override
public boolean supports(Class<?> aClass) {
return Person.class.equals(aClass);
}
@Override
public void validate(Object obj, Errors errors) {
Set<ConstraintViolation<Object>> validates = validator.validate(obj);
for (ConstraintViolation<Object> constraintViolation : validates) {
String propertyPath = constraintViolation.getPropertyPath().toString();
String message = constraintViolation.getMessage();
errors.rejectValue(propertyPath, "", message);
}
Person p = (Person) obj;
if (p.getAge() < 0) {
errors.rejectValue("age", "only.positive.numbers");
}
}
}
С помощью spring делаем injection
javax.validation.Validator
@Autowired
private Validator validator;
далее на методе
public void validate(Object obj, Errors errors)
выполняем декларативные проверки java, а затем выполняем все проверки для класса Person на spring org.springframework.validation.Validator.
Запускаем проверку также через spring
@Test
public void testValidators() {
final Person person = new Person("Иван", -4500);
final DataBinder dataBinder = new DataBinder(person);
dataBinder.addValidators(personValidator);
dataBinder.validate();
if (dataBinder.getBindingResult().hasErrors()) {
dataBinder.getBindingResult().getAllErrors()
// ....
Теперь в коллекции будут проверки от аннотаций java и spring (org.springframework.validation.Validator) для Person
Вывод в консоли
Отрицательное значение (аннотация)
Не более 3-х знаков (аннотация)
Только положительные число (spring)
Структура проекта
Spring MVC
Конечно теперь это все можно применить в web приложении.
Добавляем в проект Controller, jsp страницу (тут кстати могут и другие варианты, например генерация страниц с помощью freeMarker, и др.), css стиль, pom зависимость. И так по порядку
1) MVC Controller
import org.springframework.validation.Validator;
@Controller
public class DemoJValidationController {
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(personValidator);
}
@GetMapping("/")
public String savePersonAction(ModelMap model) {
model.addAttribute("person", new Person(null, null));
return "personEdit";
}
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePersonAction(
@Valid @ModelAttribute("person") Person person,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
return "personEdit"; // to person.jsp page
}
model.addAttribute("name", person.getName());
model.addAttribute("age", person.getAge());
return "saveSuccess"; // to saveSuccess.jsp page
}
@RequestMapping(value = "/edit", method = RequestMethod.POST)
public String editPersonAction(ModelMap model) {
model.addAttribute("person", new Person(null, null));
return "personEdit"; // to personEdit.jsp page;
}
}
Здесь с помощью spring injection подключен PersonValidator
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
устанавливаем PersonValidator в initBinder
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(personValidator);
}
Проверка инициируется с помощью аннотации
@Valid
В этом случае выполнится только spring проверка, декларативные проверки будут проигнорированы.
Если убрать из кода
@InitBinder
protected void initBinder(WebDataBinder binder)
то наоборот выполнятся все декларативные проверки, а spring будут проигнорированы.
Что бы выполнить все проверки и декларативные и spring, можно поступить так:
Убрать @InitBinder, оставить injection
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
и добавить вызов spring проверки вручную
// spring validate
personValidator.validate(person, bindingResult);
Вот код:
@Controller
public class DemoJValidationController {
@Autowired
@Qualifier("personValidator") // spring validator
private Validator personValidator;
//...
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String savePersonAction(
@Valid @ModelAttribute("person") Person person,
BindingResult bindingResult, Model model) {
// spring validate
personValidator.validate(person, bindingResult);
if (bindingResult.hasErrors()) {
return "personEdit"; // to person.jsp page
}
model.addAttribute("name", person.getName());
model.addAttribute("age", person.getAge());
return "saveSuccess"; // to saveSuccess.jsp page
}
}
т.е. в bindingResult будут добавлены еще проверки от spring :-), что и хотелось!
Привязка данных в jsp и модели, осуществляется атрибутом -
modelAttribute="person"
В примере подключена SpringMVC’s Form Tag Library.Остальные ресурсы этого примера:
DemoJValidationApplication
Spring configuration
Структура проекта
Работа приложения
Материалы
Bean Validation specification
Источник: https://habr.com/post/424819/?utm_source=habrahabr&utm_medium=rss&utm_campaign=424819
Смотри также:
Зачем нужна Java. http://fetisovvs.blogspot.com/2014/07/java.html
Разбор основных концепций параллелизма. http://fetisovvs.blogspot.com/2018/04/java.html
Первый контакт с «var» в Java 10. http://fetisovvs.blogspot.com/2018/01/var-java-10-java.html
JAVA 9. Что нового? http://fetisovvs.blogspot.com/2017/10/java-9-java.html
Руководство по Java 9 для тех, кому приходится работать с legacy-кодом. http://fetisovvs.blogspot.com/2018/08/java-9-legacy-java.html
Концепции объектно-ориентированного программирования — ООП в Java. http://fetisovvs.blogspot.com/2017/01/java-java.html
Анимации в Android по полочкам (Часть 1. Базовые анимации). http://fetisovvs.blogspot.com/2018/02/android-1-java.html
Двести пятьдесят русскоязычных обучающих видео докладов и лекций о Java. http://fetisovvs.blogspot.com/2015/12/java-5-java-java.html
Абстрактные классы и методы. http://fetisovvs.blogspot.com/2017/02/java.html
Полное руководство по Java Reflection API. Рефлексия на примерах. http://fetisovvs.blogspot.com/2017/02/java-reflection-api-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. http://fetisovvs.blogspot.com/2017/10/java-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. (Часть 3). http://fetisovvs.blogspot.com/2017/10/java-3-java.html
ТОП-3 способа конвертировать массив в ArrayList. Пример на Java. http://fetisovvs.blogspot.com/2016/09/3-arraylist-java-java.html
Ввод–вывод в Java. http://fetisovvs.blogspot.com/2016/05/java-java_28.html
Enum-Всемогущий. http://fetisovvs.blogspot.com/2017/02/enum-java.html
Массивы в Java. Создание и обработка. http://fetisovvs.blogspot.com/2017/10/java-java_18.html
Arrays, Collections: Алгоритмический минимум. http://fetisovvs.blogspot.com/2017/12/arrays-collections.html
Популярные методы для работы с Java массивами. http://fetisovvs.blogspot.com/2016/09/java-java_29.html
Пример использования метода replace в Java. Как заменить символ в строке? http://fetisovvs.blogspot.com/2017/01/replace-java-java.html
Класс Scanner в Java — описание и пример использования. http://fetisovvs.blogspot.com/2017/01/scanner-java-java.html
Пример использования метода trim в Java: как удалить пробелы в начале и конце строки? http://fetisovvs.blogspot.com/2017/01/trim-java-java.html
Spark — Потрясающий веб-микрофреймворк для Java. http://fetisovvs.blogspot.com/2017/10/spark-java-java.html
Чтение и запись CSV файла с помощью SuperCSV. http://fetisovvs.blogspot.com/2017/01/csv-supercsv-java-java.html
Конструкция try/catch/finally (исключения). http://fetisovvs.blogspot.com/2017/01/trycatchfinally-java.html
1000+ часов видео по Java на русском. http://fetisovvs.blogspot.nl/2017/06/1000-java-java.html
Раздача халявы: нетормозящие треды в Java. Project Loom. http://fetisovvs.blogspot.com/2018/09/java-project-loom-java.html
Шпаргалка Java программиста 7.1 Типовые задачи: Оптимальный путь преобразования InputStream в строку. http://fetisovvs.blogspot.com/2016/04/java-71-inputstream-java.html
Шпаргалки Java программиста 10: Lombok. http://fetisovvs.blogspot.nl/2017/12/java-10-lombok-java.html
Шпаргалки Java программиста 9: Java SE — Шпаргалка для собеседований и повторений. http://fetisovvs.blogspot.com/2017/12/java-9-java-se-java.html
Шпаргалка Java программиста 8. Библиотеки для работы с Json (Gson, Fastjson,
LoganSquare, Jackson, JsonPath и другие). http://fetisovvs.blogspot.com/2016/04/java-8-json-gson-fastjson-logansquare.html
Java 8 и паттерн Стратегия. http://fetisovvs.blogspot.com/2018/03/java-8-java.html
Java EE Concurency API. http://fetisovvs.blogspot.com/2018/08/java-ee-concurency-api-java.html
Реализация ООП-наследования в классах, работающих с SQL и MS Entity Framework. http://fetisovvs.blogspot.com/2017/02/sql-ms-entity-framework.html
Как установить соединение с СУБД MySQL в IntelliJ IDEA в редакции Community. http://fetisovvs.blogspot.com/2016/04/mysql-intellij-idea-community-java.html
Максимально простой в поддержке способ интеграции java-клиента с java-сервером. http://fetisovvs.blogspot.com/2018/09/java-java-java.html
Как с помощью maven работать с библиотеками, которых в maven нет. http://fetisovvs.blogspot.com/2017/03/maven-maven-java.html
Проекты по созданию компиляторов из Java в JavaScript и исполняемые файлы. http://fetisovvs.blogspot.com/2018/01/java-javascript-java.html
Реактивное программирование с JAX-RS. http://fetisovvs.blogspot.com/2018/09/jax-rs-java.html
Абстрактный CRUD от репозитория до контроллера: что ещё можно сделать при помощи Spring + Generics. http://fetisovvs.blogspot.com/2018/09/crud-spring-generics-java.html
Диагностика утечек памяти в Java. http://fetisovvs.blogspot.com/2017/03/java-java_18.html
Spring AOP и JavaConfig в плагинах для Atlassian Jira. http://fetisovvs.blogspot.com/2018/04/spring-aop-javaconfig-atlassian-jira.html
Блеск и нищета Java для настольных систем. http://fetisovvs.blogspot.com/2018/04/java-haulmont-java.html
Разбор задачек от Одноклассников на JPoint 2018. http://fetisovvs.blogspot.com/2018/04/jpoint-2018-java.html
Программируем… выход из лабиринта. http://fetisovvs.blogspot.com/2015/10/java.html
Основы работы с IntelliJ IDEA. Интерфейс программы. http://fetisovvs.blogspot.com/2016/09/intellij-idea-java.html
Ускоряем время сборки и доставки java web приложения. http://fetisovvs.blogspot.com/2018/03/java-web-java.html
Открытый урок Java Enterprise «CDI in action». http://fetisovvs.blogspot.com/2018/09/java-enterprise-cdi-in-action-java.html
«Мы все стремимся к сложности, а потом с ней боремся»: интервью с Венкатом Субраманиамом. http://fetisovvs.blogspot.com/2018/09/java_16.html
Разбор основных концепций параллелизма. http://fetisovvs.blogspot.com/2018/04/java.html
Первый контакт с «var» в Java 10. http://fetisovvs.blogspot.com/2018/01/var-java-10-java.html
JAVA 9. Что нового? http://fetisovvs.blogspot.com/2017/10/java-9-java.html
Руководство по Java 9 для тех, кому приходится работать с legacy-кодом. http://fetisovvs.blogspot.com/2018/08/java-9-legacy-java.html
Концепции объектно-ориентированного программирования — ООП в Java. http://fetisovvs.blogspot.com/2017/01/java-java.html
Анимации в Android по полочкам (Часть 1. Базовые анимации). http://fetisovvs.blogspot.com/2018/02/android-1-java.html
Двести пятьдесят русскоязычных обучающих видео докладов и лекций о Java. http://fetisovvs.blogspot.com/2015/12/java-5-java-java.html
Абстрактные классы и методы. http://fetisovvs.blogspot.com/2017/02/java.html
Полное руководство по Java Reflection API. Рефлексия на примерах. http://fetisovvs.blogspot.com/2017/02/java-reflection-api-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. http://fetisovvs.blogspot.com/2017/10/java-java.html
Микросервисы для Java программистов. Практическое введение во фреймворки и контейнеры. (Часть 3). http://fetisovvs.blogspot.com/2017/10/java-3-java.html
ТОП-3 способа конвертировать массив в ArrayList. Пример на Java. http://fetisovvs.blogspot.com/2016/09/3-arraylist-java-java.html
Ввод–вывод в Java. http://fetisovvs.blogspot.com/2016/05/java-java_28.html
Enum-Всемогущий. http://fetisovvs.blogspot.com/2017/02/enum-java.html
Массивы в Java. Создание и обработка. http://fetisovvs.blogspot.com/2017/10/java-java_18.html
Arrays, Collections: Алгоритмический минимум. http://fetisovvs.blogspot.com/2017/12/arrays-collections.html
Популярные методы для работы с Java массивами. http://fetisovvs.blogspot.com/2016/09/java-java_29.html
Пример использования метода replace в Java. Как заменить символ в строке? http://fetisovvs.blogspot.com/2017/01/replace-java-java.html
Класс Scanner в Java — описание и пример использования. http://fetisovvs.blogspot.com/2017/01/scanner-java-java.html
Пример использования метода trim в Java: как удалить пробелы в начале и конце строки? http://fetisovvs.blogspot.com/2017/01/trim-java-java.html
Spark — Потрясающий веб-микрофреймворк для Java. http://fetisovvs.blogspot.com/2017/10/spark-java-java.html
Чтение и запись CSV файла с помощью SuperCSV. http://fetisovvs.blogspot.com/2017/01/csv-supercsv-java-java.html
Конструкция try/catch/finally (исключения). http://fetisovvs.blogspot.com/2017/01/trycatchfinally-java.html
1000+ часов видео по Java на русском. http://fetisovvs.blogspot.nl/2017/06/1000-java-java.html
Раздача халявы: нетормозящие треды в Java. Project Loom. http://fetisovvs.blogspot.com/2018/09/java-project-loom-java.html
Шпаргалка Java программиста 7.1 Типовые задачи: Оптимальный путь преобразования InputStream в строку. http://fetisovvs.blogspot.com/2016/04/java-71-inputstream-java.html
Шпаргалки Java программиста 10: Lombok. http://fetisovvs.blogspot.nl/2017/12/java-10-lombok-java.html
Шпаргалки Java программиста 9: Java SE — Шпаргалка для собеседований и повторений. http://fetisovvs.blogspot.com/2017/12/java-9-java-se-java.html
Шпаргалка Java программиста 8. Библиотеки для работы с Json (Gson, Fastjson,
LoganSquare, Jackson, JsonPath и другие). http://fetisovvs.blogspot.com/2016/04/java-8-json-gson-fastjson-logansquare.html
Java 8 и паттерн Стратегия. http://fetisovvs.blogspot.com/2018/03/java-8-java.html
Java EE Concurency API. http://fetisovvs.blogspot.com/2018/08/java-ee-concurency-api-java.html
Реализация ООП-наследования в классах, работающих с SQL и MS Entity Framework. http://fetisovvs.blogspot.com/2017/02/sql-ms-entity-framework.html
Как установить соединение с СУБД MySQL в IntelliJ IDEA в редакции Community. http://fetisovvs.blogspot.com/2016/04/mysql-intellij-idea-community-java.html
Максимально простой в поддержке способ интеграции java-клиента с java-сервером. http://fetisovvs.blogspot.com/2018/09/java-java-java.html
Как с помощью maven работать с библиотеками, которых в maven нет. http://fetisovvs.blogspot.com/2017/03/maven-maven-java.html
Проекты по созданию компиляторов из Java в JavaScript и исполняемые файлы. http://fetisovvs.blogspot.com/2018/01/java-javascript-java.html
Реактивное программирование с JAX-RS. http://fetisovvs.blogspot.com/2018/09/jax-rs-java.html
Абстрактный CRUD от репозитория до контроллера: что ещё можно сделать при помощи Spring + Generics. http://fetisovvs.blogspot.com/2018/09/crud-spring-generics-java.html
Диагностика утечек памяти в Java. http://fetisovvs.blogspot.com/2017/03/java-java_18.html
Spring AOP и JavaConfig в плагинах для Atlassian Jira. http://fetisovvs.blogspot.com/2018/04/spring-aop-javaconfig-atlassian-jira.html
Блеск и нищета Java для настольных систем. http://fetisovvs.blogspot.com/2018/04/java-haulmont-java.html
Разбор задачек от Одноклассников на JPoint 2018. http://fetisovvs.blogspot.com/2018/04/jpoint-2018-java.html
Программируем… выход из лабиринта. http://fetisovvs.blogspot.com/2015/10/java.html
Основы работы с IntelliJ IDEA. Интерфейс программы. http://fetisovvs.blogspot.com/2016/09/intellij-idea-java.html
Ускоряем время сборки и доставки java web приложения. http://fetisovvs.blogspot.com/2018/03/java-web-java.html
Открытый урок Java Enterprise «CDI in action». http://fetisovvs.blogspot.com/2018/09/java-enterprise-cdi-in-action-java.html
«Мы все стремимся к сложности, а потом с ней боремся»: интервью с Венкатом Субраманиамом. http://fetisovvs.blogspot.com/2018/09/java_16.html
Комментариев нет:
Отправить комментарий