在本教程中,你將創(chuàng)建一個 CoffeeBot 應用程序。該應用程序就像機器人咖啡機的控制器。遺憾的是,它實際上不會為你提供咖啡,但它將演示大量有用的編程技術。該應用程序將有一個 Vue.js 客戶端和一個 Spring Boot 資源服務器。它將使用 JHipster 進行引導,節(jié)省大量時間并演示一些最佳實踐,包括在客戶端和服務器中自動配置端到端 JWT 身份驗證。你還將使用 Split 來展示如何分別使用 Split 的 Javascript SDK 和 Java SDK 在運行時動態(tài)地使用功能標志來管理前端和后端的功能集。
該應用程序本身提供飲料。服務器維護著一份飲料清單,主要是咖啡,附有尺寸、價格和名稱。為簡單起見,飲料列表將使用內存中的開發(fā)數(shù)據(jù)庫進行保存,但如果需要,可以輕松地重新配置以實現(xiàn)持久性??蛻舳藦姆掌髡埱箫嬃狭斜?,如果用戶通過身份驗證,則傳遞任何身份驗證數(shù)據(jù)。
客戶端接收此列表并將飲料列表顯示為按鈕列表。第二次分割純粹與客戶有關。添加了一項新功能:能夠在飲料中添加奶油。正如你可以想象的那樣,考慮到人們對咖啡中奶油的喜愛程度,虛擬騷亂已經(jīng)開始要求此功能。人們在叫嚷。但經(jīng)理們希望在廣泛發(fā)布之前確保奶油功能正常工作(CoffeeBot 有時會失靈)。因此,根據(jù)經(jīng)過身份驗證的用戶,添加奶油的能力被切換。你可以在這個鏈接:
看到如何使用 Split 的 Javascript SDK 來控制客戶端的奶油功能,以及如何使用 Split 的 Java SDK 來控制服務器的飲料列表
Java + Vue.js 教程依賴項
Java:我在本教程中使用了 Java 12。你可以訪問AdaptOpenJdk 網(wǎng)站下載并安裝 Java ?;蛘吣憧梢允褂肧DKMAN甚至Homebrew等版本管理器。
Node:按照 Node網(wǎng)站上的說明安裝 Node 。本教程是使用 Node 12.14.0 編寫的。
JHipster:一旦安裝了 Java 和 Node,就可以安裝 JHipster。按照其網(wǎng)站上的說明進行操作(如果出現(xiàn)問題,有助于排除故障)或只需運行此命令:npm install -g generator-jhipster@6.9.0使用npm.
拆分:如果你還沒有免費的拆分帳戶,請注冊一個。這就是實現(xiàn)功能標志的方式。
使用 JHipster 引導你的 Spring Boot 應用程序
要創(chuàng)建示例 CoffeBot 應用程序,你將使用 JHipster。正如其網(wǎng)站上所述,“JHipster 是一個快速生成、開發(fā)和部署現(xiàn)代 Web 應用程序和微服務架構的開發(fā)平臺?!?它允許你快速啟動具有各種前端和服務器配置的基于 Java 的項目。本教程將使用 Vue.js。
JHipster 的優(yōu)點之一是它為你創(chuàng)建了一個包含 Java 服務器應用程序和 Vue.js 前端應用程序的組合項目。它還包括將創(chuàng)建數(shù)據(jù)模型實體和 Web 服務控制器的生成器。它做了很多事情并創(chuàng)建了很多文件。如果你對這些平臺相對陌生,那么項目結構可能看起來有點令人難以承受,但他們在網(wǎng)站上記錄了所有內容,做得很好。他們布置的項目遵循當前的最佳實踐,因此它是一個很好的學習工具。
打開 shell 并為你的項目創(chuàng)建一個根目錄,例如 CoffeeBotApp.
導航到該目錄。你將在此處生成項目文件。
通常,當你運行 JHipster 時,它會詢問你許多有關你正在引導的項目的問題。但是,為了簡化事情,你將使用此.yo-rc.json文件來預先配置項目,從而繞過詢問。
在根項目目錄中,創(chuàng)建一個.yo-rc.json包含以下內容的文件。此配置的一些亮點是:
applicationType:整體應用程序:典型的標準應用程序(本質上不是微服務)
baseName : coffeebot– 應用程序的名稱
packageName : com.split.coffeebot– 基礎 Java 包
authenticationType : jwt– JSON Web 令牌身份驗證
devDatabaseType : h2Memory– 開發(fā)數(shù)據(jù)庫使用內存中的 H2 數(shù)據(jù)庫,該數(shù)據(jù)庫不會跨會話持久化
**clientFramework **: vue– 使用Vue.js作為前端客戶端框架
SkipFakeData : true– JHipster 默認情況下會為數(shù)據(jù)模型生成一組隨機的假數(shù)據(jù),我們希望在本教程中跳過這些數(shù)據(jù)
有很多選擇。請參閱文檔以深入了解這一點。
{
"generator-jhipster": {
"promptValues": {
"packageName": "com.split.coffeebot"
},
"jhipsterVersion": "6.9.0",
"applicationType": "monolith",
"baseName": "coffeebot",
"packageName": "com.split.coffeebot",
"packageFolder": "com/split/coffeebot",
"serverPort": "8080",
"authenticationType": "jwt",
"cacheProvider": "ehcache",
"enableHibernateCache": true,
"websocket": false,
"databaseType": "sql",
"devDatabaseType": "h2Memory",
"prodDatabaseType": "mysql",
"searchEngine": false,
"messageBroker": false,
"serviceDiscoveryType": false,
"buildTool": "gradle",
"enableSwaggerCodegen": false,
"jwtSecretKey": "ZDg4ZjkzMDJkNWQ4YWJlMjUxOTY3YjE1MDNjY2ZkMzJjYWQwYjJiOTkyMWQ3YTE5ZTgwNWY3Y2E1ZDg0OWViZjM0Nzg1NDE3MjNlMGY1MDBkNTg4YWU1MmZmNTU1ZGEzOTJiMTVlMWZjZDc5NDUyMTlmZmRmYTU0NDJjMDdiODA=",
"embeddableLaunchScript": false,
"useSass": true,
"clientPackageManager": "npm",
"clientFramework": "vue",
"clientTheme": "none",
"clientThemeVariant": "",
"creationTimestamp": 1601147759112,
"testFrameworks": [],
"jhiPrefix": "jhi",
"entitySuffix": "",
"dtoSuffix": "DTO",
"otherModules": [
{
"name": "generator-jhipster-vuejs",
"version": "1.8.0"
}
],
"enableTranslation": false,
"blueprints": [
{
"name": "generator-jhipster-vuejs",
"version": "1.8.0"
}
],
"skipFakeData": true
}
}
通過運行以下命令(在包含該文件的根項目目錄中.yo-rc.json)創(chuàng)建入門應用程序。
jhipster
當 JHipster 創(chuàng)建項目時,你將看到大量控制臺輸出。它應該以以下行結束。
INFO! Congratulations, JHipster execution is complete!
代碼語言: Swift (斯威夫特)
JHipster 已經(jīng)創(chuàng)建了一個 Git 存儲庫并進行了初始提交。此時,你可以通過打開兩個 shell(一個用于客戶端,一個用于服務器)并運行以下命令來運行入門應用程序。
Spring Boot 服務器:
./gradlew
Vue.js 客戶端:
npm start
生成 Spring Boot 數(shù)據(jù)模型
現(xiàn)在你想要使用 JHipster 生成數(shù)據(jù)模型或實體。它們定義了將存儲在數(shù)據(jù)庫中并由 REST 服務提供服務的數(shù)據(jù)結構。當你使用 JHipster 的生成器創(chuàng)建實體時,JHipster 和 Spring 會為你完成許多出色的幕后工作。它創(chuàng)建表示數(shù)據(jù)結構的 Java 類,并使用允許將數(shù)據(jù)保存到數(shù)據(jù)庫的 JPA 注釋進行注釋。它還創(chuàng)建一個實現(xiàn)創(chuàng)建、讀取、更新和刪除 (CRUD) 功能的資源文件,該文件會自動受到所選身份驗證方案(在我們的示例中為 JWT)的保護。
在前端,生成器創(chuàng)建必要的文件,允許你與實體的資源服務器進行交互,以及前端文件來創(chuàng)建、更新和檢查持久數(shù)據(jù)實體(要訪問它,你必須以管理員用戶身份登錄)。
在項目根目錄中,創(chuàng)建一個新文件:entities.jdl. 該文件定義了一種具有四個屬性的實體類型,以及該實體中使用的枚舉類型。
enum DrinkSize {
Small,
Medium,
Large,
XLarge,
XXLarge
}
entity Drink {
name String required,
size DrinkSize required,
caffeineMilligrams Integer required,
priceDollars Integer required,
}
通過運行生成實體文件:
jhipster import-jdl entities.jdl
當它詢問你是否覆蓋文件時,只需鍵入ato?overwrite this and all others。
現(xiàn)在是運行入門應用程序并探索引導功能的好時機。請記住,你需要運行兩個不同的進程。
** Spring Boot Java 服務器**```
./gradlew
Vue.js 客戶端(你可能需要等待一分鐘左右服務器才能完成運行):
npm start
客戶端應用程序應自動打開。如果沒有,請打開 http://localhost:9000
使用默認憑據(jù)以管理員用戶身份登錄admin:admin。查看“管理”菜單下的所有功能。另請查看“實體”菜單。你可以在此處查看、添加和更新你創(chuàng)建的實體。在我們的例子中,這是Drink實體,它有四個屬性:name、size、caffeine mgs和Price Dollars。
Vue.js 客戶端使用 TypeScript 和類組件,并將模板和組件聲明拆分為兩個單獨的文件。如果你習慣于更傳統(tǒng)的.vue單文件結構,一開始這可能看起來有點奇怪,但大多數(shù)差異都是不言自明的。如果你需要幫助,請查看文檔中的官方頁面以獲取更多信息。
將功能標志添加到你的 Spring Boot Java 服務器
你將使用 Split 在客戶端和服務器上實現(xiàn)功能標志。你應該已經(jīng)注冊了一個免費帳戶(如果沒有,請立即注冊)。目前,你要將 Java Split SDK 集成到 Spring Boot 應用程序中。我將引導你完成此過程,但如果你需要更多信息或遇到麻煩,請查看他們的 Java SDK 文檔。
首先,將Split依賴添加到build.gradle文件中(在項目根目錄中)。該build.gradle文件包含大量內容。只需在末尾附近添加以下行,就在開始的注釋行上方//jhipster-needle-gradle-dependency。
dependencies {
....
compile 'io.split.client:java-client:4.0.1'
//jhipster-needle-gradle-dependency - JHipster will add additional dependencies here
}
你將需要你的 Split API 密鑰。打開你的拆分儀表板。通過轉到儀表板左上角的方形工作區(qū)圖標(可能顯示默認為DE)找到 API 密鑰,單擊它,然后單擊Admin Settings。單擊左側面板中“工作區(qū)設置”下的“API 密鑰”。
你將看到已創(chuàng)建四個 API 密鑰,其中兩個用于生產,兩個用于暫存。服務器端 SDK 使用和客戶端 Javascript 使用有不同的密鑰。SDK和staging-default密鑰是你稍后需要的。
將 API 密鑰添加到配置文件的末尾application.yml。
src/main/resources/application.yml
#application:
split:
api-key: <yourSplitApiKey>代碼語言: 小黃瓜 (gherkin )
我只是指出,在這里你將其添加到全局配置文件中,但在更實際的用例中,你可能會使用兩個不同的 API 密鑰,一個用于暫存和生產,分別將它們添加到 和application-dev.yml文件application-prod.yml中。
創(chuàng)建一個名為 的 Java 文件,SplitConfig.java該文件將在 Spring Boot 應用程序中配置 Split 客戶端。它創(chuàng)建了一個可用于依賴注入的 Spring Bean,并且由于 Bean 的默認行為是創(chuàng)建一個單例實例,因此這與 Split 自己的指導一致,建議只創(chuàng)建一個客戶端實例。
src/main/java/com/split/coffeebot/config/SplitConfig.java
@Configurationpublic class SplitConfig {
@Value("#{ @environment['split.api-key'] }")
private String splitApiKey;
@Bean
public SplitClient splitClient() throws Exception {
SplitClientConfig config = SplitClientConfig.builder()
.setBlockUntilReadyTimeout(1000)
.enableDebug()
.build();
SplitFactory splitFactory = SplitFactoryBuilder.build(splitApiKey, config);
SplitClient client = splitFactory.client();
client.blockUntilReady();
return client;
}
}
你還需要向DrinkRepository.?它JPARepository為你提供了相當多的功能,無需任何自定義,但在這個應用程序中,你將需要一個自定義方法,該方法允許你從標準方法中排除一些飲料findAll()。該方法findByNameNotIn()是一個JPA查詢方法,其語法和實現(xiàn)由Spring Boot提供。你所要做的就是定義方法以使其可供使用。有關更多信息,請參閱Spring Data JPA 查詢方法的文檔。
src/main/java/com/split/coffeebot/repository/DrinkRepository.java
@SuppressWarnings("unused") @Repository public interface DrinkRepository extends JpaRepository<Drink, Long> {
List<Drink> findByNameNotIn(Collection<String> names);
}
現(xiàn)在創(chuàng)建一個CoffeeBotResource.java文件,其中包含 CoffeeBot 應用程序的業(yè)務邏輯和 REST 端點。
src/main/java/com/split/coffeebot/web/rest/CoffeeBotResource.java
package com.split.coffeebot.web.rest;
…
@RestController
@RequestMapping("/api/coffee-bot")public class CoffeeBotResource {
private final Logger log = LoggerFactory.getLogger(CoffeeBotResource.class);
SplitClient splitClient;
DrinkRepository drinkRepository;
public CoffeeBotResource(SplitClient splitClient, DrinkRepository drinkRepository) {
this.splitClient = splitClient;
this.drinkRepository = drinkRepository;
}
private Drink makeDrink(String name, DrinkSize size, Integer caffeineMg, Integer price) {
Drink drink = new Drink();
drink.setCaffeineMilligrams(caffeineMg);
drink.setName(name);
drink.setSize(size);
drink.setPriceDollars(price);
return drink;
}
@EventListener
public void onApplicationEvent(ContextRefreshedEvent event) {
drinkRepository.save(makeDrink("Water", DrinkSize.Small, 0, 1));
drinkRepository.save(makeDrink("Soda", DrinkSize.Medium, 30, 3));
drinkRepository.save(makeDrink("Coffee", DrinkSize.XLarge, 50, 5));
drinkRepository.save(makeDrink("Coffee", DrinkSize.Small, 30, 3));
drinkRepository.save(makeDrink("Coffee", DrinkSize.Medium, 40, 3));
drinkRepository.save(makeDrink("Latte", DrinkSize.Large, 100, 8));
drinkRepository.save(makeDrink("Latte", DrinkSize.Small, 80, 6));
drinkRepository.save(makeDrink("Latte", DrinkSize.Medium, 60, 5));
}
@GetMapping("/list-drinks")
public List<Drink> listDrinks() {
Optional<String> userName = SecurityUtils.getCurrentUserLogin();
String treatment = splitClient.getTreatment(userName.get(),"drink-types");
if (treatment.equals("on")) {
return drinkRepository.findAll();
}
else {
return drinkRepository.findByNameNotIn(Arrays.asList("Latte", "Soda"));
}
}
}
和方法作為輔助方法,用于在應用程序啟動時創(chuàng)建一些示例makeDrink()數(shù)據(jù)onApplicationEvent()(請記住,它使用的是內存數(shù)據(jù)庫,不會在會話之間保留任何數(shù)據(jù))。
該類使用 Spring 的依賴注入來使兩個對象可用:DrinkRepository,這是自動創(chuàng)建的接口,定義應用程序如何操作實體(飲料);,SplitClient它是負責與 Split 通信并獲取給定密鑰和治療名稱的治療的客戶端。
你很快就會創(chuàng)建這種治療方法。現(xiàn)在,請注意該getTreatment()方法至少需要兩個參數(shù)。一種是文本鍵,它是任意字符串值,通常是用戶名、帳戶 ID 或用于區(qū)分用戶的另一個唯一鍵。另一個是分割名稱,它指定使用哪種處理來進行分割。
專業(yè)提示:可選的第三個getTreatment參數(shù)(我們在這里不會使用)是一個屬性?映射對象,包含名稱-值對中的用戶屬性。即使是敏感的用戶數(shù)據(jù)也可以在此映射中傳遞,因為這些數(shù)據(jù)都不會發(fā)送到斯普利特的云。相反,屬性映射會在本地內存中與你在拆分 UI 中輸入的定位規(guī)則進行比較。更多內容請參見 Split SDK 文檔:使用屬性映射進行自定義定位。
如果治療是on,它會返回所有可用的飲料。如果處理不是on(off或control或任何其他值),則返回除Latte和之外的所有飲料Soda。這演示了一種基于拆分來分叉代碼的簡單方法。更復雜的分割和治療用例是可能的。
在你搬家之前,最后一項改變。打開SecurityConfiguration文件并允許api/coffee-bot資源路徑上的所有流量。這將允許匿名用戶獲得飲料清單。
你要添加這一行:
.antMatchers("/api/coffee-bot/**").permitAll() 代碼語言: Bash (bash )
至configure(HttpSecurity http)方法。立場很重要。該行需要添加到該.antMatchers("/api/**").authenticated()行之前。
src/main/java/com/split/coffeebot/config/SecurityConfiguration.java
@Overridepublic void configure(HttpSecurity http) throws Exception {
// @formatter:off
http
...
.and()
.authorizeRequests()
.antMatchers("/api/authenticate").permitAll()
.antMatchers("/api/register").permitAll()
.antMatchers("/api/activate").permitAll()
.antMatchers("/api/account/reset-password/init").permitAll()
.antMatchers("/api/account/reset-password/finish").permitAll()
.antMatchers("/api/coffee-bot/**").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
.antMatchers("/management/prometheus").permitAll()
.antMatchers("/management/**").hasAuthority(AuthoritiesConstants.ADMIN)
...
// @formatter:on
}
創(chuàng)建特征標志處理
如果你對治療和 Split 不熟悉,你可能需要閱讀Split 網(wǎng)站上的入門信息。簡而言之,分割定義了一個決策點,一個標志,可以在代碼中使用它來修改呈現(xiàn)給一組用戶的功能。鍵(以及可選的屬性映射)是根據(jù)拆分中定義的規(guī)則確定標志狀態(tài)的值。這個決定是在運行時調用該方法時做出的。SplitClientgetTreatment()
在我們非常簡單的示例中,你將創(chuàng)建一個名為Drink-types的拆分。這個分割將是一個簡單的開/關分割,就像一個布爾標志(除了開和關之外,還可以有多個值)。分割將默認為off,但on如果admin用戶在場,則分割將變?yōu)?。這是一個非常幼稚的例子。舉個例子,在生產中,你可以根據(jù)用戶群的一部分來定義這種劃分,以在細分中推出新功能;或者,你可以先將功能僅提供給公共 Beta 測試人員,然后再將其發(fā)布給整個用戶群。
打開拆分儀表板。你應該位于默認工作區(qū)中。
單擊左側的“拆分” 。
單擊藍色的“創(chuàng)建拆分”按鈕。
為分割命名:drink-types。你可以將其余部分留空。
單擊創(chuàng)建。
從環(huán)境下拉列表中選擇暫存-默認。
單擊添加規(guī)則按鈕。
請注意,在定義處理部分下,定義了兩個值:on和off。對于我們的用例來說,這非常棒。
在“創(chuàng)建單個目標”下,單擊“添加目標”按鈕。添加名為 的用戶admin。這意味著用戶admin將受到治療on。
單擊面板右上角的保存更改。
單擊下一個面板上的“確認”以確認更改。
更新 Vue.js 客戶端應用程序
客戶端代碼使用axios向資源服務器發(fā)出請求。你還需要安裝 Split 模塊依賴項。從項目根目錄添加依賴項。
npm install --save axios @splitsoftware/splitio@10.14.2
更新home.component.ts文件以創(chuàng)建 CoffeeBot 應用程序。你需要為下面代碼中的位置添加Javascript?–?staging-default鍵。const SPLIT_AUTH_KEY
src/main/webapp/app/core/home/home.component.ts
import Component from 'vue-class-component';
import { Inject, Vue, Watch } from 'vue-property-decorator';
import LoginService from '@/account/login.service';
import { SplitFactory } from '@splitsoftware/splitio';
import { IClient } from '@splitsoftware/splitio/types/splitio';
import axios from 'axios';const SPLIT_AUTH_KEY = <yourSplitAuthKey>;
@Component
export default class Home extends Vue {
@Inject('loginService')
private loginService: () => LoginService;
private splitClient: IClient = null;
// our list of drinks
private drinks = [];
// holds the drink that is the current order
private currentOrder = null;
// cream or no cream?
private withCream = false;
// the current Split.io treatment
private treatment = null;
public openLogin(): void {
this.loginService().openLogin((<any>this).$root);
}
public get authenticated(): boolean {
return this.$store.getters.authenticated;
}
public get username(): string {
return this.$store.getters.account ? this.$store.getters.account.login : '';
}
async getTreatment() {
// create a configured SplitFactory
const splitFactory = SplitFactory({
core: {
authorizationKey: SPLIT_AUTH_KEY, // your Split.io auth key
key: this.username, // identifier for this treatment (username in this case)
trafficType: 'user'
},
startup: {
readyTimeout: 1.5 // 1.5 sec
}
});
// create the split client (NOT READY TO USE YET)
this.splitClient = splitFactory.client();
// block untli the client is ready
this.splitClient.on(this.splitClient.Event.SDK_READY, function() {
// client is ready, get the treatment
this.treatment = this.splitClient.getTreatment('drink-types');
}.bind(this));
}
// triggered when username changes to update list
// of drinks and Split.io treatment
@Watch('username')
async usernameChanged(newVal: string, oldVal: String) {
// get treatment from split.io
await this.getTreatment();
// call the REST service to load drinks
await this.loadDrinks();
// clear the current order
this.currentOrder = null;
}
async loadDrinks() {
const response = await axios.get('http://localhost:8080/api/coffee-bot/list-drinks');
console.log(response);
if (response && response.status === 200) {
this.drinks = response.data;
}
else {
this.drinks = [];
}
}
async mounted() {
await this.getTreatment();
await this.loadDrinks();
}
beforeDestroy() {
this.splitClient.destroy();
}
}
該組件的身份驗證部分是通過 JHipster 引導程序免費提供的。通過該方法從 Spring Boot 資源服務器加載數(shù)據(jù)loadDrinks(),該方法只是將飲料存儲在本地數(shù)組中,巧妙地稱為drinks.?當安裝組件和用戶更改時(因為可用的飲料取決于治療,而治療由用戶決定),則會調用此方法。你可能會注意到此方法沒有傳遞用戶名。這是因為用戶名會自動通過 JWT(JSON Web 令牌)傳遞到服務器,由 Spring Security 處理,身份驗證代碼由 JHipster 引導。
另一個重要的函數(shù)是usernameChanged()方法,當屬性更改時調用該方法username。每次有新用戶時,都需要創(chuàng)建新的 Split 客戶端并重新加載處理。你還需要從服務器重新加載飲料。這個方法處理所有這些。
請注意此處的一般流程。首先,SplitFactory使用分割身份驗證密鑰和新用戶名配置 a。該SplitFactory實例用于創(chuàng)建SplitClient實例。然而,客戶此時不一定準備好。該代碼會阻塞,直到SDK_READY事件被觸發(fā)(參見下面的代碼),然后才嘗試從 獲取處理SplitClient,否則它將僅返回control處理。
// block until SDK is readythis.splitClient.on(this.splitClient.Event.SDK_READY, function () {
// ready now, so get treatment
this.treatment = this.splitClient.getTreatment('drink-types');
}.bind(this))
home.vue現(xiàn)在更新與該組件對應的模板文件。
src/main/webapp/app/core/home/home.vue
<template>
<div class="container">
<div class="home row justify-content-md-center">
<div class="col-md-6">
<div class="title">
<h1 class="display-4">CoffeeBot!</h1>
<p class="lead">Drink coffee!</p>
<p>{{username ? username : "anonymous"}}, treatment: {{treatment}}</p>
</div>
<div v-for="drink in drinks">
<b-button variant="outline-primary" class="menu-button" @click="currentOrder=drink">{{drink.name}} {{drink.size}} - ${{drink.priceDollars}}</b-button>
</div>
<div v-if="currentOrder !== null">
<div v-if="treatment==='on'">
<b-button v-if="!withCream" variant="success" class="menu-button" @click="withCream=true">Add Cream - FREE</b-button>
<b-button v-if="withCream" variant="danger" class="menu-button" @click="withCream=false">Remove Cream</b-button>
</div>
<div class="card order">
<h4>Current order:</h4>
<div>
{{currentOrder.name}} {{currentOrder.size}} {{withCream ? "(w/ cream)" : ""}} - ${{currentOrder.priceDollars}}
</div>
</div>
</div>
</div>
</div>
</div></template>
<script lang="ts" src="./home.component.ts"></script>
<style>
.menu-button {
margin-bottom: 10px;
width: 100%;
}
.order {
text-align: center;
padding:20px;
}
.title h1, .title p {
text-align: center;
}</style>
```
請注意,該文件使用 Vue 的條件語法根據(jù)處理狀態(tài)有條件地渲染添加和刪除奶油按鈕。在這種情況下,即使組件中有一些與添加和刪除奶油功能相關的代碼未切換,這就是我們管理功能狀態(tài)所需要做的全部工作。
嘗試完成的 Spring Boot + Vue.js 教程應用程序
你現(xiàn)在可以嘗試完成的應用程序。啟動或重新啟動服務器和客戶端。你可能希望在啟動客戶端之前讓服務器完成啟動。
Spring Boot Java 服務器:
./gradlew
Vue.js 客戶端:
npm start
客戶端應用程序應自動打開。如果沒有,請打開 http://localhost:9000
當你第一次加載應用程序時,你會看到用戶是anonymous并且治療是對照治療。
使用默認管理員憑據(jù) ( ) 登錄admin:admin,你將看到擴展的飲料列表。當你添加一個飲料時,你會看到一個名為"Add Cream"的按鈕。該按鈕的可見性或功能可能受到名為"split treatment"的處理方式的控制。換句話說,根據(jù)某種分割處理的規(guī)則或邏輯,決定了是否顯示或啟用這個"Add Cream"按鈕。
注銷并以默認用戶 ( user:user) 身份登錄,你將看到處理方式,并且off你將獲得與該用戶相同的飲料列表anonymous。此外,你無法選擇添加奶油。
了解有關 Spring Boot、功能標志和生產中測試的更多信息
在本教程中,你創(chuàng)建了一個全棧應用程序,其中包括 Vue.js 客戶端和 Spring Boot 資源服務器。Vue.js 客戶端使用 TypeScript 進行更現(xiàn)代、無錯誤的開發(fā)(因為如果使用得當,類型檢查可以大大減少運行時錯誤)。Spring Boot 服務器使用 Spring Security 和 Spring JPA 等技術來快速輕松地定義數(shù)據(jù)模型(或實體),將該實體的實例保存到數(shù)據(jù)庫,并在 REST 接口中提供該數(shù)據(jù)。
客戶端和服務器都使用 JWT 身份驗證來保護安全。Split用于實現(xiàn)功能標志,在服務器端使用Java SDK實現(xiàn)拆分,在客戶端使用Javascript SDK實現(xiàn)拆分。
所有這一切都是使用 JHipster 引導的,這使得使用現(xiàn)代最佳實踐和技術啟動新的全棧項目變得非常容易。
你可以在Split 的示例 GitHub上找到所有設置的 JHipster 的完整源代碼。文章來源:http://www.zghlxwxcb.cn/news/detail-554358.html
本文由博客群發(fā)一文多發(fā)等運營工具平臺 OpenWrite 發(fā)布文章來源地址http://www.zghlxwxcb.cn/news/detail-554358.html
到了這里,關于全棧教程:Spring Boot 和 Vue.js 入門的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!