diff --git a/spring-boot-modules/pom.xml b/spring-boot-modules/pom.xml index c8d153d4bb..228e7ce481 100644 --- a/spring-boot-modules/pom.xml +++ b/spring-boot-modules/pom.xml @@ -20,6 +20,7 @@ spring-boot-annotations spring-boot-artifacts spring-boot-autoconfiguration + spring-boot-basic-customization spring-boot-bootstrap spring-boot-client spring-boot-config-jpa-error diff --git a/spring-boot-modules/spring-boot-basic-customization/README.md b/spring-boot-modules/spring-boot-basic-customization/README.md new file mode 100644 index 0000000000..a3d9f1b1fc --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/README.md @@ -0,0 +1,13 @@ +## Spring Boot Basic Customization + +This module contains articles about Spring Boot customization + +### Relevant Articles: + + - [How to Change the Default Port in Spring Boot](https://www.baeldung.com/spring-boot-change-port) + - [Using Custom Banners in Spring Boot](https://www.baeldung.com/spring-boot-custom-banners) + - [Create a Custom FailureAnalyzer with Spring Boot](https://www.baeldung.com/spring-boot-failure-analyzer) + - [Spring Boot: Customize Whitelabel Error Page](https://www.baeldung.com/spring-boot-custom-error-page) + - [Spring Boot: Configuring a Main Class](https://www.baeldung.com/spring-boot-main-class) + - [How to Define a Spring Boot Filter?](https://www.baeldung.com/spring-boot-add-filter) + - [Guide to the Favicon in Spring Boot](https://www.baeldung.com/spring-boot-favicon) diff --git a/spring-boot-modules/spring-boot-basic-customization/pom.xml b/spring-boot-modules/spring-boot-basic-customization/pom.xml new file mode 100644 index 0000000000..7c2c89def4 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + spring-boot-basic-customization + spring-boot-basic-customization + jar + Module For Spring Boot Basic Customization + + + com.baeldung + parent-boot-2 + 0.0.1-SNAPSHOT + ../../parent-boot-2 + + + + + org.springframework.boot + spring-boot-starter + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + org.springframework.boot + spring-boot-starter-test + test + + + + + + com.baeldung.changeport.CustomApplication + + diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/FilterConfig.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/FilterConfig.java new file mode 100644 index 0000000000..42da61fe14 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/FilterConfig.java @@ -0,0 +1,23 @@ +package com.baeldung.bootcustomfilters; + +import com.baeldung.bootcustomfilters.filters.RequestResponseLoggingFilter; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + // uncomment this and comment the @Component in the filter class definition to register only for a url pattern + // @Bean + public FilterRegistrationBean loggingFilter() { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + + registrationBean.setFilter(new RequestResponseLoggingFilter()); + + registrationBean.addUrlPatterns("/users/*"); + + return registrationBean; + + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java new file mode 100644 index 0000000000..c4653932c0 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/SpringBootFiltersApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.bootcustomfilters; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/** + * Boot application + * @author hemant + * + */ +@SpringBootApplication +public class SpringBootFiltersApplication { + + public static void main(String[] args) { + SpringApplication.run(SpringBootFiltersApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java new file mode 100644 index 0000000000..50d5f4ea71 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/controller/UserController.java @@ -0,0 +1,34 @@ +package com.baeldung.bootcustomfilters.controller; + +import com.baeldung.bootcustomfilters.model.User; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +/** + * Rest controller for User + * @author hemant + * + */ +@RestController +@RequestMapping("/users") +public class UserController { + + private static final Logger LOG = LoggerFactory.getLogger(UserController.class); + + @GetMapping("") + public List getAllUsers() { + LOG.info("Fetching all the users"); + return Arrays.asList( + new User(UUID.randomUUID().toString(), "User1", "user1@test.com"), + new User(UUID.randomUUID().toString(), "User1", "user1@test.com"), + new User(UUID.randomUUID().toString(), "User1", "user1@test.com")); + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java new file mode 100644 index 0000000000..3924354932 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/RequestResponseLoggingFilter.java @@ -0,0 +1,44 @@ +package com.baeldung.bootcustomfilters.filters; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * A servlet filter to log request and response + * The logging implementation is pretty native and for demonstration only + * @author hemant + * + */ +@Component +@Order(2) +public class RequestResponseLoggingFilter implements Filter { + + private final static Logger LOG = LoggerFactory.getLogger(RequestResponseLoggingFilter.class); + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + LOG.info("Initializing filter :{}", this); + } + + @Override + public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) + throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + HttpServletResponse res = (HttpServletResponse) response; + LOG.info("Logging Request {} : {}", req.getMethod(), req.getRequestURI()); + chain.doFilter(request, response); + LOG.info("Logging Response :{}", res.getContentType()); + } + + @Override + public void destroy() { + LOG.warn("Destructing filter :{}", this); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java new file mode 100644 index 0000000000..604829c3d3 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/filters/TransactionFilter.java @@ -0,0 +1,41 @@ +package com.baeldung.bootcustomfilters.filters; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.core.annotation.Order; +import org.springframework.stereotype.Component; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; + +/** + * A filter to create transaction before and commit it once request completes + * The current implemenatation is just for demo + * @author hemant + * + */ +@Component +@Order(1) +public class TransactionFilter implements Filter { + + private final static Logger LOG = LoggerFactory.getLogger(TransactionFilter.class); + + @Override + public void init(final FilterConfig filterConfig) throws ServletException { + LOG.info("Initializing filter :{}", this); + } + + @Override + public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { + HttpServletRequest req = (HttpServletRequest) request; + LOG.info("Starting Transaction for req :{}", req.getRequestURI()); + chain.doFilter(request, response); + LOG.info("Committing Transaction for req :{}", req.getRequestURI()); + } + + @Override + public void destroy() { + LOG.warn("Destructing filter :{}", this); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/model/User.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/model/User.java new file mode 100644 index 0000000000..ab8e6c8206 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/bootcustomfilters/model/User.java @@ -0,0 +1,45 @@ +package com.baeldung.bootcustomfilters.model; + +/** + * User model + * @author hemant + * + */ +public class User { + + private String id; + private String name; + private String email; + + public User(String id, String name, String email) { + super(); + this.id = id; + this.name = name; + this.email = email; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java new file mode 100644 index 0000000000..3fce0f1289 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/CustomApplication.java @@ -0,0 +1,17 @@ +package com.baeldung.changeport; + +import java.util.Collections; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class CustomApplication { + + public static void main(String[] args) { + SpringApplication app = new SpringApplication(CustomApplication.class); + app.setDefaultProperties(Collections.singletonMap("server.port", "8083")); + app.run(args); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/ServerPortCustomizer.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/ServerPortCustomizer.java new file mode 100644 index 0000000000..f3610aeac6 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/changeport/ServerPortCustomizer.java @@ -0,0 +1,15 @@ +package com.baeldung.changeport; + +import org.springframework.boot.web.server.ConfigurableWebServerFactory; +import org.springframework.boot.web.server.WebServerFactoryCustomizer; +import org.springframework.stereotype.Component; + +//@Component +public class ServerPortCustomizer implements WebServerFactoryCustomizer { + + @Override + public void customize(ConfigurableWebServerFactory factory) { + factory.setPort(8086); + } + +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java new file mode 100644 index 0000000000..9f6c209deb --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/ErrorHandlingApplication.java @@ -0,0 +1,13 @@ +package com.baeldung.errorhandling; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication(scanBasePackages = "com.baeldung.errorhandling") +public class ErrorHandlingApplication { + + public static void main(String [] args) { + System.setProperty("spring.profiles.active", "errorhandling"); + SpringApplication.run(ErrorHandlingApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/IndexController.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/IndexController.java new file mode 100644 index 0000000000..1a8761e96b --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/IndexController.java @@ -0,0 +1,26 @@ +package com.baeldung.errorhandling.controllers; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; + +@Controller +public class IndexController { + + @GetMapping(value = {"/", ""}) + public String index() { + return "index"; + } + + @GetMapping(value = {"/server_error"}) + public String triggerServerError() { + "ser".charAt(30); + return "index"; + } + + @PostMapping(value = {"/general_error"}) + public String triggerGeneralError() { + return "index"; + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java new file mode 100644 index 0000000000..e002ac045d --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/errorhandling/controllers/MyErrorController.java @@ -0,0 +1,40 @@ +package com.baeldung.errorhandling.controllers; + +import org.springframework.boot.web.servlet.error.ErrorController; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; + +import javax.servlet.RequestDispatcher; +import javax.servlet.http.HttpServletRequest; + +@Controller +public class MyErrorController implements ErrorController { + + public MyErrorController() {} + + @GetMapping(value = "/error") + public String handleError(HttpServletRequest request) { + + Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); + + if (status != null) { + + Integer statusCode = Integer.valueOf(status.toString()); + + if(statusCode == HttpStatus.NOT_FOUND.value()) { + return "error-404"; + } + else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) { + return "error-500"; + } + } + return "error"; + } + + @Override + public String getErrorPath() { + return "/error"; + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java new file mode 100644 index 0000000000..d08fa05c6e --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/FailureAnalyzerApplication.java @@ -0,0 +1,14 @@ +package com.baeldung.failureanalyzer; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +import javax.annotation.security.RolesAllowed; + +@SpringBootApplication +public class FailureAnalyzerApplication { + @RolesAllowed("*") + public static void main(String[] args) { + SpringApplication.run(FailureAnalyzerApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyBeanNotOfRequiredTypeFailureAnalyzer.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyBeanNotOfRequiredTypeFailureAnalyzer.java new file mode 100644 index 0000000000..3949908083 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyBeanNotOfRequiredTypeFailureAnalyzer.java @@ -0,0 +1,22 @@ +package com.baeldung.failureanalyzer; + +import org.springframework.beans.factory.BeanNotOfRequiredTypeException; +import org.springframework.boot.diagnostics.AbstractFailureAnalyzer; +import org.springframework.boot.diagnostics.FailureAnalysis; + +public class MyBeanNotOfRequiredTypeFailureAnalyzer extends AbstractFailureAnalyzer { + + @Override + protected FailureAnalysis analyze(Throwable rootFailure, BeanNotOfRequiredTypeException cause) { + return new FailureAnalysis(getDescription(cause), getAction(cause), cause); + } + + private String getDescription(BeanNotOfRequiredTypeException ex) { + return String.format("The bean %s could not be injected as %s because it is of type %s", ex.getBeanName(), ex.getRequiredType().getName(), ex.getActualType().getName()); + } + + private String getAction(BeanNotOfRequiredTypeException ex) { + return String.format("Consider creating a bean with name %s of type %s", ex.getBeanName(), ex.getRequiredType().getName()); + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyDAO.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyDAO.java new file mode 100644 index 0000000000..ddaeb28574 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyDAO.java @@ -0,0 +1,5 @@ +package com.baeldung.failureanalyzer; + +public class MyDAO { + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MySecondDAO.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MySecondDAO.java new file mode 100644 index 0000000000..12dd73a05b --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MySecondDAO.java @@ -0,0 +1,8 @@ +package com.baeldung.failureanalyzer; + +import org.springframework.stereotype.Repository; + +@Repository("myDAO") +public class MySecondDAO { + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java new file mode 100644 index 0000000000..f31b67615f --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/failureanalyzer/MyService.java @@ -0,0 +1,13 @@ +package com.baeldung.failureanalyzer; + +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class MyService { + + @Resource(name = "myDAO") + private MyDAO myDAO; + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java new file mode 100644 index 0000000000..f94549b988 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/FaviconApplication.java @@ -0,0 +1,12 @@ +package com.baeldung.favicon; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class FaviconApplication { + + public static void main(String[] args) { + SpringApplication.run(FaviconApplication.class, args); + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/config/FaviconConfiguration.java b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/config/FaviconConfiguration.java new file mode 100644 index 0000000000..d1809199d6 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/java/com/baeldung/favicon/config/FaviconConfiguration.java @@ -0,0 +1,45 @@ +package com.baeldung.favicon.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; +import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@Configuration +public class FaviconConfiguration { + + @Bean + public SimpleUrlHandlerMapping myFaviconHandlerMapping() { + SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); + mapping.setOrder(Integer.MIN_VALUE); + mapping.setUrlMap(Collections.singletonMap("/favicon.ico", faviconRequestHandler())); + return mapping; + } + + @Bean + protected ResourceHttpRequestHandler faviconRequestHandler() { + ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); + ClassPathResource classPathResource = new ClassPathResource("com/baeldung/images"); + List locations = Arrays.asList(classPathResource); + requestHandler.setLocations(locations); + return requestHandler; + } + + // @Controller + static class FaviconController { + + @RequestMapping(value = "favicon.ico", method = RequestMethod.GET) + @ResponseBody + void favicon() { + } + } +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories new file mode 100644 index 0000000000..336477df96 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer + diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/application-errorhandling.properties b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/application-errorhandling.properties new file mode 100644 index 0000000000..0a6d68763c --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/application-errorhandling.properties @@ -0,0 +1,10 @@ +#server +server.port=9000 +spring.mvc.servlet.path=/ +server.servlet.context-path=/ +server.error.whitelabel.enabled=false + +#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration + +#for Spring Boot 2.0+ +#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/application.properties b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/application.properties new file mode 100644 index 0000000000..4d4a6ec7bd --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/application.properties @@ -0,0 +1,7 @@ +#spring.banner.charset=UTF-8 +#spring.banner.location=classpath:banner.txt +#spring.banner.image.location=classpath:banner.gif +#spring.banner.image.width= //TODO +#spring.banner.image.height= //TODO +#spring.banner.image.margin= //TODO +#spring.banner.image.invert= //TODO diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/banner.txt b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/banner.txt new file mode 100644 index 0000000000..abfa666eb6 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/banner.txt @@ -0,0 +1,14 @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@#@@@@@########@@@@@@@@@@@@@@@@@@@@@@@@...@@@@@@@@@:..@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@#. @@@@@* *@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@#o @@@@@* @@@@@* @@@:*.*@@@@@@@: *8@@@ @@@@&:.#@. @o**@@@@**:@o*o@@:.:@@@@@:.o#@&*:@@@@ +@@@@@@@@@@@@* @@@@@* 8888 8@ @@@8 #@o 8@# .@ @@* :. @* @@@@ @. : &@ ** .@@@@ +@@@@@@@@@@. @ o@@@@@* *@@@o::& .* 8@@@@. @@ 8@@@@. @* @@@@ @. @@@& * @@@@# .@@@@ +@@@@@@@@@& @ @@@@@@* @@@@@@ 8 @@@@ .. o&&&&&&& @@ #@@@@. @* @@@@ @. @@@# * @@@@@ .@@@@ +@@@@@@@@@ @@o @@@@@@@* oooo* 8 @@@& @* @@@ # 88. 88. *& o#: @. @@@# *@ &#& .@@@@ +@@@@@@@@# @@@8 @@@@@@@* .*@@@#. *@@ @@@& :#@@@o .@@: *&@8 @o o@@: @. @@@# *@@#. :8# .@@@@ +@@@@@@@@@ @@@@ &@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@# o@@@@ @@@@@ +@@@@@& &@@@@ 8@@@@@@@@@8&8@@@@@#8#@@@o8@#&@@o&@@@&@@8@@&@@@@88@@8#@8&@@##@@@@@@#8@@#8@@88@@@@@ *@@@@@@@ +@@@# #@@@@#. @@@@@@@@@@@@@8@@8#o@&#@@@@o.@o*@@*.@@@.@&:8o8*@@@8&@@#@@@8@@@@8@#@@@8&@@@@@@#@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/com/baeldung/images/favicon.ico b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/com/baeldung/images/favicon.ico new file mode 100644 index 0000000000..64105ac11c Binary files /dev/null and b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/com/baeldung/images/favicon.ico differ diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/favicon.ico b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/favicon.ico new file mode 100644 index 0000000000..64105ac11c Binary files /dev/null and b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/favicon.ico differ diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/logback.xml b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/logback.xml new file mode 100644 index 0000000000..7d900d8ea8 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/logback.xml @@ -0,0 +1,13 @@ + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + + + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/static/favicon.ico b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/static/favicon.ico new file mode 100644 index 0000000000..64105ac11c Binary files /dev/null and b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/static/favicon.ico differ diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error-404.html b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error-404.html new file mode 100644 index 0000000000..555cf52de4 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error-404.html @@ -0,0 +1,7 @@ + + + +

