mirror of
https://github.com/Febbweiss/springboot-react-webpack.git
synced 2026-03-05 06:35:36 +00:00
First commit
This commit is contained in:
12
src/main/java/com/opengroupe/cloud/saas/Application.java
Normal file
12
src/main/java/com/opengroupe/cloud/saas/Application.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package com.opengroupe.cloud.saas;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
||||
26
src/main/java/com/opengroupe/cloud/saas/domain/Comment.java
Normal file
26
src/main/java/com/opengroupe/cloud/saas/domain/Comment.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package com.opengroupe.cloud.saas.domain;
|
||||
|
||||
import groovy.transform.ToString;
|
||||
|
||||
@ToString
|
||||
public class Comment {
|
||||
|
||||
private final Long id;
|
||||
private final String author;
|
||||
private final String text;
|
||||
|
||||
public Comment(Long id, String author, String text) {
|
||||
this.id = id;
|
||||
this.author = author;
|
||||
this.text = text;
|
||||
}
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.opengroupe.cloud.saas.rest;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.opengroupe.cloud.saas.domain.Comment;
|
||||
|
||||
@RestController
|
||||
public class CommentController {
|
||||
|
||||
private List<Comment> comments = new ArrayList<Comment>();
|
||||
|
||||
@RequestMapping("/")
|
||||
public String index() {
|
||||
return "Greetings from Spring Boot!";
|
||||
}
|
||||
|
||||
@RequestMapping(value="/api/comments", method=RequestMethod.GET)
|
||||
public @ResponseBody List<Comment> comments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
@RequestMapping(value="/api/comments", method=RequestMethod.POST)
|
||||
public @ResponseBody List<Comment> comments(
|
||||
@RequestParam(value="id", required=true) Long id,
|
||||
@RequestParam(value="author", required=true) String author,
|
||||
@RequestParam(value="text", required=true) String text) {
|
||||
comments.add(new Comment(id, author, text));
|
||||
return comments;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.opengroupe.cloud.saas.web;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
@Controller
|
||||
public class ViewController {
|
||||
|
||||
@RequestMapping("/greeting")
|
||||
public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
|
||||
model.addAttribute("name", name);
|
||||
return "greeting";
|
||||
}
|
||||
|
||||
@RequestMapping("/index")
|
||||
public String index(Model model) {
|
||||
return "index";
|
||||
}
|
||||
}
|
||||
16
src/main/resources/application.yml
Normal file
16
src/main/resources/application.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
spring:
|
||||
main:
|
||||
banner_mode: off
|
||||
|
||||
project:
|
||||
artifactId: template
|
||||
name: Demo
|
||||
version: X.X.X
|
||||
description: Demo project for info endpoint
|
||||
|
||||
info:
|
||||
build:
|
||||
artifact: ${project.artifactId}
|
||||
name: ${project.name}
|
||||
description: ${project.description}
|
||||
version: ${project.version}
|
||||
10
src/main/resources/templates/greeting.html
Normal file
10
src/main/resources/templates/greeting.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head>
|
||||
<title>Getting Started: Serving Web Content</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
</head>
|
||||
<body>
|
||||
<p th:text="'Hello, ' + ${name} + '!'" />
|
||||
</body>
|
||||
</html>
|
||||
17
src/main/resources/templates/index.html
Normal file
17
src/main/resources/templates/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org">
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8"/>
|
||||
<title>ReactJS</title>
|
||||
<link rel="stylesheet" href="/css/react-bootstrap.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="content"></div>
|
||||
|
||||
<script src="/js/react-bootstrap.js"></script>
|
||||
<script src="/js/bundle.js"></script>
|
||||
<script src="/js/app.js"></script>
|
||||
<script src="/js/app.render.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
123
src/main/webapp/js/app.jsx
Normal file
123
src/main/webapp/js/app.jsx
Normal file
@@ -0,0 +1,123 @@
|
||||
'use strict';
|
||||
|
||||
var Comment = React.createClass({
|
||||
rawMarkup: function() {
|
||||
var rawMarkup = marked(this.props.children.toString(), {sanitize: true});
|
||||
return { __html: rawMarkup };
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className="comment">
|
||||
<h2 className="commentAuthor">
|
||||
{this.props.author}
|
||||
</h2>
|
||||
<span dangerouslySetInnerHTML={this.rawMarkup()} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var CommentForm = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {author: '', text: ''};
|
||||
},
|
||||
handleAuthorChange: function(e) {
|
||||
this.setState({author: e.target.value});
|
||||
},
|
||||
handleTextChange: function(e) {
|
||||
this.setState({text: e.target.value});
|
||||
},
|
||||
handleSubmit: function(e) {
|
||||
e.preventDefault();
|
||||
var author = this.state.author.trim();
|
||||
var text = this.state.text.trim();
|
||||
if( !text || !author ) {
|
||||
return;
|
||||
}
|
||||
this.props.onCommentSubmit({author: author, text: text})
|
||||
this.setState({author: '', text: ''});
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<form className="commentForm" onSubmit={this.handleSubmit}>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Your name"
|
||||
value={this.state.author}
|
||||
onChange={this.handleAuthorChange}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Say something..."
|
||||
value={this.state.text}
|
||||
onChange={this.handleTextChange}
|
||||
/>
|
||||
<input type="submit" value="Post" />
|
||||
</form>
|
||||
);
|
||||
}
|
||||
});
|
||||
var CommentBox = React.createClass({
|
||||
getInitialState: function() {
|
||||
return {data: []};
|
||||
},
|
||||
loadCommentsFromServer: function() {
|
||||
$.ajax({
|
||||
url: this.props.url,
|
||||
dataType: 'json',
|
||||
cache: false,
|
||||
success: function(data) {
|
||||
this.setState({data: data});
|
||||
}.bind(this),
|
||||
error: function(xhr, status, err) {
|
||||
console.error(this.props.url, status, err.toString());
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
handleCommentSubmit: function(comment) {
|
||||
var comments = this.state.data;
|
||||
comment.id = Date.now();
|
||||
var newComments = comments.concat([comment]);
|
||||
this.setState({data: newComments});
|
||||
$.ajax({
|
||||
url: this.props.url,
|
||||
method: 'POST',
|
||||
dataType: 'json',
|
||||
data: comment,
|
||||
success: function(data) {
|
||||
this.setState({data: data});
|
||||
}.bind(this),
|
||||
error: function(xhr, status, err) {
|
||||
this.setState({data: comments});
|
||||
console.error(this.props.url, status, err.toString());
|
||||
}.bind(this)
|
||||
});
|
||||
},
|
||||
componentDidMount: function() {
|
||||
this.loadCommentsFromServer();
|
||||
setInterval(this.loadCommentsFromServer, this.props.pollInterval);
|
||||
},
|
||||
render: function() {
|
||||
return (
|
||||
<div className="commentBox">
|
||||
<h1>Comments</h1>
|
||||
<CommentList data={this.state.data}/>
|
||||
<CommentForm onCommentSubmit={this.handleCommentSubmit}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
var CommentList = React.createClass({
|
||||
render: function() {
|
||||
var commentNodes = this.props.data.map( function(comment) {
|
||||
return (
|
||||
<Comment author={comment.author} key={comment.id}>{comment.text}</Comment>
|
||||
);
|
||||
});
|
||||
return (
|
||||
<div className="commentList">
|
||||
{commentNodes}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
});
|
||||
4
src/main/webapp/js/app.render.js
Normal file
4
src/main/webapp/js/app.render.js
Normal file
@@ -0,0 +1,4 @@
|
||||
ReactDOM.render(
|
||||
<CommentBox url="/api/comments" pollInterval={2000}/>,
|
||||
document.getElementById('content')
|
||||
);
|
||||
8
src/main/wro/wro.properties
Normal file
8
src/main/wro/wro.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
debug=true
|
||||
# Available processors : http://wro4j.readthedocs.org/en/stable/AvailableProcessors/
|
||||
preProcessors=lessCssImport
|
||||
postProcessors=less4j,cssMin
|
||||
# explicitly invalidates the cache each 5 seconds
|
||||
cacheUpdatePeriod=5
|
||||
# check for changes each 5 seconds and invalidates the cache only when a change is detected
|
||||
resourceWatcherUpdatePeriod=5
|
||||
13
src/main/wro/wro.xml
Normal file
13
src/main/wro/wro.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<groups xmlns="http://www.isdc.ro/wro">
|
||||
<group name="react-bootstrap">
|
||||
<css>webjar:bootstrap/@bootstrap.version@/css/bootstrap.css</css>
|
||||
<js>webjar:jquery/@jquery.version@/jquery.js</js>
|
||||
<js>webjar:react/@react.version@/react-with-addons.js</js>
|
||||
<js>webjar:react/@react.version@/react-dom.js</js>
|
||||
</group>
|
||||
|
||||
<group name="bundle">
|
||||
<js>webjar:marked/@marked-lib.version@/marked.js</js>
|
||||
</group>
|
||||
</groups>
|
||||
Reference in New Issue
Block a user