Merge branch 'master' of https://github.com/eugenp/tutorials.git
This commit is contained in:
commit
52a66320cb
|
@ -2,4 +2,4 @@
|
|||
|
||||
## Core Java 9 Examples
|
||||
|
||||
http://inprogress.baeldung.com/java-9-new-features/
|
||||
[Java 9 New Features](http://www.baeldung.com/new-java-9)
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package com.baeldung.java9.language.stream;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static java.lang.Integer.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class StreamFeaturesTest {
|
||||
|
||||
public static class TakeAndDropWhileTest {
|
||||
|
||||
public Stream<String> getStreamAfterTakeWhileOperation() {
|
||||
return Stream
|
||||
.iterate("", s -> s + "s")
|
||||
.takeWhile(s -> s.length() < 10);
|
||||
}
|
||||
|
||||
public Stream<String> getStreamAfterDropWhileOperation() {
|
||||
return Stream
|
||||
.iterate("", s -> s + "s")
|
||||
.takeWhile(s -> s.length() < 10)
|
||||
.dropWhile(s -> !s.contains("sssss"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTakeWhileOperation() {
|
||||
List<String> list = getStreamAfterTakeWhileOperation().collect(Collectors.toList());
|
||||
|
||||
assertEquals(10, list.size());
|
||||
|
||||
assertEquals("", list.get(0));
|
||||
assertEquals("ss", list.get(2));
|
||||
assertEquals("sssssssss", list.get(list.size() - 1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDropWhileOperation() {
|
||||
List<String> list = getStreamAfterDropWhileOperation().collect(Collectors.toList());
|
||||
|
||||
assertEquals(5, list.size());
|
||||
|
||||
assertEquals("sssss", list.get(0));
|
||||
assertEquals("sssssss", list.get(2));
|
||||
assertEquals("sssssssss", list.get(list.size() - 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class IterateTest {
|
||||
|
||||
private Stream<Integer> getStream() {
|
||||
return Stream.iterate(0, i -> i < 10, i -> i + 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIterateOperation() {
|
||||
List<Integer> list = getStream().collect(Collectors.toList());
|
||||
|
||||
assertEquals(10, list.size());
|
||||
|
||||
assertEquals(valueOf(0), list.get(0));
|
||||
assertEquals(valueOf(5), list.get(5));
|
||||
assertEquals(valueOf(9), list.get(list.size() - 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class OfNullableTest {
|
||||
|
||||
private List<String> collection = Arrays.asList("A", "B", "C");
|
||||
private Map<String, Integer> map = new HashMap<>() {{
|
||||
put("A", 10);
|
||||
put("C", 30);
|
||||
}};
|
||||
|
||||
private Stream<Integer> getStreamWithOfNullable() {
|
||||
return collection.stream()
|
||||
.flatMap(s -> Stream.ofNullable(map.get(s)));
|
||||
}
|
||||
|
||||
private Stream<Integer> getStream() {
|
||||
return collection.stream()
|
||||
.flatMap(s -> {
|
||||
Integer temp = map.get(s);
|
||||
return temp != null ? Stream.of(temp) : Stream.empty();
|
||||
});
|
||||
}
|
||||
|
||||
private List<Integer> testOfNullableFrom(Stream<Integer> stream) {
|
||||
List<Integer> list = stream.collect(Collectors.toList());
|
||||
|
||||
assertEquals(2, list.size());
|
||||
|
||||
assertEquals(valueOf(10), list.get(0));
|
||||
assertEquals(valueOf(30), list.get(list.size() - 1));
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOfNullable() {
|
||||
|
||||
assertEquals(
|
||||
testOfNullableFrom(getStream()),
|
||||
testOfNullableFrom(getStreamWithOfNullable())
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -35,4 +35,5 @@
|
|||
- [Java 8 Streams Advanced](http://www.baeldung.com/java-8-streams)
|
||||
- [Introduction to Thread Pools in Java](http://www.baeldung.com/thread-pool-java-and-guava)
|
||||
- [Introduction to Java 8 Streams](http://www.baeldung.com/java-8-streams-introduction)
|
||||
- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
|
||||
- [Guide to the Fork/Join Framework in Java](http://www.baeldung.com/java-fork-join)
|
||||
- [How to Print Screen in Java](http://www.baeldung.com/print-screen-in-java)
|
||||
|
|
|
@ -0,0 +1,97 @@
|
|||
package com.baeldung.java.conversion;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.Month;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.baeldung.datetime.UseLocalDateTime;
|
||||
|
||||
public class StringConversionTest {
|
||||
|
||||
@Test
|
||||
public void whenConvertedToInt_thenCorrect() {
|
||||
assertEquals(Integer.parseInt("1"), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToInteger_thenCorrect() {
|
||||
assertEquals(Integer.valueOf("12").equals(12), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedTolong_thenCorrect() {
|
||||
assertEquals(Long.parseLong("12345"), 12345);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToLong_thenCorrect() {
|
||||
assertEquals(Long.valueOf("14567").equals(14567L), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedTodouble_thenCorrect() {
|
||||
assertEquals(Double.parseDouble("1.4"), 1.4, 0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToDouble_thenCorrect() {
|
||||
assertEquals(Double.valueOf("145.67").equals(145.67d), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToByteArray_thenCorrect() throws UnsupportedEncodingException {
|
||||
byte[] byteArray1 = new byte[] { 'a', 'b', 'c' };
|
||||
String string = new String(byteArray1, "UTF-8");
|
||||
|
||||
assertEquals(Arrays.equals(string.getBytes(), byteArray1), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToboolean_thenCorrect() {
|
||||
assertEquals(Boolean.parseBoolean("true"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToBoolean_thenCorrect() {
|
||||
assertEquals(Boolean.valueOf("true"), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToCharArray_thenCorrect() {
|
||||
String str = "hello";
|
||||
char[] charArray = { 'h', 'e', 'l', 'l', 'o' };
|
||||
|
||||
assertEquals(Arrays.equals(charArray, str.toCharArray()), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToDate_thenCorrect() throws ParseException {
|
||||
String str = "15/10/2013";
|
||||
SimpleDateFormat formatter = new SimpleDateFormat("dd/M/yyyy");
|
||||
Date date1 = formatter.parse(str);
|
||||
Calendar calendar = new GregorianCalendar(2013, 9, 15);
|
||||
Date date2 = calendar.getTime();
|
||||
|
||||
assertEquals(date1.compareTo(date2), 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenConvertedToLocalDateTime_thenCorrect() throws ParseException {
|
||||
String str = "2007-12-03T10:15:30";
|
||||
LocalDateTime localDateTime = new UseLocalDateTime().getLocalDateTimeUsingParseMethod(str);
|
||||
|
||||
assertEquals(localDateTime.getDayOfMonth(), 3);
|
||||
assertEquals(localDateTime.getMonth(), Month.DECEMBER);
|
||||
assertEquals(localDateTime.getYear(), 2007);
|
||||
}
|
||||
}
|
|
@ -1,36 +1,28 @@
|
|||
package org.baeldung.httpclient;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.conn.ClientConnectionManager;
|
||||
import org.apache.http.conn.scheme.Scheme;
|
||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.SSLContextBuilder;
|
||||
import org.apache.http.conn.ssl.SSLContexts;
|
||||
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
|
||||
import org.apache.http.conn.ssl.TrustStrategy;
|
||||
import org.apache.http.conn.ssl.*;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.conn.PoolingClientConnectionManager;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLException;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* This test requires a localhost server over HTTPS <br>
|
||||
* It should only be manually run, not part of the automated build
|
||||
|
@ -101,17 +93,9 @@ public class HttpsClientSslLiveTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public final void givenIgnoringCertificates_whenHttpsUrlIsConsumed_thenCorrect() throws IOException {
|
||||
|
||||
final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
|
||||
|
||||
SSLContext sslContext = null;
|
||||
try {
|
||||
sslContext = new SSLContextBuilder().loadTrustMaterial(null, acceptingTrustStrategy).build();
|
||||
|
||||
} catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public final void givenIgnoringCertificates_whenHttpsUrlIsConsumed_thenCorrect() throws Exception {
|
||||
SSLContext sslContext = new SSLContextBuilder()
|
||||
.loadTrustMaterial(null, (certificate, authType) -> true).build();
|
||||
|
||||
final CloseableHttpClient client = HttpClients.custom().setSSLContext(sslContext).setSSLHostnameVerifier(new NoopHostnameVerifier()).build();
|
||||
final HttpGet httpGet = new HttpGet(HOST_WITH_SSL);
|
||||
|
|
|
@ -54,6 +54,11 @@
|
|||
<artifactId>batik-transcoder</artifactId>
|
||||
<version>1.8</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>3.15</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
2
pom.xml
2
pom.xml
|
@ -95,6 +95,7 @@
|
|||
<module>spring-data-neo4j</module>
|
||||
<module>spring-data-redis</module>
|
||||
<module>spring-data-rest</module>
|
||||
<module>spring-data-solr</module>
|
||||
<module>spring-dispatcher-servlet</module>
|
||||
<module>spring-exceptions</module>
|
||||
<module>spring-freemarker</module>
|
||||
|
@ -132,6 +133,7 @@
|
|||
<module>spring-security-rest-full</module>
|
||||
<module>spring-security-rest</module>
|
||||
<module>spring-security-x509</module>
|
||||
<module>spring-session</module>
|
||||
<module>spring-spel</module>
|
||||
<module>spring-thymeleaf</module>
|
||||
<module>spring-userservice</module>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.camel.file;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.camel.Exchange;
|
||||
import org.apache.camel.Processor;
|
||||
|
||||
public class FileProcessor implements Processor {
|
||||
|
||||
public void process(Exchange exchange) throws Exception {
|
||||
String originalFileName = (String) exchange.getIn().getHeader(Exchange.FILE_NAME, String.class);
|
||||
|
||||
Date date = new Date();
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
|
||||
String changedFileName = dateFormat.format(date) + originalFileName;
|
||||
exchange.getIn().setHeader(Exchange.FILE_NAME, changedFileName);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.baeldung.camel.file;
|
||||
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
|
||||
public class FileRouter extends RouteBuilder {
|
||||
|
||||
private static final String SOURCE_FOLDER = "src/test/source-folder";
|
||||
private static final String DESTINATION_FOLDER = "src/test/destination-folder";
|
||||
|
||||
@Override
|
||||
public void configure() throws Exception {
|
||||
from("file://" + SOURCE_FOLDER + "?delete=true").process(new FileProcessor()).to("file://" + DESTINATION_FOLDER);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<bean id="fileRouter" class="com.baeldung.camel.file.FileRouter" />
|
||||
<bean id="fileProcessor" class="com.baeldung.camel.file.FileProcessor" />
|
||||
|
||||
<camelContext xmlns="http://camel.apache.org/schema/spring">
|
||||
<routeBuilder ref="fileRouter" />
|
||||
</camelContext>
|
||||
|
||||
</beans>
|
|
@ -1,39 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
|
||||
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
|
||||
|
||||
<camelContext xmlns="http://camel.apache.org/schema/spring">
|
||||
<camelContext xmlns="http://camel.apache.org/schema/spring">
|
||||
|
||||
<route customId="true" id="route1">
|
||||
<route customId="true" id="route1">
|
||||
|
||||
<!-- Read files from input directory -->
|
||||
<from uri="file://src/test/data/input"/>
|
||||
<!-- Read files from input directory -->
|
||||
<from uri="file://src/test/data/input" />
|
||||
|
||||
<!-- Transform content to UpperCase -->
|
||||
<process ref="myFileProcessor"/>
|
||||
<!-- Transform content to UpperCase -->
|
||||
<process ref="myFileProcessor" />
|
||||
|
||||
<!-- Write converted file content -->
|
||||
<to uri="file://src/test/data/outputUpperCase"/>
|
||||
<!-- Write converted file content -->
|
||||
<to uri="file://src/test/data/outputUpperCase" />
|
||||
|
||||
<!-- Transform content to LowerCase -->
|
||||
<transform>
|
||||
<simple>${body.toLowerCase()}</simple>
|
||||
</transform>
|
||||
<!-- Transform content to LowerCase -->
|
||||
<transform>
|
||||
<simple>${body.toLowerCase()}</simple>
|
||||
</transform>
|
||||
|
||||
<!-- Write converted file content -->
|
||||
<to uri="file://src/test/data/outputLowerCase"/>
|
||||
<!-- Write converted file content -->
|
||||
<to uri="file://src/test/data/outputLowerCase" />
|
||||
|
||||
<!-- Display process completion message on console -->
|
||||
<transform>
|
||||
<simple>.......... File content conversion completed ..........</simple>
|
||||
</transform>
|
||||
<to uri="stream:out"/>
|
||||
<!-- Display process completion message on console -->
|
||||
<transform>
|
||||
<simple>.......... File content conversion completed ..........</simple>
|
||||
</transform>
|
||||
<to uri="stream:out" />
|
||||
|
||||
</route>
|
||||
</route>
|
||||
|
||||
</camelContext>
|
||||
</camelContext>
|
||||
|
||||
<bean id="myFileProcessor" class="com.baeldung.camel.processor.FileProcessor"/>
|
||||
<bean id="myFileProcessor" class="com.baeldung.camel.processor.FileProcessor" />
|
||||
</beans>
|
|
@ -0,0 +1,68 @@
|
|||
package org.apache.camel.file.processor;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.apache.camel.CamelContext;
|
||||
import org.apache.camel.builder.RouteBuilder;
|
||||
import org.apache.camel.impl.DefaultCamelContext;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
import com.baeldung.camel.file.FileProcessor;
|
||||
|
||||
|
||||
public class FileProcessorTest {
|
||||
|
||||
private static final long DURATION_MILIS = 10000;
|
||||
private static final String SOURCE_FOLDER = "src/test/source-folder";
|
||||
private static final String DESTINATION_FOLDER = "src/test/destination-folder";
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
File sourceFolder = new File(SOURCE_FOLDER);
|
||||
File destinationFolder = new File(DESTINATION_FOLDER);
|
||||
|
||||
cleanFolder(sourceFolder);
|
||||
cleanFolder(destinationFolder);
|
||||
|
||||
sourceFolder.mkdirs();
|
||||
File file1 = new File(SOURCE_FOLDER + "/File1.txt");
|
||||
File file2 = new File(SOURCE_FOLDER + "/File2.txt");
|
||||
file1.createNewFile();
|
||||
file2.createNewFile();
|
||||
}
|
||||
|
||||
private void cleanFolder(File folder) {
|
||||
File[] files = folder.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (file.isFile()) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moveFolderContentJavaDSLTest() throws Exception {
|
||||
final CamelContext camelContext = new DefaultCamelContext();
|
||||
camelContext.addRoutes(new RouteBuilder() {
|
||||
@Override
|
||||
public void configure() throws Exception {
|
||||
from("file://" + SOURCE_FOLDER + "?delete=true").process(new FileProcessor()).to("file://" + DESTINATION_FOLDER);
|
||||
}
|
||||
});
|
||||
camelContext.start();
|
||||
Thread.sleep(DURATION_MILIS);
|
||||
camelContext.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moveFolderContentSpringDSLTest() throws InterruptedException {
|
||||
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("camel-context-test.xml");
|
||||
Thread.sleep(DURATION_MILIS);
|
||||
applicationContext.close();
|
||||
|
||||
}
|
||||
}
|
|
@ -14,5 +14,6 @@
|
|||
|
||||
- [Intro to Spring Cloud Netflix - Hystrix](http://www.baeldung.com/spring-cloud-netflix-hystrix)
|
||||
- [Dockerizing a Spring Boot Application](http://www.baeldung.com/dockerizing-spring-boot-application)
|
||||
- [Introduction to Spring Cloud Rest Client with Netflix Ribbon](http://www.baeldung.com/spring-cloud-rest-client-with-netflix-ribbon)
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<module>spring-cloud-eureka</module>
|
||||
<module>spring-cloud-hystrix</module>
|
||||
<module>spring-cloud-bootstrap</module>
|
||||
<module>spring-cloud-ribbon-client</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
<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>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-cloud-ribbon</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>spring-cloud-ribbon-client</name>
|
||||
<description>Introduction to Spring Cloud Rest Client with Netflix Ribbon</description>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.1.RELEASE</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-ribbon</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-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>Camden.SR1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
</project>
|
|
@ -0,0 +1,28 @@
|
|||
package com.baeldung.spring.cloud.ribbon.client;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.IPing;
|
||||
import com.netflix.loadbalancer.IRule;
|
||||
import com.netflix.loadbalancer.PingUrl;
|
||||
import com.netflix.loadbalancer.WeightedResponseTimeRule;
|
||||
import com.netflix.loadbalancer.AvailabilityFilteringRule;
|
||||
|
||||
public class RibbonConfiguration {
|
||||
|
||||
@Autowired
|
||||
IClientConfig ribbonClientConfig;
|
||||
|
||||
@Bean
|
||||
public IPing ribbonPing(IClientConfig config) {
|
||||
return new PingUrl();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public IRule ribbonRule(IClientConfig config) {
|
||||
return new WeightedResponseTimeRule();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package com.baeldung.spring.cloud.ribbon.client;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SpringBootApplication
|
||||
@RestController
|
||||
@RibbonClient(name = "ping-a-server", configuration = RibbonConfiguration.class)
|
||||
public class ServerLocationApp {
|
||||
|
||||
@LoadBalanced
|
||||
@Bean
|
||||
RestTemplate getRestTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@Autowired
|
||||
RestTemplate restTemplate;
|
||||
|
||||
@RequestMapping("/server-location")
|
||||
public String serverLocation() {
|
||||
String servLoc = this.restTemplate.getForObject("http://ping-server/locaus", String.class);
|
||||
return servLoc;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(ServerLocationApp.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
spring:
|
||||
application:
|
||||
name: spring-cloud-ribbon
|
||||
|
||||
server:
|
||||
port: 8888
|
||||
|
||||
ping-server:
|
||||
ribbon:
|
||||
eureka:
|
||||
enabled: false
|
||||
listOfServers: localhost:9092,localhost:9999
|
||||
ServerListRefreshInterval: 15000
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.spring.cloud.ribbon.client;
|
||||
|
||||
import static org.assertj.core.api.BDDAssertions.then;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.context.embedded.LocalServerPort;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.web.client.TestRestTemplate;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = ServerLocationApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
public class ServerLocationAppTests {
|
||||
ConfigurableApplicationContext application2;
|
||||
ConfigurableApplicationContext application3;
|
||||
|
||||
@Before
|
||||
public void startApps() {
|
||||
this.application2 = startApp(9092);
|
||||
this.application3 = startApp(9999);
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeApps() {
|
||||
this.application2.close();
|
||||
this.application3.close();
|
||||
}
|
||||
|
||||
@LocalServerPort
|
||||
private int port;
|
||||
|
||||
@Autowired
|
||||
private TestRestTemplate testRestTemplate;
|
||||
|
||||
@Test
|
||||
public void loadBalancingServersTest() throws InterruptedException {
|
||||
ResponseEntity<String> response = this.testRestTemplate.getForEntity("http://localhost:" + this.port + "/server-location", String.class);
|
||||
assertEquals(response.getBody(), "Australia");
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext startApp(int port) {
|
||||
return SpringApplication.run(TestConfig.class, "--server.port=" + port, "--spring.jmx.enabled=false");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.spring.cloud.ribbon.client;
|
||||
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Configuration
|
||||
@EnableAutoConfiguration
|
||||
@RestController
|
||||
public class TestConfig {
|
||||
|
||||
@RequestMapping(value = "/locaus")
|
||||
public String locationAUSDetails() {
|
||||
return "Australia";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<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>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-data-solr</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>spring-data-solr</name>
|
||||
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<spring.version>4.2.5.RELEASE</spring.version>
|
||||
<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version>
|
||||
<spring-data-solr>2.0.4.RELEASE</spring-data-solr>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-solr</artifactId>
|
||||
<version>${spring-data-solr}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-context</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
<version>1.2.16</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,25 @@
|
|||
package com.baeldung.spring.data.solr.config;
|
||||
|
||||
import org.apache.solr.client.solrj.SolrClient;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.solr.core.SolrTemplate;
|
||||
import org.springframework.data.solr.repository.config.EnableSolrRepositories;
|
||||
|
||||
@Configuration
|
||||
@EnableSolrRepositories(basePackages = "com.baeldung.spring.data.solr.repository", namedQueriesLocation = "classpath:solr-named-queries.properties", multicoreSupport = true)
|
||||
@ComponentScan
|
||||
public class SolrConfig {
|
||||
|
||||
@Bean
|
||||
public SolrClient solrClient() {
|
||||
return new HttpSolrClient("http://localhost:8983/solr");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SolrTemplate solrTemplate(SolrClient client) throws Exception {
|
||||
return new SolrTemplate(client);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package com.baeldung.spring.data.solr.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.solr.core.mapping.Indexed;
|
||||
import org.springframework.data.solr.core.mapping.SolrDocument;
|
||||
|
||||
@SolrDocument(solrCoreName = "product")
|
||||
public class Product {
|
||||
|
||||
@Id
|
||||
@Indexed(name = "id", type = "string")
|
||||
private String id;
|
||||
|
||||
@Indexed(name = "name", type = "string")
|
||||
private String name;
|
||||
|
||||
@Indexed(name = "category", type = "string")
|
||||
private String category;
|
||||
|
||||
@Indexed(name = "description", type = "string")
|
||||
private String description;
|
||||
|
||||
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 getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package com.baeldung.spring.data.solr.repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.solr.repository.Query;
|
||||
import org.springframework.data.solr.repository.SolrCrudRepository;
|
||||
|
||||
import com.baeldung.spring.data.solr.model.Product;
|
||||
|
||||
public interface ProductRepository extends SolrCrudRepository<Product, String> {
|
||||
|
||||
public List<Product> findByName(String name);
|
||||
|
||||
@Query("name:*?0* OR category:*?0* OR description:*?0*")
|
||||
public Page<Product> findByCustomQuery(String searchTerm, Pageable pageable);
|
||||
|
||||
@Query(name = "Product.findByNamedQuery")
|
||||
public Page<Product> findByNamedQuery(String searchTerm, Pageable pageable);
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Product.findByNamedQuery=name:*?0* OR category:*?0* OR description:*?0*
|
|
@ -0,0 +1,144 @@
|
|||
package com.baeldung.spring.data.solr.repo;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.spring.data.solr.config.SolrConfig;
|
||||
import com.baeldung.spring.data.solr.model.Product;
|
||||
import com.baeldung.spring.data.solr.repository.ProductRepository;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = SolrConfig.class)
|
||||
public class ProductRepositoryIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private ProductRepository productRepository;
|
||||
|
||||
@Before
|
||||
public void clearSolrData() {
|
||||
productRepository.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSavingProduct_thenAvailableOnRetrieval() throws Exception {
|
||||
final Product product = new Product();
|
||||
product.setId("P000089998");
|
||||
product.setName("Desk");
|
||||
product.setCategory("Furniture");
|
||||
product.setDescription("New Desk");
|
||||
productRepository.save(product);
|
||||
final Product retrievedProduct = productRepository.findOne(product.getId());
|
||||
assertEquals(product.getId(), retrievedProduct.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenUpdatingProduct_thenChangeAvailableOnRetrieval() throws Exception {
|
||||
final Product product = new Product();
|
||||
product.setId("P0001");
|
||||
product.setName("T-Shirt");
|
||||
product.setCategory("Kitchen");
|
||||
product.setDescription("New T-Shirt");
|
||||
productRepository.save(product);
|
||||
|
||||
product.setCategory("Clothes");
|
||||
productRepository.save(product);
|
||||
|
||||
final Product retrievedProduct = productRepository.findOne(product.getId());
|
||||
assertEquals(product.getCategory(), retrievedProduct.getCategory());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenDeletingProduct_thenNotAvailableOnRetrieval() throws Exception {
|
||||
final Product product = new Product();
|
||||
product.setId("P0001");
|
||||
product.setName("Desk");
|
||||
product.setCategory("Furniture");
|
||||
product.setDescription("New Desk");
|
||||
productRepository.save(product);
|
||||
|
||||
productRepository.delete(product);
|
||||
|
||||
Product retrievedProduct = productRepository.findOne(product.getId());
|
||||
assertNull(retrievedProduct);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindByName_thenAvailableOnRetrieval() throws Exception {
|
||||
Product phone = new Product();
|
||||
phone.setId("P0001");
|
||||
phone.setName("Phone");
|
||||
phone.setCategory("Electronics");
|
||||
phone.setDescription("New Phone");
|
||||
productRepository.save(phone);
|
||||
|
||||
List<Product> retrievedProducts = productRepository.findByName("Phone");
|
||||
assertEquals(phone.getId(), retrievedProducts.get(0).getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSearchingProductsByQuery_thenAllMatchingProductsShouldAvialble() throws Exception {
|
||||
final Product phone = new Product();
|
||||
phone.setId("P0001");
|
||||
phone.setName("Smart Phone");
|
||||
phone.setCategory("Electronics");
|
||||
phone.setDescription("New Item");
|
||||
productRepository.save(phone);
|
||||
|
||||
final Product phoneCover = new Product();
|
||||
phoneCover.setId("P0002");
|
||||
phoneCover.setName("Cover");
|
||||
phoneCover.setCategory("Phone");
|
||||
phoneCover.setDescription("New Product");
|
||||
productRepository.save(phoneCover);
|
||||
|
||||
final Product wirelessCharger = new Product();
|
||||
wirelessCharger.setId("P0003");
|
||||
wirelessCharger.setName("Charging Cable");
|
||||
wirelessCharger.setCategory("Cable");
|
||||
wirelessCharger.setDescription("Wireless Charger for Phone");
|
||||
productRepository.save(wirelessCharger);
|
||||
|
||||
Page<Product> result = productRepository.findByCustomQuery("Phone", new PageRequest(0, 10));
|
||||
assertEquals(3, result.getNumberOfElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSearchingProductsByNamedQuery_thenAllMatchingProductsShouldAvialble() throws Exception {
|
||||
final Product phone = new Product();
|
||||
phone.setId("P0001");
|
||||
phone.setName("Smart Phone");
|
||||
phone.setCategory("Electronics");
|
||||
phone.setDescription("New Item");
|
||||
productRepository.save(phone);
|
||||
|
||||
final Product phoneCover = new Product();
|
||||
phoneCover.setId("P0002");
|
||||
phoneCover.setName("Cover");
|
||||
phoneCover.setCategory("Phone");
|
||||
phoneCover.setDescription("New Product");
|
||||
productRepository.save(phoneCover);
|
||||
|
||||
final Product wirelessCharger = new Product();
|
||||
wirelessCharger.setId("P0003");
|
||||
wirelessCharger.setName("Charging Cable");
|
||||
wirelessCharger.setCategory("Cable");
|
||||
wirelessCharger.setDescription("Wireless Charger for Phone");
|
||||
productRepository.save(wirelessCharger);
|
||||
|
||||
Page<Product> result = productRepository.findByNamedQuery("one", new PageRequest(0, 10));
|
||||
assertEquals(3, result.getNumberOfElements());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
## Info ##
|
||||
|
||||
- The diagram is created with [yed](http://www.yworks.com/products/yed)
|
|
@ -0,0 +1,372 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd">
|
||||
<!--Created by yEd 3.16.2.1-->
|
||||
<key attr.name="Beschreibung" attr.type="string" for="graph" id="d0"/>
|
||||
<key for="port" id="d1" yfiles.type="portgraphics"/>
|
||||
<key for="port" id="d2" yfiles.type="portgeometry"/>
|
||||
<key for="port" id="d3" yfiles.type="portuserdata"/>
|
||||
<key attr.name="url" attr.type="string" for="node" id="d4"/>
|
||||
<key attr.name="description" attr.type="string" for="node" id="d5"/>
|
||||
<key for="node" id="d6" yfiles.type="nodegraphics"/>
|
||||
<key for="graphml" id="d7" yfiles.type="resources"/>
|
||||
<key attr.name="url" attr.type="string" for="edge" id="d8"/>
|
||||
<key attr.name="description" attr.type="string" for="edge" id="d9"/>
|
||||
<key for="edge" id="d10" yfiles.type="edgegraphics"/>
|
||||
<graph edgedefault="directed" id="G">
|
||||
<data key="d0"/>
|
||||
<node id="n0" yfiles.foldertype="group">
|
||||
<data key="d4"/>
|
||||
<data key="d6">
|
||||
<y:ProxyAutoBoundsNode>
|
||||
<y:Realizers active="0">
|
||||
<y:GroupNode>
|
||||
<y:Geometry height="600.0" width="1200.0" x="-187.59999999999997" y="60.18125000000006"/>
|
||||
<y:Fill color="#FAFAFA" color2="#FAFAFA" transparent="false"/>
|
||||
<y:BorderStyle color="#795548" type="dashed" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" backgroundColor="#FAFAFA" borderDistance="0.0" fontFamily="Roboto Mono" fontSize="20" fontStyle="plain" height="27.4375" horizontalTextPosition="center" iconTextGap="4" lineColor="#00695C" modelName="internal" modelPosition="t" textColor="#212121" verticalTextPosition="bottom" visible="true" width="340.0546875" x="429.97265625" y="0.0">Servlet Engine (e.g. Tomcat)</y:NodeLabel>
|
||||
<y:Shape type="roundrectangle"/>
|
||||
<y:State closed="false" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
|
||||
<y:Insets bottom="15" bottomF="15.0" left="15" leftF="15.0" right="15" rightF="15.0" top="15" topF="15.0"/>
|
||||
<y:BorderInsets bottom="46" bottomF="45.78125" left="23" leftF="23.30000000000001" right="44" rightF="43.80000000000018" top="90" topF="89.98124999999999"/>
|
||||
</y:GroupNode>
|
||||
<y:GroupNode>
|
||||
<y:Geometry height="50.0" width="50.0" x="473.0" y="280.0"/>
|
||||
<y:Fill color="#F5F5F5" transparent="false"/>
|
||||
<y:BorderStyle color="#000000" type="dashed" width="1.0"/>
|
||||
<y:NodeLabel alignment="right" autoSizePolicy="node_width" backgroundColor="#EBEBEB" borderDistance="0.0" fontFamily="Dialog" fontSize="15" fontStyle="plain" hasLineColor="false" height="21.4609375" horizontalTextPosition="center" iconTextGap="4" modelName="internal" modelPosition="t" textColor="#000000" verticalTextPosition="bottom" visible="true" width="65.201171875" x="-7.6005859375" y="0.0">Folder 1</y:NodeLabel>
|
||||
<y:Shape type="roundrectangle"/>
|
||||
<y:State closed="true" closedHeight="50.0" closedWidth="50.0" innerGraphDisplayEnabled="false"/>
|
||||
<y:Insets bottom="5" bottomF="5.0" left="5" leftF="5.0" right="5" rightF="5.0" top="5" topF="5.0"/>
|
||||
<y:BorderInsets bottom="0" bottomF="0.0" left="0" leftF="0.0" right="0" rightF="0.0" top="0" topF="0.0"/>
|
||||
</y:GroupNode>
|
||||
</y:Realizers>
|
||||
</y:ProxyAutoBoundsNode>
|
||||
</data>
|
||||
<graph edgedefault="directed" id="n0:">
|
||||
<node id="n0::n0">
|
||||
<data key="d6">
|
||||
<y:GenericNode configuration="com.yworks.flowchart.onPageReference">
|
||||
<y:Geometry height="180.0" width="270.0" x="683.5999999999999" y="192.60000000000005"/>
|
||||
<y:Fill color="#212121" color2="#616161" transparent="false"/>
|
||||
<y:BorderStyle color="#FAFAFA" type="line" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Roboto Mono" fontSize="21" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.609375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#FAFAFA" verticalTextPosition="bottom" visible="true" width="130.0205078125" x="69.98974609375" y="75.69531249999997">Controller<y:LabelModel>
|
||||
<y:SmartNodeLabelModel distance="4.0"/>
|
||||
</y:LabelModel>
|
||||
<y:ModelParameter>
|
||||
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
|
||||
</y:ModelParameter>
|
||||
</y:NodeLabel>
|
||||
<y:StyleProperties>
|
||||
<y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/>
|
||||
</y:StyleProperties>
|
||||
</y:GenericNode>
|
||||
</data>
|
||||
</node>
|
||||
<node id="n0::n1">
|
||||
<data key="d6">
|
||||
<y:GenericNode configuration="BevelNode2">
|
||||
<y:Geometry height="34.0" width="69.0" x="464.29999999999995" y="274.6000000000002"/>
|
||||
<y:Fill color="#FFC107" transparent="false"/>
|
||||
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" borderDistance="8.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#212121" verticalTextPosition="bottom" visible="true" width="58.0087890625" x="5.49560546875" y="4.453125">Model<y:LabelModel>
|
||||
<y:SmartNodeLabelModel distance="8.0"/>
|
||||
</y:LabelModel>
|
||||
<y:ModelParameter>
|
||||
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
|
||||
</y:ModelParameter>
|
||||
</y:NodeLabel>
|
||||
<y:StyleProperties>
|
||||
<y:Property class="java.lang.Boolean" name="ModernNodeShadow" value="true"/>
|
||||
</y:StyleProperties>
|
||||
</y:GenericNode>
|
||||
</data>
|
||||
</node>
|
||||
<node id="n0::n2">
|
||||
<data key="d6">
|
||||
<y:SVGNode>
|
||||
<y:Geometry height="66.76200103759766" width="56.554100036621094" x="-149.29999999999995" y="249.21899948120125"/>
|
||||
<y:Fill color="#CCCCFF" transparent="false"/>
|
||||
<y:BorderStyle color="#000000" type="line" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#000000" verticalTextPosition="bottom" visible="true" width="4.0" x="26.277050018310547" y="70.76200103759766">
|
||||
<y:LabelModel>
|
||||
<y:SmartNodeLabelModel distance="4.0"/>
|
||||
</y:LabelModel>
|
||||
<y:ModelParameter>
|
||||
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="-0.5" nodeRatioX="0.0" nodeRatioY="0.5" offsetX="0.0" offsetY="4.0" upX="0.0" upY="-1.0"/>
|
||||
</y:ModelParameter>
|
||||
</y:NodeLabel>
|
||||
<y:SVGNodeProperties usingVisualBounds="true"/>
|
||||
<y:SVGModel svgBoundsPolicy="0">
|
||||
<y:SVGContent refid="1"/>
|
||||
</y:SVGModel>
|
||||
</y:SVGNode>
|
||||
</data>
|
||||
</node>
|
||||
<node id="n0::n3">
|
||||
<data key="d6">
|
||||
<y:GenericNode configuration="BevelNode2">
|
||||
<y:Geometry height="34.0" width="69.0" x="226.89999999999975" y="389.60000000000014"/>
|
||||
<y:Fill color="#FFC107" transparent="false"/>
|
||||
<y:BorderStyle hasColor="false" type="line" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" borderDistance="8.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#212121" verticalTextPosition="bottom" visible="true" width="58.0087890625" x="5.49560546875" y="4.453125">Model<y:LabelModel>
|
||||
<y:SmartNodeLabelModel distance="8.0"/>
|
||||
</y:LabelModel>
|
||||
<y:ModelParameter>
|
||||
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
|
||||
</y:ModelParameter>
|
||||
</y:NodeLabel>
|
||||
<y:StyleProperties>
|
||||
<y:Property class="java.lang.Boolean" name="ModernNodeShadow" value="true"/>
|
||||
</y:StyleProperties>
|
||||
</y:GenericNode>
|
||||
</data>
|
||||
</node>
|
||||
<node id="n0::n4">
|
||||
<data key="d4"/>
|
||||
<data key="d6">
|
||||
<y:GenericNode configuration="com.yworks.flowchart.terminator">
|
||||
<y:Geometry height="130.0" width="230.0" x="60.0" y="217.60000000000005"/>
|
||||
<y:Fill color="#212121" color2="#616161" transparent="false"/>
|
||||
<y:BorderStyle color="#FAFAFA" type="line" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Roboto Mono" fontSize="21" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.609375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#FAFAFA" verticalTextPosition="bottom" visible="true" width="218.23486328125" x="5.882568359375" y="50.69531249999997">DispatcherServlet<y:LabelModel>
|
||||
<y:SmartNodeLabelModel distance="4.0"/>
|
||||
</y:LabelModel>
|
||||
<y:ModelParameter>
|
||||
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
|
||||
</y:ModelParameter>
|
||||
</y:NodeLabel>
|
||||
<y:StyleProperties>
|
||||
<y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="false"/>
|
||||
</y:StyleProperties>
|
||||
</y:GenericNode>
|
||||
</data>
|
||||
</node>
|
||||
<node id="n0::n5">
|
||||
<data key="d6">
|
||||
<y:GenericNode configuration="com.yworks.flowchart.document">
|
||||
<y:Geometry height="120.0" width="230.0" x="60.0" y="479.4000000000001"/>
|
||||
<y:Fill color="#212121" color2="#616161" transparent="false"/>
|
||||
<y:BorderStyle color="#FAFAFA" type="line" width="1.0"/>
|
||||
<y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Roboto Mono" fontSize="21" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="28.609375" horizontalTextPosition="center" iconTextGap="4" modelName="custom" textColor="#FAFAFA" verticalTextPosition="bottom" visible="true" width="167.82666015625" x="31.086669921875" y="45.6953125">View Template<y:LabelModel>
|
||||
<y:SmartNodeLabelModel distance="4.0"/>
|
||||
</y:LabelModel>
|
||||
<y:ModelParameter>
|
||||
<y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/>
|
||||
</y:ModelParameter>
|
||||
</y:NodeLabel>
|
||||
<y:StyleProperties>
|
||||
<y:Property class="java.lang.Boolean" name="y.view.ShadowNodePainter.SHADOW_PAINTING" value="true"/>
|
||||
</y:StyleProperties>
|
||||
</y:GenericNode>
|
||||
</data>
|
||||
</node>
|
||||
</graph>
|
||||
</node>
|
||||
<edge id="e0" source="n0::n4" target="n0">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/>
|
||||
<y:LineStyle color="#000000" type="line" width="1.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e0" source="n0::n5" target="n0::n4">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="-38.30000000000018" sy="-18.399999999999864" tx="-37.30000000000018" ty="3.6000000000001364"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#212121" verticalTextPosition="bottom" visible="true" width="155.224609375" x="-179.1814364795589" y="-35.230035400390534">Return Control<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e1" source="n0::n4" target="n0::n5">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="48.69999999999982" sy="-5.399999999999864" tx="48.69999999999982" ty="-12.399999999999864"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="1.0" textColor="#212121" verticalTextPosition="bottom" visible="true" width="166.0263671875" x="24.00000305175763" y="96.57254638671884">Render Response<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e2" source="n0::n4" target="n0::n0">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="7.699999999999818" sy="-36.399999999999864" tx="3.699999999999818" ty="-36.399999999999864"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.5" textColor="#212121" verticalTextPosition="bottom" visible="true" width="176.828125" x="119.53513793945308" y="-49.093746948242">Delegate Request<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e3" source="n0::n0" target="n0::n4">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="4.699999999999818" sy="29.600000000000136" tx="55.69999999999982" ty="29.600000000000136"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#212121" verticalTextPosition="bottom" visible="true" width="328.0615234375" x="-388.2225097656251" y="23.99998779296891">Delegate Rendering of Response<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="e1" source="n0" target="n0::n4">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="-409.1" sy="-128.18124999999975" tx="-6.5" ty="-35.39999999999975"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="20.0" fontFamily="Roboto Mono" fontSize="14" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" hasText="false" height="4.0" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#FAFAFA" verticalTextPosition="bottom" visible="true" width="4.0" x="-190.89999995231625" y="-171.81874999999994">
|
||||
<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e4" source="n0::n2" target="n0::n4">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="7.622949981689459" sy="-29.69998781681062" tx="-4.399999999999977" ty="-29.69998781681062"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#212121" verticalTextPosition="bottom" visible="true" width="176.828125" x="4.834180450439476" y="-49.093746972084006">Incoming Request<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e5" source="n0::n4" target="n0::n2">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="-16.399999999999977" sy="27.16233534321384" tx="28.290377113176618" ty="27.16233534321384"/>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="none" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.0" textColor="#212121" verticalTextPosition="bottom" visible="true" width="166.0263671875" x="-165.36247482299802" y="24.00000624165142">Return Response<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e6" source="n0::n0" target="n0::n0">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||
<y:Point x="912.5999999999999" y="125.60000000000002"/>
|
||||
</y:Path>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="standard" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.25" textColor="#212121" verticalTextPosition="bottom" visible="true" width="155.224609375" x="-200.05571079132665" y="-142.76877441406248">Handle Request<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
<edge id="n0::e7" source="n0::n0" target="n0::n0">
|
||||
<data key="d10">
|
||||
<y:PolyLineEdge>
|
||||
<y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0">
|
||||
<y:Point x="862.5999999999999" y="459.2000000000001"/>
|
||||
</y:Path>
|
||||
<y:LineStyle color="#212121" type="line" width="4.0"/>
|
||||
<y:Arrows source="standard" target="standard"/>
|
||||
<y:EdgeLabel alignment="center" configuration="AutoFlippingLabel" distance="24.0" fontFamily="Roboto Mono" fontSize="18" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="25.09375" horizontalTextPosition="center" iconTextGap="4" modelName="side_slider" preferredPlacement="anywhere" ratio="0.25" textColor="#212121" verticalTextPosition="bottom" visible="true" width="133.62109375" x="-61.31919657274125" y="63.13254394531259">Create Model<y:PreferredPlacementDescriptor angle="0.0" angleOffsetOnRightSide="0" angleReference="absolute" angleRotationOnRightSide="co" distance="-1.0" frozen="true" placement="anywhere" side="anywhere" sideReference="relative_to_edge_flow"/>
|
||||
</y:EdgeLabel>
|
||||
<y:BendStyle smoothed="false"/>
|
||||
</y:PolyLineEdge>
|
||||
</data>
|
||||
</edge>
|
||||
</graph>
|
||||
<data key="d7">
|
||||
<y:Resources>
|
||||
<y:Resource id="1"><?xml version="1.0" encoding="utf-8"?>
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="57px" height="67px" viewBox="0 0 57 67" enable-background="new 0 0 57 67" xml:space="preserve">
|
||||
<g>
|
||||
|
||||
<radialGradient id="neck_x5F_white_1_" cx="28.0298" cy="-751.9429" r="11.4464" fx="25.7969" fy="-753.1596" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#B38E5D"/>
|
||||
<stop offset="1" style="stop-color:#805126"/>
|
||||
</radialGradient>
|
||||
<path id="neck_x5F_white_2_" fill="url(#neck_x5F_white_1_)" stroke="#5B453B" stroke-miterlimit="10" d="M19.278,37.799h18.188
|
||||
v13.23c-1.313,0.371-17.173,0.436-18.188,0.172V37.799z"/>
|
||||
|
||||
<radialGradient id="SVGID_1_" cx="27.481" cy="-760.3003" r="31.0533" fx="21.4231" fy="-763.6011" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#B38E5D"/>
|
||||
<stop offset="1" style="stop-color:#805126"/>
|
||||
</radialGradient>
|
||||
<path fill="url(#SVGID_1_)" stroke="#5B453B" stroke-miterlimit="10" d="M49.529,51.225c-4.396-4.396-10.951-5.884-12.063-6.109
|
||||
V37.8H19.278c0,0,0.038,6.903,0,6.868c0,0-6.874,0.997-12.308,6.432C1.378,56.691,0.5,62.77,0.5,62.77
|
||||
c0,1.938,1.575,3.492,3.523,3.492h48.51c1.947,0,3.521-1.558,3.521-3.492C56.055,62.768,54.211,55.906,49.529,51.225z"/>
|
||||
|
||||
<radialGradient id="face_x5F_white_1_" cx="27.7827" cy="-732.2632" r="23.424" fx="23.2131" fy="-734.753" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#B38E5D"/>
|
||||
<stop offset="1" style="stop-color:#805126"/>
|
||||
</radialGradient>
|
||||
<path id="face_x5F_white_2_" fill="url(#face_x5F_white_1_)" stroke="#5B453B" stroke-miterlimit="10" d="M43.676,23.357
|
||||
c0.086,10.199-6.738,18.52-15.246,18.586c-8.503,0.068-15.467-8.146-15.553-18.344C12.794,13.4,19.618,5.079,28.123,5.012
|
||||
C36.627,4.945,43.59,13.158,43.676,23.357z"/>
|
||||
|
||||
<linearGradient id="face_highlight_1_" gradientUnits="userSpaceOnUse" x1="2941.4297" y1="5674.7988" x2="2965.0596" y2="5768.2505" gradientTransform="matrix(0.275 0 0 0.2733 -783.3976 -1542.678)">
|
||||
<stop offset="0" style="stop-color:#FFFFFF;stop-opacity:0.42"/>
|
||||
<stop offset="1" style="stop-color:#FFFFFF;stop-opacity:0.12"/>
|
||||
</linearGradient>
|
||||
<path id="face_highlight_2_" fill="url(#face_highlight_1_)" d="M27.958,6.333c-6.035,0.047-10.747,4.493-12.787,10.386
|
||||
c-0.664,1.919-0.294,4.043,0.98,5.629c2.73,3.398,5.729,6.283,9.461,8.088c3.137,1.518,7.535,2.385,11.893,1.247
|
||||
c2.274-0.592,3.988-2.459,4.375-4.766c0.183-1.094,0.293-2.289,0.283-3.553C42.083,13.952,36.271,6.268,27.958,6.333z"/>
|
||||
<path id="path9833_2_" fill="#4B4B4B" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" d="M28.372,0.5
|
||||
C17.537,0.5,8.269,7.748,9.153,26.125c0.563,6.563,5.862,12.042,9.366,13.531c-2.929-10.968-0.304-25.021-0.585-25.526
|
||||
c-0.281-0.505,3.536,6.728,3.536,6.728l3.183-8.312c5.541,4.28,0.393,11.309,1.049,11.058c4.26-1.631,5.34-9.228,5.34-9.228
|
||||
s2.729,3.657,2.701,5.504c-0.054,3.562,2.194-6.067,2.194-6.067l1.027,2.031c6.727,9.822,3.684,16.208,1.654,22.781
|
||||
c15.665-0.703,12.289-10.48,9.658-18.407C43.59,6.092,39.206,0.5,28.372,0.5z"/>
|
||||
|
||||
<radialGradient id="collar_x5F_body_2_" cx="15.1587" cy="-763.7056" r="32.4004" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#B0E8FF"/>
|
||||
<stop offset="1" style="stop-color:#74AEEE"/>
|
||||
</radialGradient>
|
||||
<path id="collar_x5F_body_1_" fill="url(#collar_x5F_body_2_)" stroke="#5491CF" d="M0.5,62.768c0,1.938,1.575,3.494,3.523,3.494
|
||||
h48.51c1.947,0,3.521-1.559,3.521-3.494c0,0-1.844-6.861-6.525-11.543c-4.815-4.813-11.244-6.146-11.244-6.146
|
||||
c-1.771,1.655-5.61,2.802-10.063,2.802c-4.453,0-8.292-1.146-10.063-2.802c0,0-5.755,0.586-11.189,6.021
|
||||
C1.378,56.689,0.5,62.768,0.5,62.768z"/>
|
||||
|
||||
<radialGradient id="collar_x5F_r_2_" cx="31.5" cy="-753.832" r="9.2834" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#80CCFF"/>
|
||||
<stop offset="1" style="stop-color:#74AEEE"/>
|
||||
</radialGradient>
|
||||
<path id="collar_x5F_r_1_" fill="url(#collar_x5F_r_2_)" stroke="#5491CF" d="M38.159,41.381c0,0-0.574,2.369-3.013,4.441
|
||||
c-2.108,1.795-5.783,2.072-5.783,2.072l3.974,6.217c0,0,2.957-1.637,5.009-3.848c1.922-2.072,1.37-5.479,1.37-5.479L38.159,41.381z
|
||||
"/>
|
||||
|
||||
<radialGradient id="collar_x5F_l_2_" cx="19.1377" cy="-753.873" r="9.2837" gradientTransform="matrix(1 0 0 -1 0.1201 -706.5371)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#80CCFF"/>
|
||||
<stop offset="1" style="stop-color:#74AEEE"/>
|
||||
</radialGradient>
|
||||
<path id="collar_x5F_l_1_" fill="url(#collar_x5F_l_2_)" stroke="#5491CF" d="M18.63,41.422c0,0,0.576,2.369,3.012,4.441
|
||||
c2.109,1.793,5.785,2.072,5.785,2.072l-3.974,6.217c0,0-2.957-1.637-5.007-3.85c-1.922-2.072-1.37-5.48-1.37-5.48L18.63,41.422z"/>
|
||||
|
||||
<radialGradient id="Knob2_2_" cx="27.8872" cy="9.9414" r="0.9669" gradientTransform="matrix(1 0 0 -1 0.04 66.1543)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#80CCFF"/>
|
||||
<stop offset="1" style="stop-color:#74AEEE"/>
|
||||
</radialGradient>
|
||||
<circle id="Knob2_1_" fill="url(#Knob2_2_)" stroke="#5491CF" cx="28.258" cy="56.254" r="0.584"/>
|
||||
|
||||
<radialGradient id="Knob1_2_" cx="27.9253" cy="3.6973" r="0.9669" gradientTransform="matrix(1 0 0 -1 0.04 66.1543)" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#80CCFF"/>
|
||||
<stop offset="1" style="stop-color:#74AEEE"/>
|
||||
</radialGradient>
|
||||
<circle id="Knob1_1_" fill="url(#Knob1_2_)" stroke="#5491CF" cx="28.296" cy="62.499" r="0.584"/>
|
||||
</g>
|
||||
</svg>
|
||||
</y:Resource>
|
||||
</y:Resources>
|
||||
</data>
|
||||
</graphml>
|
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
|
@ -0,0 +1,13 @@
|
|||
## Spring MVC Email
|
||||
|
||||
Example Spring MVC project to send email from web form.
|
||||
|
||||
### Installing and Running
|
||||
|
||||
Just run the Spring Boot application.
|
||||
Type http://localhost:8080 in your browser to open the application.
|
||||
|
||||
|
||||
### Sending test emails
|
||||
|
||||
Follow UI links to send simple email, email using template or email with attachment.
|
|
@ -0,0 +1,55 @@
|
|||
<?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>
|
||||
|
||||
<groupId>org.baeldung.spring</groupId>
|
||||
<artifactId>SpringMVCEmail</artifactId>
|
||||
<version>1.0</version>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.0.RELEASE</version>
|
||||
<relativePath></relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<!-- Spring Boot Starter Mail dependency -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
<version>1.4.0.RELEASE</version>
|
||||
</dependency>
|
||||
<!-- The following two dependencies included to render jsp pages -->
|
||||
<dependency>
|
||||
<groupId>org.apache.tomcat.embed</groupId>
|
||||
<artifactId>tomcat-embed-jasper</artifactId>
|
||||
<version>8.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>jstl</artifactId>
|
||||
<version>1.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,12 @@
|
|||
package com.baeldung.spring;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package com.baeldung.spring.app.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
import org.springframework.web.servlet.view.InternalResourceViewResolver;
|
||||
import org.springframework.web.servlet.view.JstlView;
|
||||
import org.springframework.web.servlet.view.UrlBasedViewResolver;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Olga
|
||||
*/
|
||||
@Configuration
|
||||
@ComponentScan("com.baeldung.spring")
|
||||
@EnableWebMvc //tha same as <mvc:annotation-driven/>
|
||||
public class AppConfig extends WebMvcConfigurerAdapter {
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public UrlBasedViewResolver urlBasedViewResolver() {
|
||||
UrlBasedViewResolver resolver = new UrlBasedViewResolver();
|
||||
resolver.setOrder(0);
|
||||
resolver.setPrefix("/WEB-INF/views/");
|
||||
resolver.setSuffix(".jsp");
|
||||
resolver.setCache(false);
|
||||
resolver.setViewClass(JstlView.class);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public InternalResourceViewResolver internalResourceViewResolver() {
|
||||
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
|
||||
resolver.setOrder(1);
|
||||
resolver.setPrefix("/WEB-INF/views/");
|
||||
resolver.setSuffix(".jsp");
|
||||
resolver.setViewClass(JstlView.class);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SimpleMailMessage templateSimpleMessage() {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setText("This is the test email template for your email:\n%s\n");
|
||||
return message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.baeldung.spring.controllers;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
/**
|
||||
* Created with IntelliJ IDEA.
|
||||
* User: Olga
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping({"/","/home"})
|
||||
public class HomeController {
|
||||
|
||||
@RequestMapping(method = RequestMethod.GET)
|
||||
public String showHomePage() {
|
||||
return "home";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
package com.baeldung.spring.controllers;
|
||||
|
||||
import com.baeldung.spring.mail.EmailServiceImpl;
|
||||
import com.baeldung.spring.web.dto.MailObject;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.validation.Valid;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by Olga on 7/20/2016.
|
||||
*/
|
||||
@Controller
|
||||
@RequestMapping("/mail")
|
||||
public class MailController {
|
||||
@Autowired
|
||||
public EmailServiceImpl emailService;
|
||||
|
||||
@Value("${attachment.invoice}")
|
||||
private String attachmentPath;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("templateSimpleMessage")
|
||||
public SimpleMailMessage template;
|
||||
|
||||
private static final Map<String, Map<String, String>> labels;
|
||||
|
||||
static {
|
||||
labels = new HashMap<>();
|
||||
|
||||
//Simple email
|
||||
Map<String, String> props = new HashMap<>();
|
||||
props.put("headerText", "Send Simple Email");
|
||||
props.put("messageLabel", "Message");
|
||||
props.put("additionalInfo", "");
|
||||
labels.put("send", props);
|
||||
|
||||
//Email with template
|
||||
props = new HashMap<>();
|
||||
props.put("headerText", "Send Email Using Template");
|
||||
props.put("messageLabel", "Template Parameter");
|
||||
props.put("additionalInfo",
|
||||
"The parameter value will be added to the following message template:<br>" +
|
||||
"<b>This is the test email template for your email:<br>'Template Parameter'</b>"
|
||||
);
|
||||
labels.put("sendTemplate", props);
|
||||
|
||||
//Email with attachment
|
||||
props = new HashMap<>();
|
||||
props.put("headerText", "Send Email With Attachment");
|
||||
props.put("messageLabel", "Message");
|
||||
props.put("additionalInfo", "To make sure that you send an attachment with this email, change the value for the 'attachment.invoice' in the application.properties file to the path to the attachment.");
|
||||
labels.put("sendAttachment", props);
|
||||
}
|
||||
|
||||
@RequestMapping(value = {"/send", "/sendTemplate", "/sendAttachment"}, method = RequestMethod.GET)
|
||||
public String createMail(Model model,
|
||||
HttpServletRequest request) {
|
||||
String action = request.getRequestURL().substring(
|
||||
request.getRequestURL().lastIndexOf("/") + 1
|
||||
);
|
||||
Map<String, String> props = labels.get(action);
|
||||
Set<String> keys = props.keySet();
|
||||
Iterator<String> iterator = keys.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
String key = iterator.next();
|
||||
model.addAttribute(key, props.get(key));
|
||||
}
|
||||
|
||||
model.addAttribute("mailObject", new MailObject());
|
||||
return "mail/send";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/send", method = RequestMethod.POST)
|
||||
public String createMail(Model model,
|
||||
@ModelAttribute("mailObject") @Valid MailObject mailObject,
|
||||
Errors errors) {
|
||||
if (errors.hasErrors()) {
|
||||
return "mail/send";
|
||||
}
|
||||
emailService.sendSimpleMessage(mailObject.getTo(),
|
||||
mailObject.getSubject(), mailObject.getText());
|
||||
|
||||
return "redirect:/home";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/sendTemplate", method = RequestMethod.POST)
|
||||
public String createMailWithTemplate(Model model,
|
||||
@ModelAttribute("mailObject") @Valid MailObject mailObject,
|
||||
Errors errors) {
|
||||
if (errors.hasErrors()) {
|
||||
return "mail/send";
|
||||
}
|
||||
emailService.sendSimpleMessageUsingTemplate(mailObject.getTo(),
|
||||
mailObject.getSubject(),
|
||||
template,
|
||||
mailObject.getText());
|
||||
|
||||
return "redirect:/home";
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/sendAttachment", method = RequestMethod.POST)
|
||||
public String createMailWithAttachment(Model model,
|
||||
@ModelAttribute("mailObject") @Valid MailObject mailObject,
|
||||
Errors errors) {
|
||||
if (errors.hasErrors()) {
|
||||
return "mail/send";
|
||||
}
|
||||
emailService.sendMessageWithAttachment(
|
||||
mailObject.getTo(),
|
||||
mailObject.getSubject(),
|
||||
mailObject.getText(),
|
||||
attachmentPath
|
||||
);
|
||||
|
||||
return "redirect:/home";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package com.baeldung.spring.mail;
|
||||
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
|
||||
/**
|
||||
* Created by Olga on 8/22/2016.
|
||||
*/
|
||||
public interface EmailService {
|
||||
void sendSimpleMessage(String to,
|
||||
String subject,
|
||||
String text);
|
||||
void sendSimpleMessageUsingTemplate(String to,
|
||||
String subject,
|
||||
SimpleMailMessage template,
|
||||
String ...templateArgs);
|
||||
void sendMessageWithAttachment(String to,
|
||||
String subject,
|
||||
String text,
|
||||
String pathToAttachment);
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.baeldung.spring.mail;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.mail.MailException;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by Olga on 7/15/2016.
|
||||
*/
|
||||
@Component
|
||||
public class EmailServiceImpl implements EmailService {
|
||||
|
||||
@Autowired
|
||||
public JavaMailSender emailSender;
|
||||
|
||||
public void sendSimpleMessage(String to, String subject, String text) {
|
||||
try {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setTo(to);
|
||||
message.setSubject(subject);
|
||||
message.setText(text);
|
||||
|
||||
emailSender.send(message);
|
||||
} catch (MailException exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendSimpleMessageUsingTemplate(String to,
|
||||
String subject,
|
||||
SimpleMailMessage template,
|
||||
String ...templateArgs) {
|
||||
String text = String.format(template.getText(), templateArgs);
|
||||
sendSimpleMessage(to, subject, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessageWithAttachment(String to,
|
||||
String subject,
|
||||
String text,
|
||||
String pathToAttachment) {
|
||||
try {
|
||||
MimeMessage message = emailSender.createMimeMessage();
|
||||
// pass 'true' to the constructor to create a multipart message
|
||||
MimeMessageHelper helper = new MimeMessageHelper(message, true);
|
||||
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(text);
|
||||
|
||||
FileSystemResource file = new FileSystemResource(new File(pathToAttachment));
|
||||
helper.addAttachment("Invoice", file);
|
||||
|
||||
emailSender.send(message);
|
||||
} catch (MessagingException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package com.baeldung.spring.web.dto;
|
||||
|
||||
import org.hibernate.validator.constraints.Email;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
/**
|
||||
* Created by Olga on 7/20/2016.
|
||||
*/
|
||||
public class MailObject {
|
||||
@Email
|
||||
@NotNull
|
||||
@Size(min = 1, message = "Please, set an email address to send the message to it")
|
||||
private String to;
|
||||
private String subject;
|
||||
private String text;
|
||||
|
||||
public String getTo() {
|
||||
return to;
|
||||
}
|
||||
|
||||
public void setTo(String to) {
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public String getSubject() {
|
||||
return subject;
|
||||
}
|
||||
|
||||
public void setSubject(String subject) {
|
||||
this.subject = subject;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<application xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/application_6.xsd"
|
||||
version="6">
|
||||
|
||||
<module id="SpringMVCEmail">
|
||||
<web>
|
||||
<web-uri>SpringMVCEmail.war</web-uri>
|
||||
<context-root>SpringMVCEmail</context-root>
|
||||
</web>
|
||||
</module>
|
||||
<module id="SpringMVCEmail-Web">
|
||||
<web>
|
||||
<web-uri>web.war</web-uri>
|
||||
<context-root>SpringMVCEmailWeb</context-root>
|
||||
</web>
|
||||
</module>
|
||||
</application>
|
|
@ -0,0 +1,20 @@
|
|||
# Gmail SMTP
|
||||
spring.mail.host=smtp.gmail.com
|
||||
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
|
||||
|
||||
# Amazon SES SMTP
|
||||
#spring.mail.host=email-smtp.us-west-2.amazonaws.com
|
||||
#spring.mail.username=username
|
||||
#spring.mail.password=password
|
||||
#spring.mail.properties.mail.transport.protocol=smtp
|
||||
#spring.mail.properties.mail.smtp.port=25
|
||||
#spring.mail.properties.mail.smtp.auth=true
|
||||
#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
|
|
@ -0,0 +1,43 @@
|
|||
<%--
|
||||
Created by IntelliJ IDEA.
|
||||
User: Olga
|
||||
Date: 1/19/16
|
||||
Time: 3:53 PM
|
||||
To change this template use File | Settings | File Templates.
|
||||
--%>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form" %>
|
||||
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Home Page</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<div>
|
||||
<h4>Select any of the options below to send sample email:</h4>
|
||||
<form method="get" style="width: 200px;">
|
||||
<fieldset style="border: none; padding-left: 0px; padding-top: 0px">
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="submit" formaction="mail/send" value="Send Simple Email">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="submit" formaction="mail/sendTemplate" value="Send Email Using Template">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="submit" formaction="mail/sendAttachment" value="Send Email With Attachment">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,58 @@
|
|||
<%--
|
||||
Created by IntelliJ IDEA.
|
||||
User: Olga
|
||||
Date: 7/20/2016
|
||||
Time: 1:47 PM
|
||||
To change this template use File | Settings | File Templates.
|
||||
--%>
|
||||
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
|
||||
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
|
||||
<html>
|
||||
<head>
|
||||
<title>Send Email</title>
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<h3>${headerText}</h3>
|
||||
<form:form method="POST" modelAttribute="mailObject" >
|
||||
<fieldset>
|
||||
<div style="float:left;">
|
||||
<table cellspacing="0" width="300">
|
||||
<tr>
|
||||
<th><label for="input_to">To</label></th>
|
||||
<td><form:input path="to" id="input_to" type="email"/>
|
||||
<small>Enter email address</small><br/>
|
||||
<form:errors path="to" cssStyle="color:red;font-size:small"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="input_subject">Subject</label></th>
|
||||
<td><form:input path="subject" id="input_subject"/>
|
||||
<small>Enter the subject</small><br/>
|
||||
<form:errors path="subject" cssStyle="color:red;font-size:small"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="input_text">${messageLabel}:</label></th>
|
||||
<td><form:textarea path="text"
|
||||
rows="5" cols="50"
|
||||
id="input_text"/>
|
||||
<form:errors path="text" cssStyle="color:red;font-size:small"/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th></th>
|
||||
<td>
|
||||
<input type="submit" value="Send">
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div style="float:left; word-wrap: break-word; margin-left: 50px; width: 400px; color: grey">
|
||||
${additionalInfo}
|
||||
</div>
|
||||
</fieldset>
|
||||
</form:form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
|
||||
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
|
||||
<servlet>
|
||||
<servlet-name>simpleweb</servlet-name>
|
||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>contextClass</param-name>
|
||||
<param-value>
|
||||
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
|
||||
</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>contextConfigLocation</param-name>
|
||||
<param-value>com.baeldung.spring.app.config.AppConfig</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>simpleweb</servlet-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
|
@ -56,13 +56,10 @@ public class OkHttpFileUploadingLiveTest {
|
|||
.build();
|
||||
|
||||
|
||||
ProgressRequestWrapper.ProgressListener listener = new ProgressRequestWrapper.ProgressListener() {
|
||||
ProgressRequestWrapper.ProgressListener listener = (bytesWritten, contentLength) -> {
|
||||
|
||||
public void onRequestProgress(long bytesWritten, long contentLength) {
|
||||
|
||||
float percentage = 100f * bytesWritten / contentLength;
|
||||
assertFalse(Float.compare(percentage, 100) > 0);
|
||||
}
|
||||
float percentage = 100f * bytesWritten / contentLength;
|
||||
assertFalse(Float.compare(percentage, 100) > 0);
|
||||
};
|
||||
|
||||
ProgressRequestWrapper countingBody = new ProgressRequestWrapper(requestBody, listener);
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
package org.baeldung.okhttp;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import okhttp3.*;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
public class OkHttpGetLiveTest {
|
||||
|
||||
|
@ -54,7 +49,7 @@ public class OkHttpGetLiveTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void whenAsynchronousGetRequest_thenCorrect() {
|
||||
public void whenAsynchronousGetRequest_thenCorrect() throws InterruptedException {
|
||||
|
||||
OkHttpClient client = new OkHttpClient();
|
||||
|
||||
|
@ -65,14 +60,15 @@ public class OkHttpGetLiveTest {
|
|||
Call call = client.newCall(request);
|
||||
|
||||
call.enqueue(new Callback() {
|
||||
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
assertThat(response.code(), equalTo(200));
|
||||
System.out.println("OK");
|
||||
}
|
||||
|
||||
public void onFailure(Call call, IOException e) {
|
||||
|
||||
fail();
|
||||
}
|
||||
});
|
||||
|
||||
Thread.sleep(3000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
package org.baeldung.okhttp;
|
||||
|
||||
import okhttp3.*;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
|
||||
public class OkHttpMiscLiveTest {
|
||||
|
||||
private static final String BASE_URL = "http://localhost:8080/spring-rest";
|
||||
|
@ -37,7 +32,7 @@ public class OkHttpMiscLiveTest {
|
|||
response.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Test(expected = IOException.class)
|
||||
public void whenCancelRequest_thenCorrect() throws IOException {
|
||||
|
||||
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
|
||||
|
@ -49,30 +44,22 @@ public class OkHttpMiscLiveTest {
|
|||
.build();
|
||||
|
||||
final int seconds = 1;
|
||||
|
||||
final long startNanos = System.nanoTime();
|
||||
|
||||
final Call call = client.newCall(request);
|
||||
|
||||
// Schedule a job to cancel the call in 1 second.
|
||||
executor.schedule(new Runnable() {
|
||||
public void run() {
|
||||
executor.schedule(() -> {
|
||||
|
||||
logger.debug("Canceling call: " + (System.nanoTime() - startNanos) / 1e9f);
|
||||
call.cancel();
|
||||
logger.debug("Canceled call: " + (System.nanoTime() - startNanos) / 1e9f);
|
||||
|
||||
logger.debug("Canceling call: " + (System.nanoTime() - startNanos) / 1e9f);
|
||||
call.cancel();
|
||||
logger.debug("Canceled call: " + (System.nanoTime() - startNanos) / 1e9f);
|
||||
}
|
||||
}, seconds, TimeUnit.SECONDS);
|
||||
|
||||
try {
|
||||
|
||||
logger.debug("Executing call: " + (System.nanoTime() - startNanos) / 1e9f);
|
||||
Response response = call.execute();
|
||||
logger.debug("Call was expected to fail, but completed: " + (System.nanoTime() - startNanos) / 1e9f, response);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
||||
logger.debug("Call failed as expected: " + (System.nanoTime() - startNanos) / 1e9f, e);
|
||||
}
|
||||
logger.debug("Executing call: " + (System.nanoTime() - startNanos) / 1e9f);
|
||||
Response response = call.execute();
|
||||
logger.debug("Call completed: " + (System.nanoTime() - startNanos) / 1e9f, response);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
<?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>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>jetty-session-demo</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.0.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jetty</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>Brixton.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,24 @@
|
|||
package com.baeldung.spring.session.tomcatex;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@SpringBootApplication
|
||||
@RestController
|
||||
public class JettyWebApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(JettyWebApplication.class, args);
|
||||
}
|
||||
|
||||
@RequestMapping
|
||||
public String helloJetty() {
|
||||
return "hello Jetty";
|
||||
}
|
||||
|
||||
@RequestMapping("/test")
|
||||
public String lksjdf() {
|
||||
return "";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.baeldung.spring.session.tomcatex;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.sessionManagement()
|
||||
.sessionCreationPolicy(SessionCreationPolicy.NEVER)
|
||||
.and()
|
||||
.authorizeRequests().anyRequest().hasRole("ADMIN");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.baeldung.spring.session.tomcatex;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||
import org.springframework.session.web.http.HeaderHttpSessionStrategy;
|
||||
import org.springframework.session.web.http.HttpSessionStrategy;
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
|
||||
@Bean
|
||||
public HttpSessionStrategy httpSessionStrategy() {
|
||||
return new HeaderHttpSessionStrategy();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
server.port=8081
|
||||
spring.redis.host=localhost
|
||||
spring.redis.port=6379
|
|
@ -0,0 +1,22 @@
|
|||
<?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>
|
||||
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>parent-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-session</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>jetty-session-demo</module>
|
||||
<module>tomcat-session-demo</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -0,0 +1,66 @@
|
|||
<?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>
|
||||
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>tomcat-session-demo</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.0.RELEASE</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>Brixton.RELEASE</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.3</version>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,31 @@
|
|||
package com.baeldung.spring.session.tomcatex;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.inMemoryAuthentication()
|
||||
.withUser("user").password("password").roles("USER").and()
|
||||
.withUser("admin").password("password").roles("ADMIN");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.httpBasic().and()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/").permitAll()
|
||||
.antMatchers("/tomcat").hasRole("USER")
|
||||
.antMatchers("/tomcat/admin").hasRole("ADMIN")
|
||||
.anyRequest().authenticated();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package com.baeldung.spring.session.tomcatex;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer;
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
public class SessionConfig extends AbstractHttpSessionApplicationInitializer {
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.baeldung.spring.session.tomcatex;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@SpringBootApplication
|
||||
@RestController
|
||||
public class TomcatWebApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(TomcatWebApplication.class, args);
|
||||
}
|
||||
|
||||
@RequestMapping
|
||||
public String helloDefault() {
|
||||
return "hello default";
|
||||
}
|
||||
|
||||
@RequestMapping("/tomcat")
|
||||
public String helloTomcat() {
|
||||
return "hello tomcat";
|
||||
}
|
||||
|
||||
@RequestMapping("/tomcat/admin")
|
||||
public String helloTomcatAdmin() {
|
||||
return "hello tomcat admin";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
spring.redis.host=localhost
|
||||
spring.redis.port=6379
|
|
@ -0,0 +1,169 @@
|
|||
<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-social-login</artifactId>
|
||||
|
||||
<name>spring-social-login</name>
|
||||
<packaging>war</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>1.4.0.RELEASE</version>
|
||||
<relativePath></relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<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.security</groupId>
|
||||
<artifactId>spring-security-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-config</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-taglibs</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.thymeleaf.extras</groupId>
|
||||
<artifactId>thymeleaf-extras-springsecurity4</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.social</groupId>
|
||||
<artifactId>spring-social-facebook</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- test -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<finalName>spring-social-login</finalName>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-war-plugin</artifactId>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*IntegrationTest.java</exclude>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>integration</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<excludes>
|
||||
<exclude>**/*LiveTest.java</exclude>
|
||||
</excludes>
|
||||
<includes>
|
||||
<include>**/*IntegrationTest.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.mime>json</test.mime>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<commons-lang3.version>3.3.2</commons-lang3.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,18 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.boot.autoconfigure.domain.EntityScan;
|
||||
import org.springframework.boot.web.support.SpringBootServletInitializer;
|
||||
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableJpaRepositories("org.baeldung.persistence.dao")
|
||||
@EntityScan("org.baeldung.persistence.model")
|
||||
public class Application extends SpringBootServletInitializer {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
import org.baeldung.security.FacebookSignInAdapter;
|
||||
import org.baeldung.security.FacebookConnectionSignup;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.social.connect.ConnectionFactoryLocator;
|
||||
import org.springframework.social.connect.UsersConnectionRepository;
|
||||
import org.springframework.social.connect.mem.InMemoryUsersConnectionRepository;
|
||||
import org.springframework.social.connect.web.ProviderSignInController;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@ComponentScan(basePackages = { "org.baeldung.security" })
|
||||
public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Autowired
|
||||
private ConnectionFactoryLocator connectionFactoryLocator;
|
||||
|
||||
@Autowired
|
||||
private UsersConnectionRepository usersConnectionRepository;
|
||||
|
||||
@Autowired
|
||||
private FacebookConnectionSignup facebookConnectionSignup;
|
||||
|
||||
@Override
|
||||
protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
|
||||
auth.userDetailsService(userDetailsService);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure(final HttpSecurity http) throws Exception {
|
||||
// @formatter:off
|
||||
http
|
||||
.csrf().disable()
|
||||
.authorizeRequests()
|
||||
.antMatchers("/login*","/signin/**","/signup/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
.and()
|
||||
.formLogin().loginPage("/login").permitAll()
|
||||
.and()
|
||||
.logout();
|
||||
} // @formatter:on
|
||||
|
||||
@Bean
|
||||
// @Primary
|
||||
public ProviderSignInController providerSignInController() {
|
||||
((InMemoryUsersConnectionRepository) usersConnectionRepository).setConnectionSignUp(facebookConnectionSignup);
|
||||
return new ProviderSignInController(connectionFactoryLocator, usersConnectionRepository, new FacebookSignInAdapter());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package org.baeldung.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebMvc
|
||||
public class WebConfig extends WebMvcConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureDefaultServletHandling(final DefaultServletHandlerConfigurer configurer) {
|
||||
configurer.enable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewControllers(final ViewControllerRegistry registry) {
|
||||
super.addViewControllers(registry);
|
||||
registry.addViewController("/").setViewName("forward:/index");
|
||||
registry.addViewController("/index");
|
||||
registry.addViewController("/login");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(final ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
package org.baeldung.persistence.dao;
|
||||
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface UserRepository extends JpaRepository<User, Long> {
|
||||
|
||||
User findByUsername(final String username);
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.baeldung.persistence.model;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class User {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private Long id;
|
||||
|
||||
@Column(nullable = false, unique = true)
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
public User() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
builder.append("User [id=").append(id).append(", username=").append(username).append(", password=").append(password).append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import static org.apache.commons.lang3.RandomStringUtils.randomAlphabetic;
|
||||
|
||||
import org.baeldung.persistence.dao.UserRepository;
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.social.connect.Connection;
|
||||
import org.springframework.social.connect.ConnectionSignUp;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class FacebookConnectionSignup implements ConnectionSignUp {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
@Override
|
||||
public String execute(Connection<?> connection) {
|
||||
System.out.println("signup === ");
|
||||
final User user = new User();
|
||||
user.setUsername(connection.getDisplayName());
|
||||
user.setPassword(randomAlphabetic(8));
|
||||
userRepository.save(user);
|
||||
return user.getUsername();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.social.connect.Connection;
|
||||
import org.springframework.social.connect.web.SignInAdapter;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
|
||||
@Service
|
||||
public class FacebookSignInAdapter implements SignInAdapter {
|
||||
@Override
|
||||
public String signIn(String localUserId, Connection<?> connection, NativeWebRequest request) {
|
||||
System.out.println(" ====== Sign In adapter");
|
||||
SecurityContextHolder.getContext().setAuthentication(new UsernamePasswordAuthenticationToken(connection.getDisplayName(), null, Arrays.asList(new SimpleGrantedAuthority("FACEBOOK_USER"))));
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package org.baeldung.security;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.baeldung.persistence.dao.UserRepository;
|
||||
import org.baeldung.persistence.model.User;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class MyUserDetailsService implements UserDetailsService {
|
||||
|
||||
@Autowired
|
||||
private UserRepository userRepository;
|
||||
|
||||
public MyUserDetailsService() {
|
||||
super();
|
||||
}
|
||||
|
||||
// API
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(final String username) {
|
||||
final User user = userRepository.findByUsername(username);
|
||||
if (user == null) {
|
||||
throw new UsernameNotFoundException(username);
|
||||
}
|
||||
return new org.springframework.security.core.userdetails.User(username, user.getPassword(), true, true, true, true, Arrays.asList(new SimpleGrantedAuthority("ROLE_USER")));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
spring.social.facebook.appId=1715784745414888
|
||||
spring.social.facebook.appSecret=abefd6497e9cc01ad03be28509617bf0
|
||||
spring.thymeleaf.cache=false
|
|
@ -0,0 +1 @@
|
|||
insert into User (id, username, password) values (1,'john', '123');
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Spring Social Login</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"/>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-default">
|
||||
<div class="container-fluid">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" th:href="@{/}">Spring Social Login</a>
|
||||
</div>
|
||||
<p class="navbar-text navbar-right">
|
||||
<span sec:authentication="name">Username</span>
|
||||
<a th:href="@{/logout}">Logout</a>
|
||||
</p>
|
||||
</div><!-- /.container-fluid -->
|
||||
</nav>
|
||||
|
||||
<div class="container">
|
||||
<h1 class="col-sm-12">Welcome, <span sec:authentication="name">Username</span></h1>
|
||||
<p class="col-sm-12 text-muted" sec:authentication="authorities">User authorities</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,44 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<title>Spring Social Login</title>
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div th:if="${param.logout}" class="alert alert-info">You have been logged out</div>
|
||||
<div th:if="${param.error}" class="alert alert-danger">There was an error, please try again</div>
|
||||
|
||||
<h1 class="col-sm-12">Login</h1>
|
||||
<form th:action="@{/login}" method="POST" >
|
||||
<div class="row col-sm-6">
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3">Username</label>
|
||||
<span class="col-sm-9"><input class="form-control" type="text" name="username" /></span>
|
||||
</div>
|
||||
<br/>
|
||||
<div class="form-group">
|
||||
<label class="col-sm-3">Password</label>
|
||||
<span class="col-sm-9"><input class="form-control" type="password" name="password" /></span>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-12">
|
||||
<input type="submit" value="Login" class="btn btn-default" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
<br/>
|
||||
<br/>
|
||||
<div class="col-sm-12">
|
||||
<form action="/signin/facebook" method="POST">
|
||||
<input type="hidden" name="scope" value="public_profile" />
|
||||
<input type="submit" value="Login using Facebook" class="btn btn-primary" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
package org.baeldung.test;
|
||||
|
||||
import org.baeldung.config.Application;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
|
||||
public class ApplicationIntegrationTest {
|
||||
|
||||
@Test
|
||||
public void whenLoadApplication_thenSuccess() {
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue