Рубрики
Без рубрики

Blade – Полный Путеводитель

Изучите полное руководство для крошечного фреймворка Java 8+ MVC под названием Blade.

Автор оригинала: Andrea Ligios.

1. Обзор

Blade -это крошечный фреймворк Java 8+ MVC, построенный с нуля с некоторыми четкими целями: быть самодостаточным, продуктивным, элегантным, интуитивно понятным и очень быстрым.

Множество различных фреймворков вдохновили его дизайн: Node Express , Python Flask и Golang Macaron //Martini .

Blade также является частью амбициозного более крупного проекта, Let’s Blade . Он включает в себя разнородную коллекцию других небольших библиотек, от генерации капчи до преобразования JSON, от шаблонов до простого подключения к базе данных.

Однако в этом уроке мы сосредоточимся только на MVC.

2. Начало работы

Прежде всего, давайте создадим пустой проект Maven и добавим последнюю зависимость Blade MVC в pom.xml :


    com.bladejava
    blade-mvc
    2.0.14.RELEASE

2.1. Комплектация Блейд-приложения

Поскольку наше приложение будет создано в виде БАНКИ, у него не будет папки /lib , как на ВОЙНЕ. В результате это приводит нас к проблеме, как обеспечить blade-mvc БАНОЧКА, вместе с любой другой баночкой, которая нам может понадобиться, в наше приложение.

Различные способы сделать это, каждый из которых имеет свои плюсы и минусы, описаны в руководстве “Как создать исполняемый файл JAR с помощью Maven”.

Для простоты мы будем использовать плагин сборки Maven technique , который взрывает любую банку, импортированную в pom.xml и впоследствии связывает все классы вместе в одну убер-банку.

2.2. Запуск блейд-приложения

Blade основан на Netty , удивительной асинхронной структуре сетевых приложений, управляемой событиями. Поэтому для запуска нашего блейд-приложения нам не нужен внешний сервер приложений или контейнер сервлетов; JRE будет достаточно:

java -jar target/sample-blade-app.jar

После этого приложение будет доступно по адресу http://localhost:9000 URL.

3. Понимание архитектуры

Архитектура Blade очень проста:

Он всегда следует одному и тому же жизненному циклу:

  1. Нетти получает запрос
  2. Выполняется промежуточное программное обеспечение (необязательно)
  3. Веб-крючки выполняются (необязательно)
  4. Выполняется маршрутизация
  5. Ответ отправляется клиенту
  6. Уборка

Мы рассмотрим вышеперечисленные функции в следующих разделах.

4. Маршрутизация

Короче говоря, маршрутизация в MVC-это механизм, используемый для создания привязки между URL-адресом и контроллером.

Blade предоставляет два типа маршрутов: базовый и аннотированный.

4.1. Основные маршруты

Основные маршруты предназначены для очень небольшого программного обеспечения, такого как микросервисы или минимальные веб-приложения:

Blade.of()
  .get("/basic-routes-example", ctx -> ctx.text("GET called"))
  .post("/basic-routes-example", ctx -> ctx.text("POST called"))
  .put("/basic-routes-example", ctx -> ctx.text("PUT called"))
  .delete("/basic-routes-example", ctx -> ctx.text("DELETE called"))
  .start(App.class, args);

Имя метода, используемого для регистрации маршрута, соответствует глаголу HTTP, который будет использоваться для пересылки запроса. Вот так просто.

В этом случае мы возвращаем текст, но мы также можем отображать страницы, как мы увидим позже в этом руководстве.

4.2. Аннотированные маршруты

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

Прежде всего, нам нужно создать контроллер через аннотацию @Path , которая будет сканироваться Blade во время запуска.

Затем нам нужно использовать аннотацию маршрута, связанную с методом HTTP, который мы хотим перехватить:

@Path
public class RouteExampleController {    
    
    @GetRoute("/routes-example") 
    public String get(){ 
        return "get.html"; 
    }
    
    @PostRoute("/routes-example") 
    public String post(){ 
        return "post.html"; 
    }
    
