Статьи

Список статей

Управление транзакциями в Spring

22 февраля 2020

Тэги: Spring Java 10 Spring Data

Транзакцией называется набор связанных операций, все из которых должны быть выполнены корректно без ошибок. Если при выполнении одной из операций возникла ошибка, все остальные должны быть отменены. Прежде всего такой механизм применяется при работе с БД.

Spring предлагает очень простой декларативный способ управления транзакциями. Вам достаточно добавить @org.springframework.transaction.annotation.Transactional к публичному сервисному методу, и все операции внутри этого метода будут выполняться в транзакции. При выходе из метода транзакция будет завершена (операция commit в терминах БД) автоматически. Если в процессе работы возникнет исключение и оно не будет перехвачено внутри метода, транзакция будет отменена (операция rollback) и все данные вернуться в то состояние, в котором они были до начала транзакции.

Читать полностью...

Сравнение форматов конфига в Spring Boot

16 февраля 2020

Тэги: Spring Boot Java Collections Spring XML json yaml

Spring Boot позволяет хранить настройки приложения в файле и получать к ним доступ в декларативном стиле. Этот файл может иметь один из трёх форматов: properties, xml и yaml. Как Spring будет интерпретировать формат файла, определяется его расширением. Далее мы рассмотрим плюсы и минусы каждого формата. В качестве примера предположим, что в конфиге мы храним число, текстовую строку на русском языке и список значений.

properties-файл

По умолчанию в Spring используется properties-конфиг. Имя файла должно начинаться со слова application и иметь расширение properties. Если вы не используете профили для разделения конфигов, то достаточно иметь файл application.properties.

# числовой параметр
some.test.numberValue=42
# текстовый параметр
some.test.textValue="Текстовый параметр из properties-файла"
# список значений
some.test.list[0]=one
some.test.list[1]=two
some.test.list[2]=three

В данном формате комментарии всегда начинаются с новой строки и с символа «#». Имя каждого параметра прописывается полностью (и это один из недостатков данного формата), затем идёт «=», затем само значение. Текстовые значения можно указывать как в кавычках, так и без них. Список значений, который в нашем приложении превратится в объект типа List, в конце имени каждого значения имеет индекс в квадратных скобках. Такой синтаксис похож на объявление массива.

Читать полностью...

Кеширование в Spring Boot

15 февраля 2020

Тэги: Java 10 Spring Boot Spring maven gradle

Spring Boot поддерживает простой механизм кеширования данных. Рассмотрим его на примере, исходники которого доступны на github.

Создадим стандартное приложение Spring Boot. Это удобно делать через Spring Initializr. В итоге, если вы используете gradle, то в файле build.gradle должны быть две зависимости:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-cache'
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

Если же вы используете maven, то зависимости будут в файле pom.xml:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Зависимость spring-boot-starter-web - это базовая функциональность нашего веб-приложения, в том числе поддержка rest-контроллеров. Зависимость spring-boot-starter-cache добавляет возможность кеширования.

Читать полностью...

Вычисление MD5-хэша

13 февраля 2020

Тэги: Java 10 алгоритмы Spring

MD5 хэш (Message Digest 5) - это 128 битный алгоритм вычисления хэша от сообщения произвольной длины. Чаще всего хэш вычисляется от строки (для проверки паролей) и от файла (для контроля его целостности).

Следует сразу же заметить, что хранение паролей в виде md5-хэшей в настоящее время считается небезопасным, т.к. md5-хэш довольно сильно подвержен коллизиям. Коллизией называется ситуация, когда у двух исходных сообщений хэши равны. То есть для успешного прохождения проверки пароля, сохраняемого в виде md5-хэша, вам даже не обязательно знать именно этот пароль. Достаточно знать пароль, имеющий такой же хэш. Более того, хэши от простых паролей можно напрямую искать в Google.

Вычисление хэша от строки

Алгоритм хэширования MD5 является частью стандартной библиотеки Java, поэтому вычислить хэш от строки (например, от пароля) достаточно легко.

Читать полностью...

Сохранение данных в формате Excel

9 февраля 2020

Тэги: Java 10 ввод-вывод Java Excel Apache

Ранее мы рассматривали пример на тему Чтение данных из Excel. А сегодня узнаем, как можно сохранять данные в формате Excel. Для работы нам потребуются всё те же зависимости от Apache POI. Пример проекта на github прилагается.

Читать полностью...

Чтение данных из Excel

30 января 2020

Тэги: maven Apache Java 10 Excel