Sorry, we couldn't find the page you were looking for.

+

Go Home

+ + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error-500.html b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error-500.html new file mode 100644 index 0000000000..fc64c7e180 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error-500.html @@ -0,0 +1,9 @@ + + + +

Sorry, something went wrong!

+ +

We're fixing it.

+

Go Home

+ + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error.html b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error.html new file mode 100644 index 0000000000..4e953059e2 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error.html @@ -0,0 +1,8 @@ + + + +

Something went wrong!

+

Our Engineers are on it.

+

Go Home

+ + diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error/404.html b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error/404.html new file mode 100644 index 0000000000..df83ce219b --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/error/404.html @@ -0,0 +1,8 @@ + + + RESOURCE NOT FOUND + + +

404 RESOURCE NOT FOUND

+ + \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/index.html b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/index.html new file mode 100644 index 0000000000..95c68c8600 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/main/resources/templates/index.html @@ -0,0 +1,6 @@ + + +

Welcome Home

+

Success! It is working as we expected.

+ + diff --git a/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java b/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java new file mode 100644 index 0000000000..2d9fb56217 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/FailureAnalyzerAppIntegrationTest.java @@ -0,0 +1,45 @@ +package com.baeldung.failureanalyzer; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import com.baeldung.failureanalyzer.utils.ListAppender; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.BeanCreationException; +import org.springframework.boot.SpringApplication; + +import java.util.Collection; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; + +public class FailureAnalyzerAppIntegrationTest { + + private static final String EXPECTED_ANALYSIS_DESCRIPTION_TITLE = "Description:"; + private static final String EXPECTED_ANALYSIS_DESCRIPTION_CONTENT = "The bean myDAO could not be injected as com.baeldung.failureanalyzer.MyDAO because it is of type com.baeldung.failureanalyzer.MySecondDAO"; + private static final String EXPECTED_ANALYSIS_ACTION_TITLE = "Action:"; + private static final String EXPECTED_ANALYSIS_ACTION_CONTENT = "Consider creating a bean with name myDAO of type com.baeldung.failureanalyzer.MyDAO"; + + @BeforeEach + public void clearLogList() { + ListAppender.clearEventList(); + } + + @Test + public void givenBeanCreationErrorInContext_whenContextLoaded_thenFailureAnalyzerLogsReport() { + try { + SpringApplication.run(FailureAnalyzerApplication.class); + } catch (BeanCreationException e) { + Collection allLoggedEntries = ListAppender.getEvents() + .stream() + .map(ILoggingEvent::getFormattedMessage) + .collect(Collectors.toList()); + assertThat(allLoggedEntries).anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_DESCRIPTION_TITLE)) + .anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_DESCRIPTION_CONTENT)) + .anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_ACTION_TITLE)) + .anyMatch(entry -> entry.contains(EXPECTED_ANALYSIS_ACTION_CONTENT)); + return; + } + throw new IllegalStateException("Context load should be failing due to a BeanCreationException!"); + } + +} diff --git a/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/utils/ListAppender.java b/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/utils/ListAppender.java new file mode 100644 index 0000000000..091cd687f1 --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/test/java/com/baeldung/failureanalyzer/utils/ListAppender.java @@ -0,0 +1,25 @@ +package com.baeldung.failureanalyzer.utils; + +import ch.qos.logback.classic.spi.ILoggingEvent; +import ch.qos.logback.core.AppenderBase; + +import java.util.ArrayList; +import java.util.List; + +public class ListAppender extends AppenderBase { + + static private List events = new ArrayList<>(); + + @Override + protected void append(ILoggingEvent eventObject) { + events.add(eventObject); + } + + public static List getEvents() { + return events; + } + + public static void clearEventList() { + events.clear(); + } +} \ No newline at end of file diff --git a/spring-boot-modules/spring-boot-basic-customization/src/test/resources/logback-test.xml b/spring-boot-modules/spring-boot-basic-customization/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..6919a457cb --- /dev/null +++ b/spring-boot-modules/spring-boot-basic-customization/src/test/resources/logback-test.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file