    @PutRoute("/routes-example") 
    public String put(){ 
        return "put.html"; 
    }
    
    @DeleteRoute("/routes-example") 
    public String delete(){ 
        return "delete.html"; 
    }
}

Мы также можем использовать простую аннотацию @Route и указать метод HTTP в качестве параметра:

@Route(value="/another-route-example", method=HttpMethod.GET) 
public String anotherGet(){ 
    return "get.html" ; 
}

С другой стороны, если мы не поставим какой-либо параметр метода, маршрут будет перехватывать каждый HTTP-вызов этого URL , независимо от глагола.

4.3. Ввод параметров

Существует несколько способов передачи параметров нашим маршрутам. Давайте рассмотрим их с некоторыми примерами из документации .

  • Параметр формы:
@GetRoute("/home")
public void formParam(@Param String name){
    System.out.println("name: " + name);
}
  • Параметр Restful:
@GetRoute("/users/:uid")
public void restfulParam(@PathParam Integer uid){
    System.out.println("uid: " + uid);
}
  • Параметр загрузки файла:
@PostRoute("/upload")
public void fileParam(@MultipartParam FileItem fileItem){
    byte[] file = fileItem.getData();
}
  • Параметр заголовка:
@GetRoute("/header")
public void headerParam(@HeaderParam String referer){
    System.out.println("Referer: " + referer);
}
  • Параметр Cookie:
@GetRoute("/cookie")
public void cookieParam(@CookieParam String myCookie){
    System.out.println("myCookie: " + myCookie);
}
  • Параметр тела:
@PostRoute("/bodyParam")
public void bodyParam(@BodyParam User user){
    System.out.println("user: " + user.toString());
}
  • Параметр объекта Value, вызываемый путем отправки его атрибутов на маршрут:
@PostRoute("/voParam")
public void voParam(@Param User user){
    System.out.println("user: " + user.toString());
}

5. Статические ресурсы

При необходимости Blade также может обслуживать статические ресурсы, просто поместив их в папку /resources/static .

Например, src/main/resources/static/app.css будет доступен по адресу http://localhost:9000/static/app.css .

5.1. Настройка путей

Мы можем настроить это поведение, добавив один или несколько статических путей программно:

blade.addStatics("/custom-static");

Тот же результат можно получить с помощью конфигурации, отредактировав файл src/main/resources/application.properties :

mvc.statics=/custom-static

5.2. Включение списка ресурсов

Мы можем разрешить отображение содержимого статической папки, функция по умолчанию отключена по соображениям безопасности:

blade.showFileList(true);

Или в конфигурации:

mvc.statics.show-list=true

Теперь мы можем открыть http://localhost:9000/custom-static/ для отображения содержимого папки.

5.3. Использование веб-сайтов

Как показано во введении к учебнику по WebJars, статические ресурсы, упакованные в JAR, также являются жизнеспособным вариантом.

Blade автоматически выставляет их под /webjars/ path.

Например, давайте импортируем Bootstrap в pom.xml :


    org.webjars
    bootstrap
    4.2.1

В результате он будет доступен в разделе http://localhost:9000/webjars/bootstrap/4.2.1/css/bootstrap.css

6. HTTP-запрос

Поскольку Blade не основан на спецификации сервлета , такие объекты, как его интерфейс Request и его класс HttpRequest , немного отличаются от тех, к которым мы привыкли.

6.1. Параметры формы

При чтении параметров формы Blade широко использует Java Optional в результатах методов запроса (все методы ниже возвращают объект Optional ):

  • запрос(имя строки)
  • запрос(имя строки)
  • запрос Lang(имя строки)
  • запрос Double(имя строки)

Они также доступны с резервным значением:

  • Строковый запрос(имя строки, значение по умолчанию строки)
  • int запрос Int(имя строки, значение по умолчанию int)
  • длинный запрос Long(имя строки, длинное значение по умолчанию)
  • двойной запрос Double(имя строки, двойное значение по умолчанию)

Мы можем прочитать параметр формы через свойство auto mapped:

