Как я могу получить текущий URL-адрес страницы в Spring Boot 2 WebFlux Thymeleaf, чтобы установить активную ссылку css

Привет, у меня есть шаблон, который использует макет по умолчанию и fragemnt для заголовка и меню. Что я пытаюсь сделать, так это определить текущий URL-адрес страницы, чтобы я мог добавить требуемый css для отображения активного.

Я пробовал th: classappend = "@ {''} == 'find-all'? 'Active': ''", однако при этом текущий путь всегда отображается как пустой (т.е. текущая страница). Я также пробовал $ {# request.getCurrentPath} с ошибкой, говорящей, что не могу найти значение или имеет значение null.

URL-адрес / find-all, поэтому он должен обнаружить это и применить CSS, но, похоже, он не работает.

Код фрагмента html приведен ниже:

<div class = "header" th:fragment = "header">
<nav class = "navbar navbar-expand-md navbar-dark bg-dark">
    <a class = "navbar-brand" th:href = "@{/}">Time Keeping/Time Sheets</a>
    <button class = "navbar-toggler" type = "button" data-toggle = "collapse" data-target = "#navbar" aria-controls = "navbar"
            aria-expanded = "false" aria-label = "Toggle navigation">
        <span class = "navbar-toggler-icon"></span>
    </button>

    <div class = "collapse navbar-collapse" id = "navbar">
        <ul class = "navbar-nav mr-auto">
            <li class = "nav-item" th:classappend = "@{''} == 'find-all'? 'active': ''">
                <a class = "nav-link" th:href = "@{/find-all}">Find All</a>
            </li>
            <li class = "nav-item">
                <a class = "nav-link" th:href = "@{/add-new-entry}">Add new Time Entry</a>
            </li>
        </ul>
    </div>
</nav>

Снайпер зависимостей Maven,

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <dependency>
        <groupId>nz.net.ultraq.thymeleaf</groupId>
        <artifactId>thymeleaf-layout-dialect</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
    </dependency>
    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

Как указано ниже, это только один из используемых контроллеров.

@Controller
public class HomeController {

  private static final String currentMonthName = LocalDateTime.now().getMonth().getDisplayName(TextStyle.FULL, Locale.ENGLISH);
  private final TimeKeepingEntryService service;

  public HomeController(TimeKeepingEntryService service) {
    this.service = service;
  }

  @GetMapping("/")
  public Mono<String> index(Model model) {
    model.addAttribute("metaTitle", "Time Keeping Application");
    model.addAttribute("month", currentMonthName);
    model.addAttribute("timeEntries",   service.findByMonth(currentMonthName));
    return Mono.just("index");
  }
}
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
2
0
1 171
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

th:value = "${T(org.springframework.web.servlet.support.ServletUriComponentsBuilder).fromCurrentRequest()}"

Обновлять

Поскольку получение текущего URL-адреса с помощью Thymeleaf, похоже, не работает, мы могли бы найти обходной путь. Мы могли бы получить текущий наш текущий URL-адрес в нашем @Controller и отправить его через атрибут. Этого можно добиться с помощью HttpServletRequest. Код будет выглядеть примерно так, как показано ниже.

@GetMapping("/")
  public Mono<String> index(Model model, HttpServletRequest request) {
    model.addAttribute("metaTitle", "Time Keeping Application");
    model.addAttribute("month", currentMonthName);
    model.addAttribute("timeEntries", service.findByMonth(currentMonthName));
    model.addAttribute("currentUrl", request.getRequestURL().toString());
    return Mono.just("index");
  }

Теперь все, что вам нужно сделать, это использовать этот новый атрибут в своем шаблоне.

<p th:text = "${currentUrl}"></p>

Обновление 2

Поскольку ни один из последних вариантов не работал, вы можете попробовать использовать jQuery.

$(document).ready(function() {
    var url = $(location).attr('href');
    $("#id").text(url);
})
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p id = "id"></p>

Привет, я получаю следующую ошибку org.springframework.expression.spel.SpelEvaluationException: EL1005E: Тип не может быть найден 'org.springframework.web.servlet.support.ServletUriComponent‌ sBuilder' в org.springframework.expression.spel.support.Stoc tor.findType (Standar‌ dTypeLocator.java:11‌ 7) ~ [spring-expression-5.0.9.RELEASE.jar: 5.0.9.RELEASE] в org.springframework.expression.spel.ExpressionState.findType‌ (ExpressionState. jav‌ a: 155) ~ [spring-expression-5.0.9.RELEASE.jar: 5.0.9.RELEASE] в org.springframework.expression.spel.ast.TypeReference.getVal‌ ueInternal (TypeRefer‌ ence.java:68 )

D. Beer 31.10.2018 00:56

Вы пробовали с ${#httpServletRequest.requestURI}?

Alain Cruz 31.10.2018 02:50

Да, я получаю следующую ошибку. org.springframework.expression.spel.SpelEvaluationException: EL1007E: свойство или поле 'requestURI' не может быть найдено в null

D. Beer 31.10.2018 19:55

Вы не возражаете добавить свой метод @Controller, который загружает эту страницу? Похоже, проблема в вашем HttpServletRequest.

Alain Cruz 31.10.2018 20:06

Я добавил контроллер для индексной страницы, также он построен с использованием макетов Thymeleaf.

D. Beer 31.10.2018 20:16

Привет, Ален, спасибо за обновление, у меня нет HttpServletRequest из-за использования netty по умолчанию с webflux. Я пробовал HttpServerRequest и т. д. И не нашел конструктора defualt.

D. Beer 31.10.2018 23:12

Я добавил опцию с использованием jQuery, она должна работать, так как вам ничего не нужно из Spring.

Alain Cruz 31.10.2018 23:43

Трюк с jquery позволил мне получить URL-адрес страницы и добавить активный класс в правый пункт меню.

D. Beer 01.11.2018 14:16

Превосходно! Рад, что смог помочь!

Alain Cruz 01.11.2018 15:05

С Thymeleaf 3.0.x вы можете использовать:

 ${#ctx.getRequest().getPath()}

К сожалению, пока я не вижу абстракции для mvc и webflux.

Другие вопросы по теме