Для чтения данных из файла Excel можно использовать библиотеку Apache POI. Эта библиотека позволяет читать как «старый» формат Excel 97-2003 (расширение файла .xls), так и «новый» (.xlsx). В качестве примера вы можете использовать проект на github.

Добавим в наш maven-проект необходимые зависимости.

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.1</version>
</dependency>

Теперь напишем класс ExcelReader, состоящий из одного публичного метода read() и нескольких приватных.

Читать полностью...

Распаковка zip-архивов

29 января 2020

Тэги: Java 10 ввод-вывод Java

Ранее мы рассматривали Создание zip-архивов, а теперь попробуем выполнить обратную операцию. Если у нас имеется zip-архив с файлами, то распаковать его мы можем следующим образом:

public static void main(String[] args) throws IOException {
    try (var file = new ZipFile("/home/devmark/Documents/test.zip")) {
        var entries = file.entries();
        var uncompressedDirectory = new File(file.getName()).getParent() + File.separator;
        while (entries.hasMoreElements()) {
            var entry = entries.nextElement();
            if (entry.isDirectory()) {
                processDirectory(uncompressedDirectory, entry);
            } else {
                processFile(file, uncompressedDirectory, entry);
            }
        }
    }
}

Мы создаём объект ZipFile из пакета java.util, в конструктор которому передаём полный путь до нашего архива. Все действия выполняем в конструкции try-with-resources, которая автоматически закроет ресурс, связанный с нашим архивом, в конце работы с ним.

Читать полностью...

Создание zip-архивов

27 января 2020

Тэги: Java 10 ввод-вывод Java

Если нам нужно упаковать в zip-архив какую-то папку с файлами, то сделать это можно следующим образом:

public static void main(String[] args) throws IOException {
    var fileToZip = new File("/home/devmark/Documents/test-dir");
    try (
            var fos = new FileOutputStream(fileToZip.getAbsolutePath() + ".zip");
            var zipOut = new ZipOutputStream(fos)
    ) {
        zipFile(fileToZip, fileToZip.getName(), zipOut);
    }
}

Тут мы создаём объект File с полным путём до папки. Затем используем конструкцию try-with-resources для создания потоков вывода, которая автоматически закрывает эти потоки при выходе из блока. Мы сначала создаём файловый поток вывода FileOutputStream для записи файла с архивом, затем «обрачиваем» его потоком ZipOutputStream, который как раз и позволяет нам архивировать содержимое. По завершении работы программы zip-архив будет лежать на одном уровне с исходной директорией, называться он будет так же, только с расширением «.zip». Теперь рассмотрим метод zipFile().

Читать полностью...

Spring Boot: преобразование объекта в json

26 января 2020

Тэги: Spring Boot Java 10 rest json

Spring Boot значительно упрощает преобразование объекта в json. Предположим, у нас есть такой класс, содержащий какую-то информацию о пользователе:

public class User {
    private String firstName;
    private String lastName;
    private int age;

   // далее идут get- и set-методы для указанных полей...
}

Создадим контроллер, который будет его возвращать.

@RestController
public class JsonController {

    @GetMapping
    public User getUser() {
        var user = new User();
        user.setFirstName("Сигизмунд");
        user.setLastName("Петров");
        user.setAge(23);
        return user;
    }
}

Этих двух классов достаточно, чтобы вы уже могли получать информацию о пользователе в формате json! Выполнив GET-запрос к вашему приложению (по умолчанию http://127.0.0.1:8080/), вы получите такой json:

Читать полностью...

Как получить все даты в указанном диапазоне

26 января 2020

Тэги: Java 8 Java 9 Stream API

Предположим, у нас есть дата начала dateTill и дата окончания dateFrom некоторого временного диапазона. И нам нужно получить список, содержащий все даты из этого диапазона. Как это сделать? Есть два варианта.

Вариант для Java 9

Если у вас Java версии 9 или более поздняя, то можно использовать такой лаконичный вариант:

public List<LocalDate> getDatesFromInterval(LocalDate dateFrom, LocalDate dateTill) {
    return dateFrom.datesUntil(dateTill.plusDays(1))
            .collect(Collectors.toList());
}

Метод LocalDate.datesUntil() порождает поток, начинающийся с указанной даты и заканчивающийся датой, переданной в этот метод в качестве параметра. Чтобы конечная дата также попала в выборку, прибавляем к ней ещё один день с помощью метода plusDays(). В конце превращаем этот поток в список, используя метод collect().

Читать полностью...

❮ Назад Далее ❯