@PostRoute("/save")
public void formParams(@Param String username){
    // ...
}

Или из Запроса объекта:

@PostRoute("/save")
public void formParams(Request request){
    String username = request.query("username", "Baeldung");
}

6.2. Данные JSON

Давайте теперь посмотрим, как объект JSON может быть сопоставлен с POJO:

curl -X POST http://localhost:9000/users -H 'Content-Type: application/json' \ 
  -d '{"name":"Baeldung","site":"baeldung.com"}'

POJO (аннотированный Ломбоком для удобства чтения):

public class User {
    @Getter @Setter private String name;
    @Getter @Setter private String site;
}

Опять же, значение доступно как введенное свойство:

@PostRoute("/users")
public void bodyParams(@BodyParam User user){
    // ...
}

И из Запроса :

@PostRoute("/users")
public void bodyParams(Request request) {
    String bodyString = request.bodyToString();
}

6.3. Параметры RESTful

Параметры RESTful в красивых URL-адресах, таких как localhost:9000/user/42 , также являются гражданами первого класса:

@GetRoute("/user/:id")
public void user(@PathParam Integer id){
    // ...
}

Как обычно, мы можем полагаться на объект Request , когда это необходимо:

@GetRoute("/user")
public void user(Request request){
    Integer id = request.pathInt("id");
}

Очевидно, что тот же метод доступен и для типов Long и Strong .

6.4. Привязка данных

Blade поддерживает параметры привязки JSON и формы и автоматически присоединяет их к объекту модели:

@PostRoute("/users")
public void bodyParams(User user){}

6.5. Атрибуты запроса и сеанса

API для чтения и записи объектов в Запросе и сеансе кристально чист.

Методы с двумя параметрами, представляющими ключ и значение, являются мутаторами, которые мы можем использовать для хранения наших значений в различных контекстах:

Session session = request.session();
request.attribute("request-val", "Some Request value");
session.attribute("session-val", 1337);

С другой стороны, те же методы, принимающие только ключевой параметр, являются аксессуарами:

String requestVal = request.attribute("request-val");
String sessionVal = session.attribute("session-val"); //It's an Integer

Интересной особенностью является их общий тип возврата T , который избавляет нас от необходимости приводить результат.

6.6. Заголовки

Заголовки запросов, напротив, могут быть прочитаны только из запроса:

String header1 = request.header("a-header");
String header2 = request.header("a-safe-header", "with a default value");
Map allHeaders = request.headers();

6.7. Коммунальные услуги

Следующие служебные методы также доступны из коробки, и они настолько очевидны, что не нуждаются в дальнейших объяснениях:

  • булева изи()
  • логическое значение isAjax()
  • Тип содержимого строки()
  • Агент пользователя строки()

6.8. Чтение файлов cookie

Давайте посмотрим, как объект Request помогает нам работать с файлами cookie, особенно при чтении Необязательного :

Optional cookieRaw(String name);

Мы также можем получить его в виде Строки , указав значение по умолчанию, которое будет применяться, если файл cookie не существует:

String cookie(String name, String defaultValue);

Наконец, именно так мы можем прочитать все файлы cookie сразу ( ключи – это имена файлов Cookie, значения – это значения файлов cookie):

Map cookies = request.cookies();

7. HTTP-ответ

Аналогично тому , что было сделано с Запросом , мы можем получить ссылку на объект Response , просто объявив его в качестве параметра метода маршрутизации:

@GetRoute("/")
public void home(Response response) {}

7.1. Простой вывод

Мы можем легко отправить простой вывод вызывающему абоненту с помощью одного из удобных методов вывода, а также 200 HTTP-кода и соответствующего типа контента.

Во-первых, мы можем отправить простой текст:

response.text("Hello World!");

Во-вторых, мы можем создать HTML:

