diff --git a/pom.xml b/pom.xml
index 88aa7011d0..163c3bdcc8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -722,10 +722,11 @@
spring-boot-parent
spring-boot-property-exp
spring-boot-security
+ spring-boot-springdoc
spring-boot-testing
spring-boot-vue
spring-caching
- spring-boot-libraries
+ spring-boot-libraries
spring-cloud
@@ -922,6 +923,7 @@
spring-boot-keycloak
spring-boot-mvc
spring-boot-property-exp
+ spring-boot-springdoc
spring-boot-vue
spring-cloud
spring-cloud/spring-cloud-archaius/basic-config
@@ -1467,8 +1469,9 @@
spring-boot-parent
spring-boot-property-exp
spring-boot-security
+ spring-boot-springdoc
spring-boot-vue
- spring-caching
+ spring-caching
spring-cloud
spring-cloud-bus
diff --git a/spring-boot-springdoc/pom.xml b/spring-boot-springdoc/pom.xml
new file mode 100644
index 0000000000..a818db6e53
--- /dev/null
+++ b/spring-boot-springdoc/pom.xml
@@ -0,0 +1,106 @@
+
+
+ 4.0.0
+ com.baeldung
+ spring-boot-springdoc
+ 0.0.1-SNAPSHOT
+ spring-boot-springdoc
+ Project for Springdoc integration
+ jar
+
+
+ parent-boot-2
+ com.baeldung
+ 0.0.1-SNAPSHOT
+ ../parent-boot-2
+
+
+
+ 1.8
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+
+
+ org.springdoc
+ springdoc-openapi-core
+ 1.1.45
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ 1.1.45
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
+
+ integration
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+ 2.1.8.RELEASE
+
+
+ pre-integration-test
+
+ start
+
+
+
+ post-integration-test
+
+ stop
+
+
+
+
+
+ org.springdoc
+ springdoc-openapi-maven-plugin
+ 0.2
+
+
+ integration-test
+
+ generate
+
+
+
+
+ http://localhost:8080/api-docs
+ openapi.json
+ ${project.build.directory}
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/SpringdocApplication.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/SpringdocApplication.java
new file mode 100644
index 0000000000..45c7c23621
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/SpringdocApplication.java
@@ -0,0 +1,13 @@
+package com.baeldung.springdoc;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class SpringdocApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(SpringdocApplication.class, args);
+ }
+
+}
diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/BookController.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/BookController.java
new file mode 100644
index 0000000000..4d7d9e3d85
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/controller/BookController.java
@@ -0,0 +1,73 @@
+package com.baeldung.springdoc.controller;
+
+import java.util.Collection;
+
+import javax.validation.Valid;
+import javax.validation.constraints.NotNull;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PatchMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestController;
+
+import com.baeldung.springdoc.exception.BookNotFoundException;
+import com.baeldung.springdoc.model.Book;
+import com.baeldung.springdoc.repository.BookRepository;
+
+@RestController
+@RequestMapping("/api/book")
+public class BookController {
+
+ @Autowired
+ private BookRepository repository;
+
+ @GetMapping("/{id}")
+ public Book findById(@PathVariable long id) {
+ return repository.findById(id)
+ .orElseThrow(() -> new BookNotFoundException());
+ }
+
+ @GetMapping("/")
+ public Collection findBooks() {
+ return repository.getBooks();
+ }
+
+ @PutMapping("/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ public Book updateBook(@PathVariable("id") final String id, @RequestBody final Book book) {
+ return book;
+ }
+
+ @PatchMapping("/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ public Book patchBook(@PathVariable("id") final String id, @RequestBody final Book book) {
+ return book;
+ }
+
+ @PostMapping("/")
+ @ResponseStatus(HttpStatus.CREATED)
+ public Book postBook(@NotNull @Valid @RequestBody final Book book) {
+ return book;
+ }
+
+ @RequestMapping(method = RequestMethod.HEAD, value = "/")
+ @ResponseStatus(HttpStatus.OK)
+ public Book headBook() {
+ return new Book();
+ }
+
+ @DeleteMapping("/{id}")
+ @ResponseStatus(HttpStatus.OK)
+ public long deleteBook(@PathVariable final long id) {
+ return id;
+ }
+}
diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java
new file mode 100644
index 0000000000..632cb683bc
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/BookNotFoundException.java
@@ -0,0 +1,10 @@
+package com.baeldung.springdoc.exception;
+
+@SuppressWarnings("serial")
+public class BookNotFoundException extends RuntimeException {
+
+ public BookNotFoundException() {
+
+ }
+
+}
\ No newline at end of file
diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java
new file mode 100644
index 0000000000..c829072236
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/exception/GlobalControllerExceptionHandler.java
@@ -0,0 +1,24 @@
+package com.baeldung.springdoc.exception;
+
+import org.springframework.core.convert.ConversionFailedException;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+@RestControllerAdvice
+public class GlobalControllerExceptionHandler {
+
+ @ExceptionHandler(ConversionFailedException.class)
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ public ResponseEntity handleConnversion(RuntimeException ex) {
+ return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
+ }
+
+ @ExceptionHandler(BookNotFoundException.class)
+ @ResponseStatus(HttpStatus.NOT_FOUND)
+ public ResponseEntity handleBookNotFound(RuntimeException ex) {
+ return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
+ }
+}
diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/model/Book.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/model/Book.java
new file mode 100644
index 0000000000..8f678a7ec2
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/model/Book.java
@@ -0,0 +1,41 @@
+package com.baeldung.springdoc.model;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
+
+public class Book {
+
+ private long id;
+
+ @NotBlank
+ @Size(min = 0, max = 20)
+ private String title;
+
+ @NotBlank
+ @Size(min = 0, max = 30)
+ private String author;
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+}
diff --git a/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/repository/BookRepository.java b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/repository/BookRepository.java
new file mode 100644
index 0000000000..4040ba28c2
--- /dev/null
+++ b/spring-boot-springdoc/src/main/java/com/baeldung/springdoc/repository/BookRepository.java
@@ -0,0 +1,28 @@
+package com.baeldung.springdoc.repository;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import org.springframework.stereotype.Repository;
+
+import com.baeldung.springdoc.model.Book;
+
+@Repository
+public class BookRepository {
+
+ private Map books = new HashMap<>();
+
+ public Optional findById(long id) {
+ return Optional.ofNullable(books.get(id));
+ }
+
+ public void add(Book book) {
+ books.put(book.getId(), book);
+ }
+
+ public Collection getBooks() {
+ return books.values();
+ }
+}
diff --git a/spring-boot-springdoc/src/main/resources/application.properties b/spring-boot-springdoc/src/main/resources/application.properties
new file mode 100644
index 0000000000..f03e90feb6
--- /dev/null
+++ b/spring-boot-springdoc/src/main/resources/application.properties
@@ -0,0 +1,5 @@
+# custom path for swagger-ui
+springdoc.swagger-ui.path=/swagger-ui-custom.html
+
+# custom path for api docs
+springdoc.api-docs.path=/api-docs
diff --git a/spring-boot-springdoc/src/main/resources/logback.xml b/spring-boot-springdoc/src/main/resources/logback.xml
new file mode 100644
index 0000000000..6a07b178e9
--- /dev/null
+++ b/spring-boot-springdoc/src/main/resources/logback.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextIntegrationTest.java b/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextIntegrationTest.java
new file mode 100644
index 0000000000..58c12dc3bc
--- /dev/null
+++ b/spring-boot-springdoc/src/test/java/com/baeldung/springdoc/SpringContextIntegrationTest.java
@@ -0,0 +1,17 @@
+package com.baeldung.springdoc;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+@RunWith(SpringRunner.class)
+@SpringBootTest
+public class SpringContextIntegrationTest {
+
+ @Test
+ public void whenSpringContextIsBootstrapped_thenNoExceptions() {
+
+ }
+
+}