Merge remote-tracking branch 'upstream/master' into BAEL-4590
This commit is contained in:
commit
e9eb203671
|
@ -6,6 +6,7 @@ import org.junit.jupiter.api.BeforeEach;
|
|||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
@ -37,6 +38,12 @@ public class CreateFileUnitTest {
|
|||
assertTrue(success);
|
||||
}
|
||||
|
||||
@Test
|
||||
void givenUsingFileOutputStream_whenCreatingFile_thenCorrect() throws IOException {
|
||||
try(FileOutputStream fileOutputStream = new FileOutputStream(FILE_NAME)){
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenUsingGuava_whenCreatingFile_thenCorrect() throws IOException {
|
||||
com.google.common.io.Files.touch(new File(FILE_NAME));
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.baeldung.arguments
|
||||
|
||||
fun main() {
|
||||
|
||||
// Skip both the connectTimeout and enableRetry arguments
|
||||
connect("http://www.baeldung.com")
|
||||
|
||||
// Skip only the enableRetry argument:
|
||||
connect("http://www.baeldung.com", 5000)
|
||||
|
||||
// Skip only the middle argument connectTimeout
|
||||
// connect("http://www.baeldung.com", false) // This results in a compiler error
|
||||
|
||||
// Because we skipped the connectTimeout argument, we must pass the enableRetry as a named argument
|
||||
connect("http://www.baeldung.com", enableRetry = false)
|
||||
|
||||
// Overriding Functions and Default Arguments
|
||||
val realConnector = RealConnector()
|
||||
realConnector.connect("www.baeldung.com")
|
||||
realConnector.connect()
|
||||
}
|
||||
|
||||
fun connect(url: String, connectTimeout: Int = 1000, enableRetry: Boolean = true) {
|
||||
println("The parameters are url = $url, connectTimeout = $connectTimeout, enableRetry = $enableRetry")
|
||||
}
|
||||
|
||||
open class AbstractConnector {
|
||||
open fun connect(url: String = "localhost") {
|
||||
// function implementation
|
||||
}
|
||||
}
|
||||
|
||||
class RealConnector : AbstractConnector() {
|
||||
override fun connect(url: String) {
|
||||
println("The parameter is url = $url")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.arguments
|
||||
|
||||
fun main() {
|
||||
resizePane(newSize = 10, forceResize = true, noAnimation = false)
|
||||
|
||||
// Swap the order of last two named arguments
|
||||
resizePane(newSize = 11, noAnimation = false, forceResize = true)
|
||||
|
||||
// Named arguments can be passed in any order
|
||||
resizePane(forceResize = true, newSize = 12, noAnimation = false)
|
||||
|
||||
// Mixing Named and Positional Arguments
|
||||
// Kotlin 1.3 would allow us to name only the arguments after the positional ones
|
||||
resizePane(20, true, noAnimation = false)
|
||||
|
||||
// Using a positional argument in the middle of named arguments (supported from Kotlin 1.4.0)
|
||||
// resizePane(newSize = 20, true, noAnimation = false)
|
||||
|
||||
// Only the last argument as a positional argument (supported from Kotlin 1.4.0)
|
||||
// resizePane(newSize = 30, forceResize = true, false)
|
||||
|
||||
// Use a named argument in the middle of positional arguments (supported from Kotlin 1.4.0)
|
||||
// resizePane(40, forceResize = true, false)
|
||||
}
|
||||
|
||||
fun resizePane(newSize: Int, forceResize: Boolean, noAnimation: Boolean) {
|
||||
println("The parameters are newSize = $newSize, forceResize = $forceResize, noAnimation = $noAnimation")
|
||||
}
|
2
pom.xml
2
pom.xml
|
@ -977,7 +977,7 @@
|
|||
<module>jjwt</module>
|
||||
<module>jmeter</module>
|
||||
<module>jmh</module>
|
||||
<module>jni</module>
|
||||
<module>java-native</module>
|
||||
<module>jooby</module>
|
||||
<module>jsf</module>
|
||||
<module>json</module>
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.annotations;
|
||||
|
||||
import com.baeldung.annotations.componentscanautoconfigure.teacher.Teacher;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
@ComponentScan(basePackages = {"com.baeldung.annotations.componentscanautoconfigure.healthcare",
|
||||
"com.baeldung.annotations.componentscanautoconfigure.employee"},
|
||||
basePackageClasses = Teacher.class)
|
||||
@EnableAutoConfiguration(exclude = {JdbcTemplateAutoConfiguration.class})
|
||||
//@EnableAutoConfiguration(excludeName = {"org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration"})
|
||||
public class EmployeeApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(EmployeeApplication.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.annotations.componentscanautoconfigure.employee;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("employee")
|
||||
public class Employee {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Employee" + this.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.annotations.componentscanautoconfigure.employee;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SeniorEmployee {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Senior Employee" + this.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.baeldung.annotations.componentscanautoconfigure.healthcare;
|
||||
|
||||
public class Doctor {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Doctor" + this.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package com.baeldung.annotations.componentscanautoconfigure.healthcare;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class Hospital {
|
||||
|
||||
@Bean("doctor")
|
||||
public Doctor getDoctor() {
|
||||
return new Doctor();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.annotations.componentscanautoconfigure.student;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("student")
|
||||
public class Student {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student" + this.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.annotations.componentscanautoconfigure.teacher;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("teacher")
|
||||
public class Teacher {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Teacher" + this.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.baeldung.annotations;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
|
||||
public class EmployeeApplicationTest {
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withUserConfiguration(EmployeeApplication.class);
|
||||
|
||||
@Test
|
||||
void whenApplicationContextRuns_thenContainAllDefinedBeans() {
|
||||
contextRunner.run(context -> assertAll(
|
||||
() -> assertTrue(context.containsBeanDefinition("employee")),
|
||||
() -> assertTrue(context.containsBeanDefinition("seniorEmployee")),
|
||||
() -> assertTrue(context.containsBeanDefinition("doctor")),
|
||||
() -> assertTrue(context.containsBeanDefinition("hospital")),
|
||||
() -> assertFalse(context.containsBeanDefinition("student")),
|
||||
() -> assertTrue(context.containsBeanDefinition("teacher"))));
|
||||
}
|
||||
}
|
|
@ -76,7 +76,7 @@
|
|||
</build>
|
||||
|
||||
<properties>
|
||||
<keycloak-adapter-bom.version>10.0.2</keycloak-adapter-bom.version>
|
||||
<keycloak-adapter-bom.version>11.0.2</keycloak-adapter-bom.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -1,37 +1,61 @@
|
|||
package com.baeldung.spring.configuration;
|
||||
|
||||
import freemarker.cache.ClassTemplateLoader;
|
||||
import freemarker.cache.TemplateLoader;
|
||||
import freemarker.template.Configuration;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.PropertySource;
|
||||
import org.springframework.context.support.ResourceBundleMessageSource;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
|
||||
import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver;
|
||||
import org.thymeleaf.spring5.SpringTemplateEngine;
|
||||
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
|
||||
import org.thymeleaf.templateresolver.ITemplateResolver;
|
||||
|
||||
@Configuration
|
||||
@ComponentScan(basePackages = { "com.baeldung.spring.mail" })
|
||||
@PropertySource(value={"classpath:application.properties"})
|
||||
public class EmailConfiguration {
|
||||
|
||||
@Value("${spring.mail.host}")
|
||||
private String mailServerHost;
|
||||
|
||||
@Value("${spring.mail.port}")
|
||||
private Integer mailServerPort;
|
||||
|
||||
@Value("${spring.mail.username}")
|
||||
private String mailServerUsername;
|
||||
|
||||
@Value("${spring.mail.password}")
|
||||
private String mailServerPassword;
|
||||
|
||||
@Value("${spring.mail.properties.mail.smtp.auth}")
|
||||
private String mailServerAuth;
|
||||
|
||||
@Value("${spring.mail.properties.mail.smtp.starttls.enable}")
|
||||
private String mailServerStartTls;
|
||||
|
||||
@Value("${spring.mail.templates.path}")
|
||||
private String mailTemplatesPath;
|
||||
|
||||
@Bean
|
||||
public JavaMailSender getJavaMailSender() {
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
|
||||
mailSender.setHost("smtp.gmail.com");
|
||||
mailSender.setPort(587);
|
||||
mailSender.setHost(mailServerHost);
|
||||
mailSender.setPort(mailServerPort);
|
||||
|
||||
mailSender.setUsername("my.gmail@gmail.com");
|
||||
mailSender.setPassword("password");
|
||||
mailSender.setUsername(mailServerUsername);
|
||||
mailSender.setPassword(mailServerPassword);
|
||||
|
||||
Properties props = mailSender.getJavaMailProperties();
|
||||
props.put("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.starttls.enable", "false");
|
||||
props.put("mail.smtp.auth", mailServerAuth);
|
||||
props.put("mail.smtp.starttls.enable", mailServerStartTls);
|
||||
props.put("mail.debug", "true");
|
||||
|
||||
return mailSender;
|
||||
|
@ -45,39 +69,52 @@ public class EmailConfiguration {
|
|||
}
|
||||
|
||||
@Bean
|
||||
public SpringTemplateEngine thymeleafTemplateEngine() {
|
||||
public SpringTemplateEngine thymeleafTemplateEngine(ITemplateResolver templateResolver) {
|
||||
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
|
||||
templateEngine.setTemplateResolver(thymeleafTemplateResolver());
|
||||
templateEngine.setTemplateResolver(templateResolver);
|
||||
templateEngine.setTemplateEngineMessageSource(emailMessageSource());
|
||||
return templateEngine;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SpringResourceTemplateResolver thymeleafTemplateResolver() {
|
||||
SpringResourceTemplateResolver templateResolver = new SpringResourceTemplateResolver();
|
||||
templateResolver.setPrefix("/WEB-INF/views/mail/");
|
||||
public ITemplateResolver thymeleafClassLoaderTemplateResolver() {
|
||||
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
|
||||
templateResolver.setPrefix(mailTemplatesPath + "/");
|
||||
templateResolver.setSuffix(".html");
|
||||
templateResolver.setTemplateMode("HTML");
|
||||
templateResolver.setCharacterEncoding("UTF-8");
|
||||
return templateResolver;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public ITemplateResolver thymeleafFilesystemTemplateResolver() {
|
||||
// FileTemplateResolver templateResolver = new FileTemplateResolver();
|
||||
// templateResolver.setPrefix(mailTemplatesPath + "/");
|
||||
// templateResolver.setSuffix(".html");
|
||||
// templateResolver.setTemplateMode("HTML");
|
||||
// templateResolver.setCharacterEncoding("UTF-8");
|
||||
// return templateResolver;
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public FreeMarkerConfigurer freemarkerConfig() {
|
||||
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
|
||||
freeMarkerConfigurer.setTemplateLoaderPath("/WEB-INF/views/mail");
|
||||
public FreeMarkerConfigurer freemarkerClassLoaderConfig() {
|
||||
Configuration configuration = new Configuration(Configuration.VERSION_2_3_27);
|
||||
TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), "/" + mailTemplatesPath);
|
||||
configuration.setTemplateLoader(templateLoader);
|
||||
FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
|
||||
freeMarkerConfigurer.setConfiguration(configuration);
|
||||
return freeMarkerConfigurer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public FreeMarkerViewResolver freemarkerViewResolver() {
|
||||
FreeMarkerViewResolver resolver = new FreeMarkerViewResolver();
|
||||
resolver.setCache(true);
|
||||
resolver.setPrefix("");
|
||||
resolver.setSuffix(".ftl");
|
||||
return resolver;
|
||||
}
|
||||
|
||||
// @Bean
|
||||
// public FreeMarkerConfigurer freemarkerFilesystemConfig() throws IOException {
|
||||
// Configuration configuration = new Configuration(Configuration.VERSION_2_3_27);
|
||||
// TemplateLoader templateLoader = new FileTemplateLoader(new File(mailTemplatesPath));
|
||||
// configuration.setTemplateLoader(templateLoader);
|
||||
// FreeMarkerConfigurer freeMarkerConfigurer = new FreeMarkerConfigurer();
|
||||
// freeMarkerConfigurer.setConfiguration(configuration);
|
||||
// return freeMarkerConfigurer;
|
||||
// }
|
||||
|
||||
@Bean
|
||||
public ResourceBundleMessageSource emailMessageSource() {
|
||||
|
|
|
@ -112,7 +112,7 @@ public class EmailServiceImpl implements EmailService {
|
|||
String to, String subject, Map<String, Object> templateModel)
|
||||
throws IOException, TemplateException, MessagingException {
|
||||
|
||||
Template freemarkerTemplate = freemarkerConfigurer.createConfiguration().getTemplate("template-freemarker.ftl");
|
||||
Template freemarkerTemplate = freemarkerConfigurer.getConfiguration().getTemplate("template-freemarker.ftl");
|
||||
String htmlBody = FreeMarkerTemplateUtils.processTemplateIntoString(freemarkerTemplate, templateModel);
|
||||
|
||||
sendHtmlMessage(to, subject, htmlBody);
|
||||
|
|
|
@ -6,7 +6,7 @@ spring.mail.port=587
|
|||
spring.mail.username=username
|
||||
spring.mail.password=password
|
||||
spring.mail.properties.mail.smtp.auth=true
|
||||
spring.mail.properties.mail.smtp.starttls.enable=true
|
||||
spring.mail.properties.mail.smtp.starttls.enable=false
|
||||
|
||||
# Amazon SES SMTP
|
||||
#spring.mail.host=email-smtp.us-west-2.amazonaws.com
|
||||
|
@ -19,4 +19,14 @@ spring.mail.properties.mail.smtp.starttls.enable=true
|
|||
#spring.mail.properties.mail.smtp.starttls.required=true
|
||||
|
||||
# path to attachment file
|
||||
attachment.invoice=path_to_file
|
||||
attachment.invoice=path_to_file
|
||||
|
||||
|
||||
#
|
||||
# Mail templates
|
||||
#
|
||||
|
||||
# Templates directory inside main/resources or absolute filesystem path
|
||||
spring.mail.templates.path=mail-templates
|
||||
#spring.mail.templates.path=/path/to/templates
|
||||
|
||||
|
|
Loading…
Reference in New Issue