response.html("

Hello World!

");

В-третьих, мы также можем сгенерировать XML:

response.xml("Hello World!");

Наконец, мы можем вывести JSON с помощью String :

response.json("{\"The Answer\":42}");

И даже из POJO, используя автоматическое преобразование JSON:

User user = new User("Baeldung", "baeldung.com"); 
response.json(user);

7.2. Вывод файлов

Загрузка файла с сервера не может быть проще:

response.download("the-file.txt", "/path/to/the/file.txt");

Первый параметр задает имя файла, который будет загружен, в то время как второй (объект File , здесь построенный с помощью String ) представляет путь к фактическому файлу на сервере.

7.3. Рендеринг шаблонов

Blade также может отображать страницы с помощью механизма шаблонов:

response.render("admin/users.html");

Каталог шаблонов по умолчанию- src/main/resources/templates/ , поэтому предыдущий однострочный файл будет искать файл src/main/resources/templates/admin/users.html .

Подробнее об этом мы узнаем позже, в разделе Templating .

7.4. Перенаправление

Перенаправление означает отправку 302 HTTP-кода в браузер вместе с URL-адресом, за которым следует второй GET.

Мы можем перенаправить на другой маршрут или на внешний URL-адрес:

response.redirect("/target-route");

7.5. Написание Файлов cookie

На данный момент мы должны привыкнуть к простоте Блейда. Таким образом, давайте посмотрим, как мы можем написать истекающий файл cookie в одной строке кода:

response.cookie("cookie-name", "Some value here");

Действительно, удалить файл cookie одинаково просто:

response.removeCookie("cookie-name");

7.6. Прочие Операции

Наконец, объект Response предоставляет нам несколько других методов для выполнения таких операций, как написание заголовков, настройка типа содержимого, настройка кода состояния и так Далее.

Давайте быстро взглянем на некоторые из них:

  • Статус ответа(int status)
  • Заголовки карт()
  • Ответ не Найден()
  • Файлы cookie карты()
  • Тип содержимого ответа(String ContentType)
  • пустое тело(@NonNull байт[] данных)
  • Заголовок ответа(имя строки, строковое значение)

8. Веб-крючки

WebHook-это перехватчик, с помощью которого мы можем запускать код до и после выполнения метода маршрутизации .

Мы можем создать WebHook, просто реализовав функциональный интерфейс WebHook и переопределив метод before() :

@FunctionalInterface
public interface WebHook {

    boolean before(RouteContext ctx);

    default boolean after(RouteContext ctx) {
        return true;
    }
}

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

8.1. Перехват Каждого Запроса

Аннотация @Bean указывает фреймворку сканировать класс с помощью контейнера IoC.

Веб-крючок, аннотированный им, следовательно, будет работать глобально, перехватывая запросы к каждому URL-адресу:

@Bean
public class BaeldungHook implements WebHook {

    @Override
    public boolean before(RouteContext ctx) {
        System.out.println("[BaeldungHook] called before Route method");
        return true;
    }
}

8.2. Сужение до URL-адреса

Мы также можем перехватывать определенные URL-адреса, чтобы выполнять код только вокруг этих методов маршрута:

Blade.of()
  .before("/user/*", ctx -> System.out.println("Before: " + ctx.uri()));
  .start(App.class, args);

8.3. Промежуточное программное обеспечение

Промежуточные программы являются приоритетными веб-крючками, которые выполняются перед любым стандартным веб-крючком:

public class BaeldungMiddleware implements WebHook {

    @Override
    public boolean before(RouteContext context) {
        System.out.println("[BaeldungMiddleware] called before Route method and other WebHooks");
        return true;
    }
}

Они просто должны быть определены без аннотации @Bean , а затем зарегистрированы декларативно через use() :

Blade.of()
  .use(new BaeldungMiddleware())
  .start(App.class, args);

Кроме того, Blade поставляется со следующим встроенным промежуточным программным обеспечением, связанным с безопасностью, имена которого должны быть понятны:

9. Конфигурация

В Blade конфигурация полностью необязательна, потому что все работает “из коробки” по соглашению. Однако мы можем настроить параметры по умолчанию и ввести новые атрибуты внутри файла src/main/resources/application.properties .

9.1. Чтение конфигурации

Мы можем прочитать конфигурацию по-разному, с указанием или без указания значения по умолчанию в случае, если параметр недоступен.

  • Во время запуска:
Blade.of()
  .on(EventType.SERVER_STARTED, e -> {
      Optional version = WebContext.blade().env("app.version");
  })
  .start(App.class, args);
  • Внутри маршрута:
@GetRoute("/some-route")
public void someRoute(){
    String authors = WebContext.blade().env("app.authors","Unknown authors");
}
  • В пользовательском загрузчике, реализуя интерфейс Blade Loader , переопределяя метод load() и аннотируя класс с помощью @Bean :
@Bean
public class LoadConfig implements BladeLoader {

    @Override
    public void load(Blade blade) {
        Optional version = WebContext.blade().env("app.version");
        String authors = WebContext.blade().env("app.authors","Unknown authors");
    }
}

9.2. Атрибуты конфигурации

Несколько параметров, уже настроенных, но готовых к настройке, сгруппированы по типу и перечислены по этому адресу в таблицах с тремя столбцами (имя, описание, значение по умолчанию). Мы также можем ссылаться на переведенную страницу , обращая внимание на то, что перевод ошибочно заглавными буквами называет имена настроек. Реальные настройки полностью строчные.

Группировка параметров конфигурации по префиксу делает их читаемыми сразу на карте, что полезно, когда их много:

Environment environment = blade.environment();
Map map = environment.getPrefix("app");
String version = map.get("version").toString();
String authors = map.get("authors","Unknown authors").toString();

9.3. Работа С Несколькими Средами

При развертывании нашего приложения в другой среде нам может потребоваться указать другие параметры, например те, которые связаны с подключением к базе данных. Вместо того, чтобы вручную заменять файл application.properties , Blade предлагает нам способ настройки приложения для различных сред. Мы можем просто сохранить application.properties со всеми настройками разработки, а затем создать другие файлы в той же папке, например application-prod.properties , содержащие только те настройки, которые отличаются .

Во время запуска мы можем указать среду, которую мы хотим использовать, и фреймворк объединит файлы , используя наиболее конкретные настройки из application-prod.properties и все остальные настройки из файла application.properties по умолчанию:

java -jar target/sample-blade-app.jar --app.env=prod

10. Создание шаблонов

Шаблонизация в Blade-это модульный аспект. Хотя он интегрирует очень простой механизм шаблонов, для любого профессионального использования представлений мы должны полагаться на внешний механизм шаблонов. Затем мы можем выбрать движок из доступных в репозитории blade-template-engine на GitHub, которые являются FreeMarker , Jetbrick , Pebble и Velocity , или даже создать оболочку для импорта другого шаблона , который нам нравится.

Автор Блейда предлагает Jetbrick , еще один умный китайский проект.

10.1. Использование движка по умолчанию

Шаблон по умолчанию работает путем анализа переменных из разных контекстов с помощью нотации ${} :

Hello, ${name}!

10.2. Подключение внешнего двигателя

Переход на другой движок шаблонов-это легкий ветерок! Мы просто импортируем зависимость (оболочку лезвия) двигателя:


    com.bladejava
    blade-template-jetbrick
    0.1.3

На этом этапе достаточно написать простую конфигурацию, чтобы указать фреймворку использовать эту библиотеку:

@Bean
public class TemplateConfig implements BladeLoader {

    @Override
    public void load(Blade blade) {
        blade.templateEngine(new JetbrickTemplateEngine());
    }
}

В результате теперь каждый файл в src/main/resources/templates/ будет анализироваться с помощью нового движка, синтаксис которого выходит за рамки этого руководства.

10.3. Упаковка нового двигателя

Для создания нового механизма шаблонов требуется создать один класс, который должен реализовать интерфейс Template Engine и переопределить метод render() :

void render (ModelAndView modelAndView, Writer writer) throws TemplateException;

Для этой цели мы можем взглянуть на код фактической обертки Jetbrick , чтобы получить представление о том, что это значит.

11. Ведение журнала

Blade использует slf4j-api в качестве интерфейса ведения журнала.

Он также включает в себя уже настроенную реализацию ведения журнала, называемую blade-log . Поэтому нам не нужно ничего импортировать; он работает как есть, просто определяя Logger :

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

11.1. Настройка встроенного регистратора

Если мы хотим изменить конфигурацию по умолчанию, нам необходимо настроить следующие параметры в качестве системных свойств:

  • Уровни ведения журнала (могут быть “трассировка”, “отладка”, “информация”, “предупреждение” или “ошибка”):
# Root Logger
com.blade.logger.rootLevel=info

# Package Custom Logging Level
com.blade.logger.somepackage=debug

# Class Custom Logging Level
com.blade.logger.com.baeldung.sample.SomeClass=trace
  • Отображаемая информация:
# Date and Time
com.blade.logger.showDate=false

# Date and Time Pattern
com.blade.logger.datePattern=yyyy-MM-dd HH:mm:ss:SSS Z

# Thread Name
com.blade.logger.showThread=true

# Logger Instance Name
com.blade.logger.showLogName=true

# Only the Last Part of FQCN
com.blade.logger.shortName=true
  • Лесоруб:
# Path 
com.blade.logger.dir=./logs

# Name (it defaults to the current app.name)
com.blade.logger.name=sample

11.2. За исключением Встроенного регистратора

Хотя наличие уже настроенного встроенного регистратора очень удобно для запуска нашего небольшого проекта, мы можем легко оказаться в случае, когда другие библиотеки импортируют свою собственную реализацию ведения журнала. И в этом случае мы можем удалить интегрированный, чтобы избежать конфликтов:


    com.bladejava
    blade-mvc
    ${blade.version}
    
        
            com.bladejava
            blade-log
        
    

12. Настройка

12.1. Пользовательская обработка Исключений

По умолчанию в фреймворк также встроен обработчик исключений. Он выводит исключение на консоль, и если app.dev Mode является true , трассировка стека также отображается на веб-странице.

Однако мы можем обработать исключение определенным образом, определив @Bean , расширяющий класс DefaultExceptionHandler :

@Bean
public class GlobalExceptionHandler extends DefaultExceptionHandler {

    @Override
    public void handle(Exception e) {
        if (e instanceof BaeldungException) {
            BaeldungException baeldungException = (BaeldungException) e;
            String msg = baeldungException.getMessage();
            WebContext.response().json(RestResponse.fail(msg));
        } else {
            super.handle(e);
        }
    }
}

12.2. Пользовательские страницы Ошибок

Аналогично, ошибки 404 – Не найдено и 500 – Внутренняя ошибка сервера обрабатываются через страницы по умолчанию.

Мы можем заставить фреймворк использовать наши собственные страницы, объявив их в файле application.properties со следующими настройками:

mvc.view.404=my-404.html
mvc.view.500=my-500.html

Конечно, эти HTML-страницы должны быть помещены в папку src/main/resources/templates .

Кроме того, в пределах 500 мы можем получить исключение сообщение и трассировку стека через их специальные переменные:




    
        
        500 Internal Server Error
    
    
        

Custom Error 500 Page

The following error occurred: "${message}"

 ${stackTrace} 

13. Запланированные задачи

Еще одной интересной особенностью фреймворка является возможность планирования выполнения метода.

Это возможно, если аннотировать метод класса @Bean аннотацией @Schedule :

@Bean
public class ScheduleExample {

    @Schedule(name = "baeldungTask", cron = "0 */1 * * * ?")
    public void runScheduledTask() {
        System.out.println("This is a scheduled Task running once per minute.");
    }
}

Действительно, он использует классические выражения cron для указания Даты, времени координат. Мы можем прочитать больше о них в Руководство по выражениям Cron .

Позже мы могли бы использовать статические методы класса Диспетчер задач для выполнения операций с запланированными задачами.

  • Получить все запланированные задачи:
List allScheduledTasks = TaskManager.getTasks();
  • Получить задачу по имени:
Task myTask = TaskManager.getTask("baeldungTask");
  • Остановите задачу по имени:
boolean closed = TaskManager.stopTask("baeldungTask");

14. События

Как уже было показано в разделе 9.1, можно прослушивать указанное событие перед запуском некоторого пользовательского кода.

Blade предоставляет следующие события из коробки:

public enum EventType {
    SERVER_STARTING,
    SERVER_STARTED,
    SERVER_STOPPING,
    SERVER_STOPPED,
    SESSION_CREATED,
    SESSION_DESTROY,
    SOURCE_CHANGED,
    ENVIRONMENT_CHANGED
}

В то время как первые шесть легко угадать, последние два нуждаются в некоторых подсказках: ENVIRONMENT_CHANGED позволяет нам выполнить действие, если файл конфигурации изменяется, когда сервер работает. SOURCE_CHANGED , вместо этого, еще не реализован и предназначен только для использования в будущем.

Давайте посмотрим, как мы можем поместить значение в сеанс всякий раз, когда он создается:

Blade.of()
  .on(EventType.SESSION_CREATED, e -> {
      Session session = (Session) e.attribute("session");
      session.attribute("name", "Baeldung");
  })
  .start(App.class, args);

15. Реализация сессии

Говоря о сеансе, его реализация по умолчанию хранит значения сеанса в памяти.

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

Тогда это будет всего лишь вопрос того, чтобы дать фреймворку понять, что мы хотим его использовать. Мы можем сделать это так же, как и для пользовательского движка шаблонов, с той лишь разницей, что мы вызываем метод sessionType() :

@Bean
public class SessionConfig implements BladeLoader {
 
    @Override
    public void load(Blade blade) {
        blade.sessionType(new RedisSession());
    }
}

16. Аргументы командной строки

При запуске Blade из командной строки есть три параметра, которые мы можем указать, чтобы изменить его поведение.

Во-первых, мы можем изменить IP-адрес, который по умолчанию является локальным 0.0.0.0 петлевая обратная связь:

java -jar target/sample-blade-app.jar --server.address=192.168.1.100

Во-вторых, мы также можем изменить порт, который по умолчанию 9000 :

java -jar target/sample-blade-app.jar --server.port=8080

Наконец, как показано в разделе 9.3, мы можем изменить среду, чтобы разрешить чтение другого файла application-XXX.properties поверх файла по умолчанию, который является application.properties :

java -jar target/sample-blade-app.jar --app.env=prod

17. Запуск ИДЕИ

Любая современная Java IDE способна воспроизводить блейд-проект, даже не нуждаясь в плагинах Maven. Запуск блейда в среде IDE особенно полезен при запуске демо-версий Blade , примеров, написанных специально для демонстрации функциональных возможностей фреймворка. Все они наследуют родительский pom, поэтому проще позволить IDE выполнять работу, а не вручную настраивать их для запуска в качестве автономных приложений.

17.1. Затмение

В Eclipse достаточно щелкнуть правой кнопкой мыши по проекту и запустить Запуск от имени Java-приложения , выбрать наш App класс и нажать OK .

Консоль Eclipse, однако, не будет корректно отображать цвета ANSI, вместо этого выливая их коды:

К счастью, установка ANSI Escape в консоли расширение исправляет проблему навсегда:

17.2. ИДЕЯ IntelliJ

IntelliJ IDEA работает с цветами ANSI из коробки. Поэтому достаточно создать проект, щелкнуть правой кнопкой мыши на файле App и запустить Запустить ‘App.main()’ (что эквивалентно нажатию Ctrl+Shift+F10 ):

17.3. Код Visual Studio

Также можно использовать VSCode, популярную не ориентированную на Java IDE, предварительно установив пакет расширений Java .

Нажатие Ctrl+F5 приведет к запуску проекта:

18. Заключение

Мы видели, как использовать Blade для создания небольшого приложения MVC.

Вся документация доступна только на китайском языке. Несмотря на широкое распространение в основном в Китае, благодаря его китайскому происхождению , автор недавно перевел API и задокументировал основные функциональные возможности проекта на английском языке на GitHub .

Как всегда, мы можем найти исходный код примера на GitHub .