Простые приложения на Groovy
Простые приложения на Groovy
Groovy — динамический язык на JVM — лаконичный синтаксис, GString, встроенный JSON (JsonSlurper), удобные File API. Запуск: groovy script.groovy.
Как запускать примеры из главы
- Команда:
groovy имя.groovy - Нужно: JDK + Groovy (
groovy -version).
Генератор паролей
Как запустить
- Файл:
password.groovy - Команда:
groovy password.groovy
import java.security.SecureRandom
def generatePassword(int len = 16) {
def chars = ('a'..'z') + ('A'..'Z') + ('0'..'9') + '!@#$%^&*'
def rnd = new SecureRandom()
(1..len).collect { chars[rnd.nextInt(chars.size())] }.join()
}
println generatePassword()
Разбор:
import java.security.SecureRandomподключает криптографически стойкий генератор случайных чисел, который лучше обычногоRandomдля паролей.- Функция
generatePassword(int len = 16)объявляет параметр длины с дефолтным значением16, поэтому её можно вызывать без аргументов. - Выражение
('a'..'z') + ('A'..'Z') + ('0'..'9') + '!@#$%^&*'формирует пул допустимых символов: диапазоны букв и цифр плюс спецсимволы. new SecureRandom()создаёт источник случайности, аrnd.nextInt(chars.size())выбирает индекс внутри пула.- Конструкция
(1..len).collect { ... }.join()делаетlenитераций, на каждой выбирает символ, затем склеивает список символов в итоговую строку. println generatePassword()выводит готовый пароль в консоль; при каждом запуске результат будет новым.
Сортировщик файла
def sortFile(input, output) {
def lines = new File(input).readLines('UTF-8')
.collect { it.trim() }
.findAll { it }
.sort()
new File(output).text = lines.join('\n') + '\n'
}
Разбор:
- Функция
sortFile(input, output)принимает путь к исходному и итоговому файлу. new File(input).readLines('UTF-8')читает файл построчно в кодировке UTF-8, чтобы корректно обрабатывать кириллицу и спецсимволы..collect { it.trim() }убирает пробелы по краям строк, а.findAll { it }отфильтровывает пустые строки..sort()сортирует строки по возрастанию (лексикографически).lines.join('\n') + '\n'собирает отсортированный текст и добавляет перевод строки в конце файла.new File(output).text = ...перезаписывает целевой файл новым содержимым.
Калькулятор
def calc(a, b, op) {
switch (op) {
case '+': return a + b
case '-': return a - b
case '*': return a * b
case '/': return b ? a / b : null
default: return null
}
}
Разбор:
- Функция
calc(a, b, op)реализует простой калькулятор: два операнда и символ операции. switch (op)выбирает ветку по значению оператора (+,-,*,/).return a + bи аналогичные выражения сразу возвращают результат выбранной операции.- В ветке деления используется тернарный оператор
b ? a / b — null— еслиbне ноль (truthy), выполняется деление, иначе возвращаетсяnull. default: return nullобрабатывает неизвестные операции и защищает от непредусмотренного ввода.
JSON-трекер
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
def db = new File('tasks.json')
def load() { db.exists() ? new JsonSlurper().parse(db) : [] }
def save(tasks) { db.text = JsonOutput.prettyPrint(JsonOutput.toJson(tasks)) }
def tasks = load()
tasks << [id: System.currentTimeMillis(), title: 'Изучить Groovy', done: false]
save(tasks)
Разбор:
JsonSlurperнужен для чтения JSON в структуры Groovy (Map/List), аJsonOutput— для сериализации обратно в JSON.def db = new File('tasks.json')задаёт файл-хранилище рядом со скриптом.load()проверяетdb.exists(): если файл есть, парсит его; если нет, возвращает пустой список[].save(tasks)преобразует список задач в JSON и форматирует его черезprettyPrintдля читаемости.tasks << [...]добавляет новую задачу в конец списка;System.currentTimeMillis()используется как простой уникальныйid.save(tasks)сохраняет обновлённое состояние на диск, превращая скрипт в минимальный трекер задач.
HTTP (HttpURLConnection)
def url = new URL('https://example.com')
def conn = url.openConnection()
conn.requestMethod = 'GET'
println conn.inputStream.text.take(200)
Разбор:
new URL('https://example.com')создаёт объект адреса, к которому будет выполняться запрос.url.openConnection()открывает соединение и возвращаетURLConnection(на HTTP это обычноHttpURLConnection).conn.requestMethod = 'GET'явно задаёт HTTP-метод запроса.conn.inputStream.textчитает тело ответа целиком как текст..take(200)берёт только первые 200 символов, чтобы не выводить слишком большой объём данных в консоль.println ...печатает результат и помогает быстро проверить, что соединение работает.
Полноценный desktop API-тестер (Swing, JMeter как HTTP-движок, заголовки, JSON, smoke-тест) — пошагово в Практикум — API-тестер на Groovy и JMeter.
Характерный пример — GString и замыкания
def greet = { name -> "Привет, $name!" }
['Анна', 'Борис'].each { println greet(it) }
Разбор:
def greet = { name -> ... }объявляет замыкание (closure) и сохраняет его в переменнойgreet.- Параметр
nameподставляется в GString через$name, поэтому возвращается персонализированная строка приветствия. - Список
['Анна', 'Борис']перебирается методомeach, который принимает замыкание-обработчик. - Внутри
eachпеременнаяit— текущий элемент списка;greet(it)вызывает ранее объявленное замыкание. printlnвыводит результат для каждого элемента, демонстрируя типичный функциональный стиль обработки коллекций в Groovy.
GString и each — типичный "скриптовый" стиль Groovy на JVM.
Дополнительные сниппеты
Аргументы командной строки
В скрипте без класса доступен массив args — как String[] в main у Java.
if (args.length == 0) {
println 'Использование: groovy sort-lines.groovy input.txt output.txt'
return
}
println "Входной файл: ${args[0]}"
Разбор:
args— встроенная переменная скрипта; элементы приходят из командной строки после имени файла.args.length == 0проверяет, что пользователь передал хотя бы один аргумент.returnв script mode завершает выполнение скрипта без явногоSystem.exit.- GString
"${args[0]}"подставляет первый переданный путь или имя файла.
Запуск: groovy sort-lines.groovy data.txt sorted.txt.
Построчный разбор лога
def logFile = new File('app.log')
def errors = logFile.readLines('UTF-8').findAll { it.contains('ERROR') }
errors.each { println it }
Разбор:
new File('app.log')ссылается на файл относительно текущей рабочей директории.readLines('UTF-8')читает все строки сразу вList<String>.findAll { it.contains('ERROR') }оставляет только строки с маркером ошибки.each { println it }выводит каждую подходящую строку;it— текущая строка списка.
Фильтр незавершённых задач (JSON-трекер)
def openTasks = load().findAll { !it.done }
println "Открыто: ${openTasks.size()}"
openTasks.each { println "- ${it.title}" }
Разбор:
load()(из примера выше) возвращает список карт с полямиid,title,done.findAll { !it.done }отбирает задачи, у которыхdoneложно (falseили отсутствует).openTasks.size()— число элементов в отфильтрованном списке.- В
eachобращениеit.titleиспользует property-стиль Groovy для ключей map.
Проверка калькулятора
assert calc(10, 2, '+') == 12
assert calc(10, 2, '-') == 8
assert calc(4, 2, '*') == 8
assert calc(10, 0, '/') == null
assert calc(1, 2, '%') == null
Разбор:
assertпрерывает выполнение, если условие ложно — удобно для быстрой самопроверки скрипта.- Сложение, вычитание и умножение проверяют обычные ветки
switch. calc(10, 0, '/')должен вернутьnull, потому что деление на ноль в примере запрещено.- Неизвестный оператор
%попадает вdefaultи тоже даётnull.
Дата в строке лога (регулярное выражение)
def line = '2026-05-28 14:02 ERROR payment failed'
def matcher = line =~ /\d{4}-\d{2}-\d{2}/
if (matcher) {
println "Дата в логе: ${matcher[0]}"
}
Разбор:
- Оператор
=~создаётMatcherдля поиска подстроки по шаблону. - Шаблон
\d{4}-\d{2}-\d{2}означает дату в форматеГГГГ-ММ-ДД. - В условии
if (matcher)matcher приводится к boolean:true, если совпадение найдено. matcher[0]— первое полное совпадение в строке.
Копирование файла одной строкой
def src = new File('input.txt')
def dst = new File('backup.txt')
dst.bytes = src.bytes
println "Скопировано ${src.length()} байт"
Разбор:
- Свойство
bytesуFileчитает или записывает содержимое файла как массив байтов. - Присваивание
dst.bytes = src.bytesкопирует файл целиком без ручного потока. src.length()возвращает размер исходного файла в байтах.- Подход годится для небольших файлов; для очень больших лучше потоковое копирование.
См. также: Gradle · Java — простые приложения
Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций. Сборка своего HTTP-клиента на Groovy — Практикум — API-тестер.