JAVA-8293 Split or move spring boot module
This commit is contained in:
@@ -4,3 +4,8 @@ This module contains articles about Spring Boot Actuator in Spring Boot version
|
||||
|
||||
## Relevant articles:
|
||||
- [Spring Boot Actuator](https://www.baeldung.com/spring-boot-actuators)
|
||||
- [A Quick Intro to the SpringBootServletInitializer](https://www.baeldung.com/spring-boot-servlet-initializer)
|
||||
- [Spring Shutdown Callbacks](https://www.baeldung.com/spring-shutdown-callbacks)
|
||||
- [Dynamic DTO Validation Config Retrieved from the Database](https://www.baeldung.com/spring-dynamic-dto-validation)
|
||||
|
||||
|
||||
|
||||
@@ -20,14 +20,36 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</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-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-tomcat</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.14.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
@@ -40,6 +62,7 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.dynamicvalidation;
|
||||
|
||||
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
|
||||
import static java.lang.annotation.ElementType.CONSTRUCTOR;
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.ElementType.PARAMETER;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.Payload;
|
||||
|
||||
@Constraint(validatedBy = { ContactInfoValidator.class })
|
||||
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ContactInfo {
|
||||
String message() default "Invalid value";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.dynamicvalidation;
|
||||
|
||||
import com.baeldung.dynamicvalidation.dao.ContactInfoExpressionRepository;
|
||||
import com.baeldung.dynamicvalidation.model.ContactInfoExpression;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.thymeleaf.util.StringUtils;
|
||||
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ContactInfoValidator implements ConstraintValidator<ContactInfo, String> {
|
||||
|
||||
private static final Logger LOG = LogManager.getLogger(ContactInfoValidator.class);
|
||||
|
||||
@Autowired
|
||||
private ContactInfoExpressionRepository expressionRepository;
|
||||
|
||||
@Value("${contactInfoType}")
|
||||
String expressionType;
|
||||
|
||||
private String pattern;
|
||||
|
||||
@Override
|
||||
public void initialize(final ContactInfo contactInfo) {
|
||||
if (StringUtils.isEmptyOrWhitespace(expressionType)) {
|
||||
LOG.error("Contact info type missing!");
|
||||
} else {
|
||||
pattern = expressionRepository.findById(expressionType).map(ContactInfoExpression::getPattern).orElse("");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(final String value, final ConstraintValidatorContext context) {
|
||||
if (!StringUtils.isEmptyOrWhitespace(pattern)) {
|
||||
return Pattern.matches(pattern, value);
|
||||
}
|
||||
LOG.error("Contact info pattern missing!");
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.dynamicvalidation;
|
||||
|
||||
import javax.annotation.security.RolesAllowed;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DynamicValidationApp {
|
||||
@RolesAllowed("*")
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DynamicValidationApp.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.baeldung.dynamicvalidation.config;
|
||||
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import com.baeldung.dynamicvalidation.model.Customer;
|
||||
|
||||
@Controller
|
||||
public class CustomerController {
|
||||
|
||||
@GetMapping("/customer")
|
||||
public String getCustomerPage(Model model) {
|
||||
return "customer";
|
||||
}
|
||||
|
||||
@PostMapping("/customer")
|
||||
public String validateCustomer(@Valid final Customer customer, final BindingResult result, final Model model) {
|
||||
if (result.hasErrors()) {
|
||||
model.addAttribute("message", "The information is invalid!");
|
||||
} else {
|
||||
model.addAttribute("message", "The information is valid!");
|
||||
}
|
||||
return "customer";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.baeldung.dynamicvalidation.config;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
@EnableJpaRepositories("com.baeldung.dynamicvalidation.dao")
|
||||
@EntityScan("com.baeldung.dynamicvalidation.model")
|
||||
@Configuration
|
||||
public class PersistenceConfig {
|
||||
|
||||
@Bean
|
||||
public DataSource dataSource() {
|
||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
|
||||
EmbeddedDatabase db = builder.setType(EmbeddedDatabaseType.H2).addScript("schema-expressions.sql").addScript("data-expressions.sql").build();
|
||||
return db;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.baeldung.dynamicvalidation.dao;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
import com.baeldung.dynamicvalidation.model.ContactInfoExpression;
|
||||
|
||||
public interface ContactInfoExpressionRepository extends Repository<ContactInfoExpression, String> {
|
||||
Optional<ContactInfoExpression> findById(String id);
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.dynamicvalidation.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class ContactInfoExpression {
|
||||
|
||||
@Id
|
||||
@Column(name = "expression_type")
|
||||
private String type;
|
||||
private String pattern;
|
||||
|
||||
public ContactInfoExpression() {
|
||||
|
||||
}
|
||||
|
||||
public ContactInfoExpression(final String type, final String pattern) {
|
||||
this.type = type;
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(final String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getPattern() {
|
||||
return pattern;
|
||||
}
|
||||
|
||||
public void setPattern(final String pattern) {
|
||||
this.pattern = pattern;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.baeldung.dynamicvalidation.model;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.validation.constraints.NotNull;
|
||||
|
||||
import com.baeldung.dynamicvalidation.ContactInfo;
|
||||
|
||||
@Entity
|
||||
public class Customer {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private long id;
|
||||
|
||||
@ContactInfo
|
||||
@NotNull
|
||||
private String contactInfo;
|
||||
|
||||
public Customer() {
|
||||
}
|
||||
|
||||
public Customer(final long id, final String contactInfo) {
|
||||
this.id = id;
|
||||
this.contactInfo = contactInfo;
|
||||
}
|
||||
|
||||
public String getContactInfo() {
|
||||
return contactInfo;
|
||||
}
|
||||
|
||||
public void setContactInfo(final String contactInfo) {
|
||||
this.contactInfo = contactInfo;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(final long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.baeldung.servletinitializer;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.builder.SpringApplicationBuilder;
|
||||
//import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@SpringBootApplication
|
||||
public class WarInitializerApplication extends SpringBootServletInitializer {
|
||||
|
||||
@Override
|
||||
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
|
||||
return builder.sources(WarInitializerApplication.class);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication sa = new SpringApplication(WarInitializerApplication.class);
|
||||
sa.setLogStartupInfo(false);
|
||||
sa.run(args);
|
||||
}
|
||||
|
||||
@RestController
|
||||
public static class WarInitializerController {
|
||||
|
||||
@GetMapping("/")
|
||||
public String handler(Model model) {
|
||||
model.addAttribute("date", LocalDateTime.now());
|
||||
return "WarInitializerApplication is up and running!";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.shutdownhooks;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableAutoConfiguration
|
||||
public class ShutdownHookApplication {
|
||||
|
||||
public static void main(String args[]) {
|
||||
SpringApplication.run(ShutdownHookApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.shutdownhooks.beans;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Bean1 {
|
||||
|
||||
@PreDestroy
|
||||
public void destroy() {
|
||||
System.out.println("Shutdown triggered using @PreDestroy.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.baeldung.shutdownhooks.beans;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class Bean2 implements DisposableBean {
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
System.out.println("Shutdown triggered using DisposableBean.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.baeldung.shutdownhooks.beans;
|
||||
|
||||
public class Bean3 {
|
||||
|
||||
public void destroy() {
|
||||
System.out.println("Shutdown triggered using bean destroy method.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.shutdownhooks.config;
|
||||
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
public class ExampleServletContextListener implements ServletContextListener {
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent event) {
|
||||
System.out.println("Shutdown triggered using ServletContextListener.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent event) {
|
||||
// Triggers when context initializes
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.shutdownhooks.config;
|
||||
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
||||
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.baeldung.shutdownhooks.beans.Bean3;
|
||||
|
||||
@Configuration
|
||||
public class ShutdownHookConfiguration {
|
||||
|
||||
@Bean(destroyMethod = "destroy")
|
||||
public Bean3 initializeBean3() {
|
||||
return new Bean3();
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletListenerRegistrationBean<ServletContextListener> servletListener() {
|
||||
ServletListenerRegistrationBean<ServletContextListener> srb = new ServletListenerRegistrationBean<>();
|
||||
srb.setListener(new ExampleServletContextListener());
|
||||
return srb;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.baeldung.servletinitializer;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
|
||||
import com.baeldung.servletinitializer.WarInitializerApplication.WarInitializerController;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@WebMvcTest(controllers = WarInitializerController.class)
|
||||
public class WarInitializerApplicationIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Test
|
||||
public void whenContextRootUrlIsAccessed_thenStatusIsOk() throws Exception {
|
||||
mockMvc.perform(get("/"))
|
||||
.andExpect(status().is(200));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenContextRootUrlIsAccesed_thenCorrectStringIsReturned() throws Exception {
|
||||
mockMvc.perform(get("/"))
|
||||
.andExpect(content().string(containsString("WarInitializerApplication is up and running!")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
spring.mail.host=localhost
|
||||
spring.mail.port=8025
|
||||
spring.mail.properties.mail.smtp.auth=false
|
||||
|
||||
# spring.datasource.x
|
||||
spring.datasource.driver-class-name=org.h2.Driver
|
||||
spring.datasource.url=jdbc:h2:mem:db;DB_CLOSE_DELAY=-1
|
||||
spring.datasource.username=sa
|
||||
spring.datasource.password=sa
|
||||
|
||||
# hibernate.X
|
||||
spring.jpa.hibernate.dialect=org.hibernate.dialect.H2Dialect
|
||||
spring.jpa.hibernate.ddl-auto=create-drop
|
||||
spring.jpa.hibernate.show_sql=true
|
||||
spring.jpa.hibernate.hbm2ddl.auto=create-drop
|
||||
spring.jpa.hibernate.cache.use_second_level_cache=true
|
||||
spring.jpa.hibernate.cache.use_query_cache=true
|
||||
spring.jpa.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
|
||||
|
||||
management.security.enabled=false
|
||||
Reference in New Issue
Block a user