PR for http://jira.baeldung.com/browse/BAEL-1947 Spring Boot Vue (#4687)
* commit first as binodpanta * revert test change * A short example of real-time event streaming using Spring WebFlux * Code for http://jira.baeldung.com/browse/BAEL-1527 * remove unrelated files * Apply feedback changes to rename test and remove link from readme file, ongoing work * Update formatting fixes to code and add pom changes, that partially fix test runnning issues in IDE but not in cmdline * Apply Eclipse formatter to test code and apply suggested pom fixes * BAEL-1527 Formatting fix in pom.xml * Use string.format to cleanup logging code * BAEL-1527 Changed logging pattern * Start the spring-boot-vue module, WIP * some small updates with comments * Add index html template page * merge pom.xml fixes * Add integration test with MockMvc to verify index.html content is rendered correctly * fix up pom merge issues * merge issues fix for pom * pom end of file newline
This commit is contained in:
parent
977a92ef0e
commit
896a2d071a
4
pom.xml
4
pom.xml
|
@ -422,6 +422,7 @@
|
|||
<module>spring-boot-persistence</module>
|
||||
<module>spring-boot-security</module>
|
||||
<module>spring-boot-mvc</module>
|
||||
<module>spring-boot-vue</module>
|
||||
<module>spring-boot-logging-log4j2</module>
|
||||
<module>spring-cloud-data-flow</module>
|
||||
<module>spring-cloud</module>
|
||||
|
@ -1223,4 +1224,5 @@
|
|||
<maven-pmd-plugin.version>3.8</maven-pmd-plugin.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
</project>
|
||||
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
/target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/build/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-boot-vue</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>spring-boot-vue</name>
|
||||
<description>Demo project for Spring Boot Vue project</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.0.2.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- needed to render html templates in /resources/templates -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
|
||||
</project>
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.springbootmvc;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringBootMvcApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringBootMvcApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.baeldung.springbootmvc.controllers;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@Controller
|
||||
public class MainController {
|
||||
|
||||
@RequestMapping(value = "/", method = RequestMethod.GET)
|
||||
public String index(Model model) {
|
||||
// this attribute will be available in the view index.html as a thymeleaf variable
|
||||
model.addAttribute("eventName", "FIFA 2018");
|
||||
// this just means render index.html from static/ area
|
||||
return "index";
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,98 @@
|
|||
<!doctype html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<!-- Include Bootstrap -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<!-- Optional theme -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"
|
||||
integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container-fluid">
|
||||
<h3 class="display-3">This is an example Vue.js application developed with Spring Boot</h3>
|
||||
<p class="lead">This file is rendered by a Spring built-in default controller for index.html (/) using
|
||||
Spring's built-in
|
||||
Thymeleaf templating engine.
|
||||
Although we don't need it per se, we customized the information passed to this
|
||||
view from thymeleaf by adding a controller method for "/" route to demonstrate how to pass information from
|
||||
Thymeleaf to this page.
|
||||
The combination of template engine and frontend framework like Vue can make this a powerful approach to build
|
||||
more complex applications while leveraging the benefits of a framework like Vue.js.
|
||||
You can use thymeleaf features too but this project focuses mainly on using Vue.js on the
|
||||
frontend as the framework and makes minimal use of Thymeleaf.
|
||||
Also we don't use any routing and multiple components in this example, so what you see is technically a
|
||||
Single Page Application (SPA) without any routes configured.
|
||||
</p>
|
||||
|
||||
<div id="contents-main">
|
||||
<div class="lead">
|
||||
<strong>Name of Event:</strong>
|
||||
<span th:text="${eventName}"></span>
|
||||
</div>
|
||||
<div id="contents">
|
||||
<!-- Since we create a Vue component pointing to id=contents,
|
||||
Vue will generate a unordered list of items such
|
||||
as this inside this div.
|
||||
v-for will cause a loop to run over all players
|
||||
as per the players array found in app.data
|
||||
<ul>
|
||||
<li></li>
|
||||
<li></li>
|
||||
</ul>
|
||||
-->
|
||||
<ul>
|
||||
<li style="list-style-type:none" v-for="player in players">
|
||||
<player-card
|
||||
v-bind:player="player" v-bind:key="player.id">
|
||||
</player-card>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- include Vue.js -->
|
||||
<!-- we include babel js so that we can write ES6 code in the browser
|
||||
for a more production like setup it is recommended to setup a build process
|
||||
to transpile and minify the code (such as using webpack)
|
||||
-->
|
||||
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.21.1/babel.min.js"></script>
|
||||
<script type="text/babel">
|
||||
// player-card is now a Vue component that generates a 'card' showing a player
|
||||
// It can be used
|
||||
// declaratively like <player-card v-bind:player="someplayer">
|
||||
Vue.component('player-card', {
|
||||
props: ['player'],
|
||||
template: `<div class="card">
|
||||
<div class="card-body">
|
||||
<h6 class="card-title">
|
||||
{{ player.name }}
|
||||
</h6>
|
||||
<p class="card-text">
|
||||
<div>
|
||||
{{ player.description }}
|
||||
</div>
|
||||
</p>
|
||||
</div>
|
||||
</div>`
|
||||
});
|
||||
|
||||
var app = new Vue({
|
||||
el: '#contents',
|
||||
data: {
|
||||
players: [
|
||||
{id: "1", name: "Lionel Messi", description: "Argentina's superstar"},
|
||||
{id: "2", name: "Christiano Ronaldo", description: "Portugal top-ranked player"}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,35 @@
|
|||
package com.baeldung.springbootmvc;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
public class SpringBootMvcApplicationTests {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
/**
|
||||
* If this test passes, we got a page with the thymeleaf provided variable
|
||||
* value for eventName
|
||||
*/
|
||||
@Test
|
||||
public void shouldLoadCorrectIndexPage() throws Exception {
|
||||
mockMvc.perform(get("/")).andExpect(status().isOk()).
|
||||
andExpect(MockMvcResultMatchers.content()
|
||||
.string(containsString("FIFA 2018")));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue