Java Spring Boot (Part 1)

Neil HaddleyApril 6, 2021

Spring based Java Applications that you can just run.

Javaspring-bootjavarest-apiweb

I used Spring Tool Suite (an Eclipse-based IDE) and Maven (a Java build and dependency management tool) to create a REST API with Spring Boot.

Creating a REST project using Spring Boot

I opened Spring Tool Suite, created a new Spring Starter Project, added a Book class and a BooksRestController, then ran and tested the app in the browser.

I created a new Spring Starter Project

I created a new Spring Starter Project

I entered the project name and package details

I entered the project name and package details

The REST API project depends on "Spring Web"

The REST API project depends on "Spring Web"

I added a new class

I added a new class

I added class "Book"

I added class "Book"

I added class "BooksRestController"

I added class "BooksRestController"

Annotations

The @RestController annotation is used to mark the BooksRestController class as a Spring Framework RestController.

Add @RestController annotation to BooksRestController classUse CTRL+Space to import org.springframework.web.bind.annotation.RestController

Add @RestController annotation to BooksRestController classUse CTRL+Space to import org.springframework.web.bind.annotation.RestController

Add "books" ArrayList to the BooksRestController

Add "books" ArrayList to the BooksRestController

Books REST Controller

The @GetMapping annotation is used to mark the book and books methods as HTTP Get method handlers.

I ran it as a Spring Boot App

I ran it as a Spring Boot App

http://localhost:8080/books

http://localhost:8080/books

http://localhost:8080/books/1788395549

http://localhost:8080/books/1788395549

http://localhost:8080/books/1234567890

http://localhost:8080/books/1234567890

React client

I added static files (images, HTML, and JavaScript) to the /src/main/resources/static folder of the Spring Boot project, including a React app that calls the REST API exposed by the same Spring Boot project.

Static files

Static files

Running the React/Spring Boot app

Running the React/Spring Boot app

Book.java

JAVA
1package com.haddley.Books;
2
3public class Book {
4
5	public Book(long id, String title) {
6		_id = id;
7		_title = title;
8	}
9
10	private long _id;
11
12	public long getId() {
13		return _id;
14	}
15
16	public void setId(long id) {
17		this._id = id;
18	}
19
20	public String getTitle() {
21		return _title;
22	}
23
24	public void setTitle(String title) {
25		this._title = title;
26	}
27
28	private String _title;
29	
30}

BooksRestController.java

JAVA
1package com.haddley.Books;
2
3import java.util.ArrayList;
4
5import org.springframework.http.HttpStatus;
6import org.springframework.web.bind.annotation.GetMapping;
7import org.springframework.web.bind.annotation.PathVariable;
8import org.springframework.web.bind.annotation.RestController;
9import org.springframework.web.server.ResponseStatusException;
10
11
12@RestController
13public class BooksRestController {
14
15	private static ArrayList<Book> books = new ArrayList<Book>();
16
17	static {
18		books.add(new Book(1788395549, "Learning Node.js Development"));
19		books.add(new Book(1788620216, "Hands-On Microservices with Node.js"));
20	}
21
22	@GetMapping("/books/{id}")
23	public Book book(@PathVariable Long id) {
24		@SuppressWarnings("unchecked")
25		ArrayList<Book> result = (ArrayList<Book>) BooksRestController.books.clone();
26		result.removeIf(n -> (n.getId() != id));
27		if (result.isEmpty()){
28			throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Book Not Found");
29		}
30		return result.get(0);
31	}
32
33	@GetMapping("/books")
34	public ArrayList<Book> books() {
35		return BooksRestController.books;
36	}
37	
38}

App.js

JAVASCRIPT
1import React, { useEffect, useState } from 'react';
2
3function App() {
4
5  const [books, setBooks] = useState([]);
6
7  useEffect(() => {
8
9    console.log("use effect");
10    fetch('/books')
11      .then(
12        (d) => {
13          d.json().then((b) => {
14            setBooks(() => b)
15          });
16        }
17      )
18
19  }
20    , [])
21
22  return (
23
24    <>
25        {books.map(book =>
26            <h4>{book.title}</h4>)}
27    </>
28
29  );
30}
31
32export default App;

index.html

HTML
1<!DOCTYPE html>
2<html lang="en">
3
4<head>
5	<title>React App</title>
6</head>
7
8<body>
9
10	<noscript>You need to enable JavaScript to run this app.</noscript>
11	<div id="root"></div>
12
13	<script>!function (e) {function r(r) {for (var n, i, l = r[0], p = r[1], f = r[2], c = 0, s = []; c < l.length; c++)i = l[c], Object.prototype.hasOwnProperty.call(o, i) && o[i] && s.push(o[i][0]), o[i] = 0; for (n in p) Object.prototype.hasOwnProperty.call(p, n) && (e[n] = p[n]); for (a && a(r); s.length;)s.shift()(); return u.push.apply(u, f || []), t()} function t() {for (var e, r = 0; r < u.length; r++) {for (var t = u[r], n = !0, l = 1; l < t.length; l++) {var p = t[l]; 0 !== o[p] && (n = !1)} n && (u.splice(r--, 1), e = i(i.s = t[0]))} return e} var n = {}, o = {1: 0}, u = []; function i(r) {if (n[r]) return n[r].exports; var t = n[r] = {i: r, l: !1, exports: {}}; return e[r].call(t.exports, t, t.exports, i), t.l = !0, t.exports} i.m = e, i.c = n, i.d = function (e, r, t) {i.o(e, r) || Object.defineProperty(e, r, {enumerable: !0, get: t})}, i.r = function (e) {"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {value: "Module"}), Object.defineProperty(e, "__esModule", {value: !0})}, i.t = function (e, r) {if (1 & r && (e = i(e)), 8 & r) return e; if (4 & r && "object" == typeof e && e && e.__esModule) return e; var t = Object.create(null); if (i.r(t), Object.defineProperty(t, "default", {enumerable: !0, value: e}), 2 & r && "string" != typeof e) for (var n in e) i.d(t, n, function (r) {return e[r]}.bind(null, n)); return t}, i.n = function (e) {var r = e && e.__esModule ? function () {return e.default} : function () {return e}; return i.d(r, "a", r), r}, i.o = function (e, r) {return Object.prototype.hasOwnProperty.call(e, r)}, i.p = "/"; var l = this["webpackJsonpnode-spring-client"] = this["webpackJsonpnode-spring-client"] || [], p = l.push.bind(l); l.push = r, l = l.slice(); for (var f = 0; f < l.length; f++)r(l[f]); var a = p; t()}([])</script>
14	<script src="/js/2.bd91be3c.chunk.js"></script>
15	<script src="/js/main.d36b6e09.chunk.js"></script>
16
17</body>
18
19</html>

References