Merge pull request #8911 from kwoyke/JAVA-86
JAVA-86: Create spring-boot-basic-customization module
This commit is contained in:
commit
63a14ce5ca
|
@ -20,6 +20,7 @@
|
||||||
<module>spring-boot-annotations</module>
|
<module>spring-boot-annotations</module>
|
||||||
<module>spring-boot-artifacts</module>
|
<module>spring-boot-artifacts</module>
|
||||||
<module>spring-boot-autoconfiguration</module>
|
<module>spring-boot-autoconfiguration</module>
|
||||||
|
<module>spring-boot-basic-customization</module>
|
||||||
<module>spring-boot-bootstrap</module>
|
<module>spring-boot-bootstrap</module>
|
||||||
<module>spring-boot-client</module>
|
<module>spring-boot-client</module>
|
||||||
<module>spring-boot-config-jpa-error</module>
|
<module>spring-boot-config-jpa-error</module>
|
||||||
|
|
|
@ -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)
|
|
@ -0,0 +1,45 @@
|
||||||
|
<?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>
|
||||||
|
<artifactId>spring-boot-basic-customization</artifactId>
|
||||||
|
<name>spring-boot-basic-customization</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
<description>Module For Spring Boot Basic Customization</description>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>com.baeldung</groupId>
|
||||||
|
<artifactId>parent-boot-2</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../parent-boot-2</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<!-- The main class to start by executing "java -jar" -->
|
||||||
|
<start-class>com.baeldung.changeport.CustomApplication</start-class>
|
||||||
|
</properties>
|
||||||
|
</project>
|
|
@ -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<RequestResponseLoggingFilter> loggingFilter() {
|
||||||
|
FilterRegistrationBean<RequestResponseLoggingFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
|
|
||||||
|
registrationBean.setFilter(new RequestResponseLoggingFilter());
|
||||||
|
|
||||||
|
registrationBean.addUrlPatterns("/users/*");
|
||||||
|
|
||||||
|
return registrationBean;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<User> 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"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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<ConfigurableWebServerFactory> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(ConfigurableWebServerFactory factory) {
|
||||||
|
factory.setPort(8086);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<BeanNotOfRequiredTypeException> {
|
||||||
|
|
||||||
|
@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());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package com.baeldung.failureanalyzer;
|
||||||
|
|
||||||
|
public class MyDAO {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package com.baeldung.failureanalyzer;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository("myDAO")
|
||||||
|
public class MySecondDAO {
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<Resource> locations = Arrays.asList(classPathResource);
|
||||||
|
requestHandler.setLocations(locations);
|
||||||
|
return requestHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Controller
|
||||||
|
static class FaviconController {
|
||||||
|
|
||||||
|
@RequestMapping(value = "favicon.ico", method = RequestMethod.GET)
|
||||||
|
@ResponseBody
|
||||||
|
void favicon() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
org.springframework.boot.diagnostics.FailureAnalyzer=com.baeldung.failureanalyzer.MyBeanNotOfRequiredTypeFailureAnalyzer
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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&@@@@@@#@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||||
|
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,13 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||||
|
</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
|
<root level="INFO">
|
||||||
|
<appender-ref ref="STDOUT" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1> Sorry, we couldn't find the page you were looking for. </h1>
|
||||||
|
<p><a href="/">Go Home</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1> Sorry, something went wrong! </h1>
|
||||||
|
|
||||||
|
<h2>We're fixing it.</h2>
|
||||||
|
<p><a href="/">Go Home</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1> Something went wrong! </h1>
|
||||||
|
<h2>Our Engineers are on it.</h2>
|
||||||
|
<p><a href="/">Go Home</a></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>RESOURCE NOT FOUND</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>404 RESOURCE NOT FOUND</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<h1>Welcome Home</h1>
|
||||||
|
<p><strong>Success!</strong> It is working as we expected.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -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<String> 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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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<ILoggingEvent> {
|
||||||
|
|
||||||
|
static private List<ILoggingEvent> events = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void append(ILoggingEvent eventObject) {
|
||||||
|
events.add(eventObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<ILoggingEvent> getEvents() {
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void clearEventList() {
|
||||||
|
events.clear();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<configuration>
|
||||||
|
<include
|
||||||
|
resource="org/springframework/boot/logging/logback/base.xml" />
|
||||||
|
<appender name="LISTAPPENDER"
|
||||||
|
class="com.baeldung.failureanalyzer.utils.ListAppender">
|
||||||
|
</appender>
|
||||||
|
<logger
|
||||||
|
name="org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter">
|
||||||
|
<appender-ref ref="LISTAPPENDER" />
|
||||||
|
</logger>
|
||||||
|
<root level="info">
|
||||||
|
<appender-ref ref="CONSOLE" />
|
||||||
|
</root>
|
||||||
|
</configuration>
|
Loading…
Reference in New Issue