Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
I den här självstudien använder du en variantfunktionsflagga för att hantera upplevelser för olika användarsegment i ett exempelprogram, Quote of the Day. Du använder den variantfunktionsflagga som skapats i Använd variantfunktionsflaggor. Innan du fortsätter måste du skapa variantfunktionsflaggan Greeting i din App Configuration-butiken.
Förutsättningar
- Ett Java Development Kit (JDK) som stöds med version 17 eller senare.
- Apache Maven version 3.0 eller senare.
- Följ tutorialen Använd variantfunktionsflaggor och skapa variantfunktionsflaggan Greeting (Hälsning).
Konfigurera en Spring Boot-webbapp
Om du redan har en Spring Boot-webbapp med autentisering kan du gå vidare till avsnittet Använd variantfunktionsflaggan .
Bläddra till Spring Initializr och skapa ett nytt projekt med följande alternativ:
- Generera ett Maven--projekt med Java-.
- Ange en Spring Boot-version som är 3.0 eller senare.
- Ange Gruppen till
com.exampleoch Artefakt tillquoteoftheday. - Lägg till Spring Web- och Thymeleaf-beroenden .
När du har angett alternativen väljer du Generera för att ladda ned projektet. Extrahera filerna till ditt lokala system.
Skapa appen Citat för dagen
Skapa en ny fil med namnet Quote.java i
src/main/java/com/example/quoteofthedaymappen med följande innehåll. Den definierar en dataklass för citattecken.package com.example.quoteoftheday; public record Quote(String message, String author) { }Skapa en ny fil med namnet HomeController.java med följande innehåll. Den hanterar startsidans visning med ett slumpmässigt citat.
package com.example.quoteoftheday; import java.util.List; import java.util.Random; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @Controller public class HomeController { private final List<Quote> quotes = List.of( new Quote("You cannot change what you are, only what you do.", "Philip Pullman")); private final Random random = new Random(); @GetMapping("/") public String index(Model model) { String greetingMessage = "Hi"; model.addAttribute("greetingMessage", greetingMessage); model.addAttribute("quote", quotes.get(random.nextInt(quotes.size()))); return "index"; } }Skapa mallkatalogen på
src/main/resources/templatesoch lägg till en ny fil med namnet index.html med följande innehåll:<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>QuoteOfTheDay</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous"> <link rel="stylesheet" th:href="@{/css/site.css}"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"> </head> <body> <header> <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3"> <div class="container"> <a class="navbar-brand" href="/">QuoteOfTheDay</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target=".navbar-collapse" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> </div> </nav> </header> <div class="container"> <main role="main" class="pb-3"> <div class="quote-container"> <div class="quote-content"> <h3 class="greeting-content" th:if="${greetingMessage}" th:text="${greetingMessage}"></h3> <br /> <p class="quote">"<span th:text="${quote.message}"></span>"</p> <p>- <b th:text="${quote.author}"></b></p> </div> <div class="vote-container"> <button class="btn btn-primary" onclick="heartClicked(this)"> <i class="far fa-heart"></i> </button> </div> </div> </main> </div> <footer class="border-top footer text-muted"> <div class="container"> © 2024 - QuoteOfTheDay </div> </footer> <script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script> <script> function heartClicked(button) { var icon = button.querySelector('i'); icon.classList.toggle('far'); icon.classList.toggle('fas'); } </script> </body> </html>Skapa katalogen static/css på
src/main/resources/static/cssoch lägg till en ny fil med namnet site.css med följande innehåll:html { font-size: 14px; } @media (min-width: 768px) { html { font-size: 16px; } } .btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus { box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb; } html { position: relative; min-height: 100%; } body { margin-bottom: 60px; } body { font-family: Arial, sans-serif; background-color: #f4f4f4; color: #333; } .quote-container { background-color: #fff; margin: 2em auto; padding: 2em; border-radius: 8px; max-width: 750px; box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2); display: flex; justify-content: space-between; align-items: start; position: relative; } .vote-container { position: absolute; top: 10px; right: 10px; display: flex; gap: 0em; } .vote-container .btn { background-color: #ffffff; border-color: #ffffff; color: #333 } .vote-container .btn:focus { outline: none; box-shadow: none; } .vote-container .btn:hover { background-color: #F0F0F0; } .greeting-content { font-family: 'Georgia', serif; } .quote-content p.quote { font-size: 2em; font-family: 'Georgia', serif; font-style: italic; color: #4EC2F7; }Uppdatera filen application.properties på
src/main/resources/application.propertiesmed följande innehåll:spring.application.name=quoteoftheday
Använd variantfunktionsflaggan
Öppna filenpom.xml och lägg till följande beroenden för Azure App Configuration och funktionshantering:
<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-starter-appconfiguration-config</artifactId> </dependency> <dependencyManagement> <dependencies> <dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-cloud-azure-dependencies</artifactId> <version>7.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>Uppdatera filen application.properties på
src/main/resources/application.propertiesför att lägga till Inställningar för Azure App Configuration:Du kan ansluta till din App Configuration-butik med hjälp av Microsoft Entra-ID (rekommenderas) eller en anslutningssträng.
spring.config.import=azureAppConfiguration spring.cloud.azure.appconfiguration.stores[0].endpoint=${APP_CONFIGURATION_ENDPOINT} spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled=trueDu använder
DefaultAzureCredentialför att autentisera mot din App Configuration-butik. Följ anvisningarna för att tilldela dina autentiseringsuppgifter rollen App Configuration Data Reader . Se till att ge tillräckligt med tid för att behörigheten ska spridas innan du kör programmet.Skapa en ny fil med namnet QueryStringTargetingContextAccessor.java för att ange målkontexten för den aktuella användaren:
package com.example.quoteoftheday; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.azure.spring.cloud.feature.management.targeting.TargetingContext; import com.azure.spring.cloud.feature.management.targeting.TargetingContextAccessor; @Component public class QueryStringTargetingContextAccessor implements TargetingContextAccessor { @Override public void configureTargetingContext(TargetingContext context) { ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder .getRequestAttributes(); if (attributes != null) { String userId = attributes.getRequest().getParameter("userId"); if (userId != null) { context.setUserId(userId); } } } }Uppdatera HomeController.java för att använda variantfunktionsflaggan:
package com.example.quoteoftheday; import java.util.List; import java.util.Random; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import com.azure.spring.cloud.feature.management.FeatureManager; import com.azure.spring.cloud.feature.management.models.Variant; @Controller public class HomeController { private static final Logger LOGGER = LoggerFactory.getLogger(HomeController.class); private final FeatureManager featureManager; private final List<Quote> quotes = List.of( new Quote("You cannot change what you are, only what you do.", "Philip Pullman")); private final Random random = new Random(); public HomeController(FeatureManager featureManager) { this.featureManager = featureManager; } @GetMapping("/") public String index(Model model) { // Get the variant for the Greeting feature flag String greetingMessage = ""; Variant variant = featureManager.getVariant("Greeting"); if (variant != null) { Object value = variant.getValue(); if (value != null) { greetingMessage = value.toString(); } } else { LOGGER.warn( "No variant given. Either the feature flag named 'Greeting' is not defined or the variants are not defined properly."); } model.addAttribute("greetingMessage", greetingMessage); model.addAttribute("quote", quotes.get(random.nextInt(quotes.size()))); return "index"; } }
Skapa och köra appen
Ange en miljövariabel.
Ange miljövariabeln med namnet APP_CONFIGURATION_ENDPOINT till slutpunkten för din App Configuration-lagring som finns under Översikt i Azure-portalen.
Om du använder Windows-kommandotolken kör du följande kommando och startar om kommandotolken så att ändringen börjar gälla:
setx APP_CONFIGURATION_ENDPOINT "<endpoint-of-your-app-configuration-store>"Om du använder PowerShell kör du följande kommando:
$Env:APP_CONFIGURATION_ENDPOINT = "<endpoint-of-your-app-configuration-store>"Om du använder macOS eller Linux kör du följande kommando:
export APP_CONFIGURATION_ENDPOINT='<endpoint-of-your-app-configuration-store>'Skapa och kör ditt Spring Boot-program med Maven:
mvn clean package mvn spring-boot:runVänta tills appen startas och öppna sedan en webbläsare och navigera till
http://localhost:8080/. Du bör se standardvyn för appen som inte har något hälsningsmeddelande.
Du kan använda
userIdfrågeparametern i URL:en för att ange användar-ID:t. Besöklocalhost:8080/?userId=UserAoch du ser ett långt hälsningsmeddelande.
Prova olika användar-ID:er för att se hur variantfunktionsflaggan ändrar hälsningsmeddelandet för olika användarsegment. Besök
localhost:8080/?userId=UserBoch du ser ett kortare hälsningsmeddelande.
Nästa steg
Den fullständiga funktionskörningen av Spring Boot-funktionshanteringsbiblioteket finns i följande dokument.