Merge branch 'masterupstream' into beforeAfterAnnotationsJunit

This commit is contained in:
Marcos Lopez Gonzalez 2018-04-06 19:26:40 +02:00
commit 74e66a8ba9
71 changed files with 304095 additions and 327 deletions

32
apache-opennlp/pom.xml Normal file
View File

@ -0,0 +1,32 @@
<?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>apache-opennlp</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.apache.opennlp</groupId>
<artifactId>opennlp-tools</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.9.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,32 @@
package com.baeldung.apache.opennlp;
import java.io.FileInputStream;
import java.io.InputStream;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.chunker.ChunkerModel;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.SimpleTokenizer;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class ChunkerTest {
@Test
public void givenChunkerModel_whenChunk_thenChunksAreDetected() throws Exception {
SimpleTokenizer tokenizer = SimpleTokenizer.INSTANCE;
String[] tokens = tokenizer.tokenize("He reckons the current account deficit will narrow to only 8 billion.");
InputStream inputStreamPOSTagger = getClass().getResourceAsStream("/models/en-pos-maxent.bin");
POSModel posModel = new POSModel(inputStreamPOSTagger);
POSTaggerME posTagger = new POSTaggerME(posModel);
String tags[] = posTagger.tag(tokens);
InputStream inputStreamChunker = new FileInputStream("src/main/resources/models/en-chunker.bin");
ChunkerModel chunkerModel = new ChunkerModel(inputStreamChunker);
ChunkerME chunker = new ChunkerME(chunkerModel);
String[] chunks = chunker.chunk(tokens, tags);
assertThat(chunks).contains("B-NP", "B-VP", "B-NP", "I-NP", "I-NP", "I-NP", "B-VP", "I-VP", "B-PP", "B-NP", "I-NP", "I-NP", "O");
}
}

View File

@ -0,0 +1,41 @@
package com.baeldung.apache.opennlp;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Arrays;
import opennlp.tools.langdetect.Language;
import opennlp.tools.langdetect.LanguageDetector;
import opennlp.tools.langdetect.LanguageDetectorFactory;
import opennlp.tools.langdetect.LanguageDetectorME;
import opennlp.tools.langdetect.LanguageDetectorModel;
import opennlp.tools.langdetect.LanguageDetectorSampleStream;
import opennlp.tools.util.InputStreamFactory;
import opennlp.tools.util.MarkableFileInputStreamFactory;
import opennlp.tools.util.ObjectStream;
import opennlp.tools.util.PlainTextByLineStream;
import opennlp.tools.util.TrainingParameters;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class LanguageDetectorAndTrainingDataTest {
@Test
public void givenLanguageDictionary_whenLanguageDetect_thenLanguageIsDetected() throws FileNotFoundException, IOException {
InputStreamFactory dataIn = new MarkableFileInputStreamFactory(new File("src/main/resources/models/DoccatSample.txt"));
ObjectStream lineStream = new PlainTextByLineStream(dataIn, "UTF-8");
LanguageDetectorSampleStream sampleStream = new LanguageDetectorSampleStream(lineStream);
TrainingParameters params = new TrainingParameters();
params.put(TrainingParameters.ITERATIONS_PARAM, 100);
params.put(TrainingParameters.CUTOFF_PARAM, 5);
params.put("DataIndexer", "TwoPass");
params.put(TrainingParameters.ALGORITHM_PARAM, "NAIVEBAYES");
LanguageDetectorModel model = LanguageDetectorME.train(sampleStream, params, new LanguageDetectorFactory());
LanguageDetector ld = new LanguageDetectorME(model);
Language[] languages = ld.predictLanguages("estava em uma marcenaria na Rua Bruno");
assertThat(Arrays.asList(languages).toString()).contains("pob (0.9999999950605625)", "ita (4.939427661577956E-9)", "spa (9.665954064665144E-15)",
"fra (8.250349924885834E-25)");
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.apache.opennlp;
import java.io.InputStream;
import opennlp.tools.lemmatizer.DictionaryLemmatizer;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.SimpleTokenizer;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class LemmetizerTest {
@Test
public void givenEnglishDictionary_whenLemmatize_thenLemmasAreDetected() throws Exception {
SimpleTokenizer tokenizer = SimpleTokenizer.INSTANCE;
String[] tokens = tokenizer.tokenize("John has a sister named Penny.");
InputStream inputStreamPOSTagger = getClass().getResourceAsStream("/models/en-pos-maxent.bin");
POSModel posModel = new POSModel(inputStreamPOSTagger);
POSTaggerME posTagger = new POSTaggerME(posModel);
String tags[] = posTagger.tag(tokens);
InputStream dictLemmatizer = getClass().getResourceAsStream("/models/en-lemmatizer.dict");
DictionaryLemmatizer lemmatizer = new DictionaryLemmatizer(dictLemmatizer);
String[] lemmas = lemmatizer.lemmatize(tokens, tags);
assertThat(lemmas).contains("O", "have", "a", "sister", "name", "O", "O");
}
}

View File

@ -0,0 +1,39 @@
package com.baeldung.apache.opennlp;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import opennlp.tools.namefind.NameFinderME;
import opennlp.tools.namefind.TokenNameFinderModel;
import opennlp.tools.tokenize.SimpleTokenizer;
import opennlp.tools.util.Span;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class NamedEntityRecognitionTest {
@Test
public void givenEnglishPersonModel_whenNER_thenPersonsAreDetected() throws Exception {
SimpleTokenizer tokenizer = SimpleTokenizer.INSTANCE;
String[] tokens = tokenizer.tokenize("John is 26 years old. His best friend's name is Leonard. He has a sister named Penny.");
InputStream inputStreamNameFinder = getClass().getResourceAsStream("/models/en-ner-person.bin");
TokenNameFinderModel model = new TokenNameFinderModel(inputStreamNameFinder);
NameFinderME nameFinderME = new NameFinderME(model);
List<Span> spans = Arrays.asList(nameFinderME.find(tokens));
assertThat(spans.toString()).isEqualTo("[[0..1) person, [13..14) person, [20..21) person]");
List<String> names = new ArrayList<String>();
int k = 0;
for (Span s : spans) {
names.add("");
for (int index = s.getStart(); index < s.getEnd(); index++) {
names.set(k, names.get(k) + tokens[index]);
}
k++;
}
assertThat(names).contains("John","Leonard","Penny");
}
}

View File

@ -0,0 +1,24 @@
package com.baeldung.apache.opennlp;
import java.io.InputStream;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.SimpleTokenizer;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class POSTaggerTest {
@Test
public void givenPOSModel_whenPOSTagging_thenPOSAreDetected() throws Exception {
SimpleTokenizer tokenizer = SimpleTokenizer.INSTANCE;
String[] tokens = tokenizer.tokenize("John has a sister named Penny.");
InputStream inputStreamPOSTagger = getClass().getResourceAsStream("/models/en-pos-maxent.bin");
POSModel posModel = new POSModel(inputStreamPOSTagger);
POSTaggerME posTagger = new POSTaggerME(posModel);
String tags[] = posTagger.tag(tokens);
assertThat(tags).contains("NNP", "VBZ", "DT", "NN", "VBN", "NNP", ".");
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.apache.opennlp;
import java.io.InputStream;
import opennlp.tools.sentdetect.SentenceDetectorME;
import opennlp.tools.sentdetect.SentenceModel;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class SentenceDetectionTest {
@Test
public void givenEnglishModel_whenDetect_thenSentencesAreDetected() throws Exception {
String paragraph = "This is a statement. This is another statement. Now is an abstract word for time, "
+ "that is always flying. And my email address is google@gmail.com.";
InputStream is = getClass().getResourceAsStream("/models/en-sent.bin");
SentenceModel model = new SentenceModel(is);
SentenceDetectorME sdetector = new SentenceDetectorME(model);
String sentences[] = sdetector.sentDetect(paragraph);
assertThat(sentences).contains("This is a statement.",
"This is another statement.",
"Now is an abstract word for time, that is always flying.",
"And my email address is google@gmail.com.");
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.apache.opennlp;
import java.io.InputStream;
import opennlp.tools.tokenize.SimpleTokenizer;
import opennlp.tools.tokenize.TokenizerME;
import opennlp.tools.tokenize.TokenizerModel;
import opennlp.tools.tokenize.WhitespaceTokenizer;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
public class TokenizerTest {
@Test
public void givenEnglishModel_whenTokenize_thenTokensAreDetected() throws Exception {
InputStream inputStream = getClass().getResourceAsStream("/models/en-token.bin");
TokenizerModel model = new TokenizerModel(inputStream);
TokenizerME tokenizer = new TokenizerME(model);
String[] tokens = tokenizer.tokenize("Baeldung is a Spring Resource.");
assertThat(tokens).contains("Baeldung", "is", "a", "Spring", "Resource", ".");
}
@Test
public void givenWhitespaceTokenizer_whenTokenize_thenTokensAreDetected() throws Exception {
WhitespaceTokenizer tokenizer = WhitespaceTokenizer.INSTANCE;
String[] tokens = tokenizer.tokenize("Baeldung is a Spring Resource.");
assertThat(tokens).contains("Baeldung", "is", "a", "Spring", "Resource.");
}
@Test
public void givenSimpleTokenizer_whenTokenize_thenTokensAreDetected() throws Exception {
SimpleTokenizer tokenizer = SimpleTokenizer.INSTANCE;
String[] tokens = tokenizer.tokenize("Baeldung is a Spring Resource.");
assertThat(tokens).contains("Baeldung", "is", "a", "Spring", "Resource", ".");
}
}

View File

@ -0,0 +1,15 @@
package com.baeldung.kotlin.objects
object Counter {
private var count: Int = 0
fun currentCount() = count
fun increment() {
++count
}
fun decrement() {
--count
}
}

View File

@ -0,0 +1,36 @@
package com.baeldung.kotlin.objects
import org.junit.Assert
import org.junit.Test
class ObjectsTest {
@Test
fun singleton() {
Assert.assertEquals(42, SimpleSingleton.answer)
Assert.assertEquals("Hello, world!", SimpleSingleton.greet("world"))
}
@Test
fun counter() {
Assert.assertEquals(0, Counter.currentCount())
Counter.increment()
Assert.assertEquals(1, Counter.currentCount())
Counter.decrement()
Assert.assertEquals(0, Counter.currentCount())
}
@Test
fun comparator() {
val strings = listOf("Hello", "World")
val sortedStrings = strings.sortedWith(ReverseStringComparator)
Assert.assertEquals(listOf("World", "Hello"), sortedStrings)
}
@Test
fun companion() {
Assert.assertEquals("You can see me", OuterClass.public)
// Assert.assertEquals("You can't see me", OuterClass.secret) // Cannot access 'secret'
}
}

View File

@ -0,0 +1,10 @@
package com.baeldung.kotlin.objects
class OuterClass {
companion object {
private val secret = "You can't see me"
val public = "You can see me"
}
fun getSecretValue() = secret
}

View File

@ -0,0 +1,5 @@
package com.baeldung.kotlin.objects
object ReverseStringComparator : Comparator<String> {
override fun compare(o1: String, o2: String) = o1.reversed().compareTo(o2.reversed())
}

View File

@ -0,0 +1,7 @@
package com.baeldung.kotlin.objects
object SimpleSingleton {
val answer = 42;
fun greet(name: String) = "Hello, $name!"
}

View File

@ -0,0 +1,8 @@
package com.baeldung.kotlin.objects
class StaticClass {
companion object {
@JvmStatic
val staticField = 42
}
}

View File

@ -42,6 +42,7 @@
<module>apache-thrift</module>
<module>apache-curator</module>
<module>apache-zookeeper</module>
<module>apache-opennlp</module>
<module>autovalue</module>
<module>axon</module>
<module>bootique</module>

View File

@ -0,0 +1,202 @@
package com.baeldung.rxjava.filters;
import org.junit.Test;
import rx.Observable;
import rx.observers.TestSubscriber;
public class RxJavaFilterOperatorsTest {
@Test
public void givenRangeObservable_whenFilteringItems_thenOddItemsAreFiltered() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.filter(i -> i % 2 != 0);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(5);
subscriber.assertValues(1, 3, 5, 7, 9);
}
@Test
public void givenRangeObservable_whenFilteringWithTake_thenOnlyFirstThreeItemsAreEmitted() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.take(3);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(3);
subscriber.assertValues(1, 2, 3);
}
@Test
public void givenObservable_whenFilteringWithTakeWhile_thenItemsEmittedUntilConditionIsVerified() {
Observable<Integer> sourceObservable = Observable.just(1, 2, 3, 4, 3, 2, 1);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.takeWhile(i -> i < 4);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(3);
subscriber.assertValues(1, 2, 3);
}
@Test
public void givenRangeObservable_whenFilteringWithTakeFirst_thenOnlyFirstItemIsEmitted() {
Observable<Integer> sourceObservable = Observable.just(1, 2, 3, 4, 5, 7, 6);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.takeFirst(x -> x > 5);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(7);
}
@Test
public void givenRangeObservable_whenFilteringWithFirst_thenOnlyFirstThreeItemsAreEmitted() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.first();
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(1);
}
@Test
public void givenEmptyObservable_whenFilteringWithFirstOrDefault_thenDefaultValue() {
Observable<Integer> sourceObservable = Observable.empty();
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.firstOrDefault(-1);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(-1);
}
@Test
public void givenRangeObservable_whenFilteringWithTakeLast_thenLastThreeItemAreEmitted() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.takeLast(3);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(3);
subscriber.assertValues(8, 9, 10);
}
@Test
public void givenRangeObservable_whenFilteringWithLast_thenOnlyLastItemIsEmitted() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.last(i -> i % 2 != 0);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(9);
}
@Test
public void givenRangeObservable_whenFilteringWithLastAndDefault_thenOnlyDefaultIsEmitted() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.lastOrDefault(-1, i -> i > 10);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(-1);
}
@Test
public void givenObservable_whenTakingElementAt_thenItemAtSpecifiedIndexIsEmitted() {
Observable<Integer> sourceObservable = Observable.just(1, 2, 3, 5, 7, 11);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.elementAt(4);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(7);
}
@Test
public void givenObservable_whenTakingElementAtOrDefault_thenDefaultIsReturned() {
Observable<Integer> sourceObservable = Observable.just(1, 2, 3, 5, 7, 11);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.elementAtOrDefault(7, -1);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(1);
subscriber.assertValue(-1);
}
@Test
public void givenMixedTypeObservable_whenFilteringByType_thenOnlyNumbersAreEmitted() {
Observable sourceObservable = Observable.just(1, "two", 3, "five", 7, 11);
TestSubscriber subscriber = new TestSubscriber();
Observable filteredObservable = sourceObservable.ofType(String.class);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(2);
subscriber.assertValues("two", "five");
}
}

View File

@ -0,0 +1,105 @@
package com.baeldung.rxjava.filters;
import org.junit.Test;
import rx.Observable;
import rx.observers.TestSubscriber;
public class RxJavaSkipOperatorsTest {
@Test
public void givenRangeObservable_whenSkipping_thenFirstFourItemsAreSkipped() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.skip(4);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(6);
subscriber.assertValues(5, 6, 7, 8, 9, 10);
}
@Test
public void givenObservable_whenSkippingWhile_thenFirstItemsAreSkipped() {
Observable<Integer> sourceObservable = Observable.just(1, 2, 3, 4, 5, 4, 3, 2, 1);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.skipWhile(i -> i < 4);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(6);
subscriber.assertValues(4, 5, 4, 3, 2, 1);
}
@Test
public void givenRangeObservable_whenSkippingLast_thenLastFiveItemsAreSkipped() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = sourceObservable.skipLast(5);
filteredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(5);
subscriber.assertValues(1, 2, 3, 4, 5);
}
@Test
public void givenObservable_whenFilteringDistinct_thenOnlyDistinctValuesAreEmitted() {
Observable<Integer> sourceObservable = Observable.just(1, 1, 2, 2, 1, 3, 3, 1);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> distinctObservable = sourceObservable.distinct();
distinctObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(3);
subscriber.assertValues(1, 2, 3);
}
@Test
public void givenObservable_whenFilteringDistinctUntilChanged_thenOnlyDistinctConsecutiveItemsAreEmitted() {
Observable<Integer> sourceObservable = Observable.just(1, 1, 2, 2, 1, 3, 3, 1);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> distinctObservable = sourceObservable.distinctUntilChanged();
distinctObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(5);
subscriber.assertValues(1, 2, 1, 3, 1);
}
@Test
public void givenRangeObservable_whenIgnoringElements_thenOnlyDistinctConsecutiveItemsAreEmitted() {
Observable<Integer> sourceObservable = Observable.range(1, 10);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> ignoredObservable = sourceObservable.ignoreElements();
ignoredObservable.subscribe(subscriber);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValueCount(0);
subscriber.assertNoValues();
}
}

View File

@ -0,0 +1,221 @@
package com.baeldung.rxjava.filters;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.Test;
import rx.Observable;
import rx.observers.TestSubscriber;
import rx.schedulers.TestScheduler;
public class RxJavaTimeFilteringOperatorsTest {
@Test
public void givenTimedObservable_whenSampling_thenOnlySampleItemsAreEmitted() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> sampledObservable =
timedObservable.sample(2500L, TimeUnit.MILLISECONDS, testScheduler);
sampledObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValues(3, 5, 6);
}
@Test
public void givenTimedObservable_whenThrottlingLast_thenThrottleLastItemsAreEmitted() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = timedObservable.throttleLast(3100L, TimeUnit.MILLISECONDS, testScheduler);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValues(4, 6);
}
@Test
public void givenRangeObservable_whenThrottlingFirst_thenThrottledFirstItemsAreEmitted() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable =
timedObservable.throttleFirst(4100L, TimeUnit.MILLISECONDS, testScheduler);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValues(1, 6);
}
@Test
public void givenTimedObservable_whenThrottlingWithTimeout_thenLastItemIsEmitted() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = timedObservable.throttleWithTimeout(2000L, TimeUnit.MILLISECONDS, testScheduler);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValue(6);
}
@Test
public void givenTimedObservable_whenDebounceOperatorIsApplied_thenLastItemIsEmitted() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = timedObservable.debounce(2000L, TimeUnit.MILLISECONDS, testScheduler);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValue(6);
}
@Test
public void givenTimedObservable_whenUsingTimeout_thenTimeOutException() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = timedObservable.timeout(500L, TimeUnit.MILLISECONDS, testScheduler);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertError(TimeoutException.class);
subscriber.assertValues(1);
}
@Test
public void givenObservable_whenSkippingUntil_thenItemsAreSkippedUntilSecondObservableEmitsItems() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
Observable<Integer> delayedObservable = Observable.just(1)
.delay(3000, TimeUnit.MILLISECONDS, testScheduler);
TestSubscriber<Integer> subscriber = new TestSubscriber();
Observable<Integer> filteredObservable = timedObservable.skipUntil(delayedObservable);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValues(4, 5, 6);
}
@Test
public void givenObservable_whenSkippingWhile_thenItemsAreEmittedUntilSecondObservableEmitsItems() {
TestScheduler testScheduler = new TestScheduler();
Observable<Integer> timedObservable =
Observable.just(1, 2, 3, 4, 5, 6)
.zipWith(
Observable.interval(0, 1, TimeUnit.SECONDS, testScheduler),
(item, time) -> item
);
TestSubscriber subscriber = new TestSubscriber();
Observable<Integer> delayedObservable = Observable.just(1)
.delay(3000, TimeUnit.MILLISECONDS, testScheduler);
Observable<Integer> filteredObservable = timedObservable.takeUntil(delayedObservable);
filteredObservable.subscribe(subscriber);
testScheduler.advanceTimeBy(7, TimeUnit.SECONDS);
subscriber.assertCompleted();
subscriber.assertNoErrors();
subscriber.assertValues(1, 2, 3);
}
}

View File

@ -28,7 +28,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>

View File

@ -0,0 +1,26 @@
package com.baeldung.errorhandling;
import com.baeldung.autoconfiguration.MySQLAutoconfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.handler.HandlerMappingIntrospector;
@SpringBootApplication(exclude = {MySQLAutoconfiguration.class})
@ComponentScan(basePackages = "com.baeldung.errorhandling")
public class ErrorHandlingApplication {
public static void main(String [] args) {
System.setProperty("spring.profiles.active", "errorhandling");
SpringApplication.run(ErrorHandlingApplication.class, args);
}
@Bean(name = "mvcHandlerMappingIntrospector")
public HandlerMappingIntrospector mvcHandlerMappingIntrospector(ApplicationContext context) {
return new HandlerMappingIntrospector(context);
}
}

View File

@ -0,0 +1,26 @@
package com.baeldung.errorhandling.controllers;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
public class IndexController {
@GetMapping(value = {"/", ""})
public String index() {
return "index";
}
@GetMapping(value = {"/server_error"})
public String triggerServerError() {
"ser".charAt(30);
return "index";
}
@PostMapping(value = {"/general_error"})
public String triggerGeneralError() {
return "index";
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.errorhandling.controllers;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
@Controller
public class MyErrorController implements ErrorController {
public MyErrorController() {}
@RequestMapping(value = "/error")
public String handleError(HttpServletRequest request) {
Integer statusCode =
Integer.valueOf(request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE).toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error-404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error-500";
}
else {
return "error";
}
}
@Override
public String getErrorPath() {
return "/error";
}
}

View File

@ -0,0 +1,10 @@
#server
server.port=9000
server.servlet-path=/
server.context-path=/
#server.error.whitelabel.enabled=false
#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
#for Spring Boot 2.0+
#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<body>
<h1>Sorry we couldn't find the resource you are looking for</h1>
<a href="/">Go Home</a>
</body>
</html>

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<body>
<h1>Oops! We spilled something but we're fixing it</h1>
<a href="/">Go Home</a>
</body>
</html>

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html>
<body>
<h1>Something went wrong! Our Engineers are on it temp</h1>
<a href="/">Go Home</a>
</body>
</html>

View File

@ -0,0 +1,8 @@
<html>
<head>
<title>RESOURCE NOT FOUND</title>
</head>
<body>
<h1>404 RESOURCE NOT FOUND</h1>
</body>
</html>

View File

@ -0,0 +1,6 @@
<!DOCTYPE html>
<html>
<body>
<h1>Welcome Home</h1>
</body>
</html>

View File

@ -4,7 +4,7 @@
<link rel="stylesheet" href="/webjars/bootstrap/3.3.7-1/css/bootstrap.min.css" />
</head>
<body>
<h1>Welcome Home</h1>
<div class="container"><br/>
<div class="alert alert-success">
<a href="#" class="close" data-dismiss="alert" aria-label="close">×</a>

View File

@ -15,3 +15,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring
- [Geolocation by IP in Java](http://www.baeldung.com/geolocation-by-ip-with-maxmind)
- [Guide to JavaServer Pages (JSP)](http://www.baeldung.com/jsp)
- [Exploring SpringMVCs Form Tag Library](http://www.baeldung.com/spring-mvc-form-tags)
- [Guide to JSTL](http://www.baeldung.com/guide-to-jstl)

View File

@ -37,6 +37,13 @@
<!-- web -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
@ -57,6 +64,13 @@
<version>${hibernate-validator.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!-- Json conversion -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
@ -108,6 +122,14 @@
</build>
<repositories>
<repository>
<id>1</id>
<name>jstl</name>
<url>https://mvnrepository.com/artifact/javax.servlet/jstl</url>
</repository>
</repositories>
<properties>
<!-- Spring -->
<org.springframework.version>5.0.2.RELEASE</org.springframework.version>

View File

@ -0,0 +1,17 @@
package com.baeldung.jstl.bundles;
import java.util.ListResourceBundle;
public class CustomMessage_en extends ListResourceBundle {
@Override
protected Object[][] getContents() {
return contents;
}
static final Object[][] contents = {
{"verb.go", "go"},
{"verb.come", "come"},
{"verb.sit", "sit"},
{"verb.stand", "stand"}
};
}

View File

@ -0,0 +1,17 @@
package com.baeldung.jstl.bundles;
import java.util.ListResourceBundle;
public class CustomMessage_fr_FR extends ListResourceBundle {
@Override
protected Object[][] getContents() {
return contents;
}
static final Object[][] contents = {
{"verb.go", "aller"},
{"verb.come", "venir"},
{"verb.sit", "siéger"},
{"verb.stand", "se lever"}
};
}

View File

@ -0,0 +1,125 @@
package com.baeldung.jstl.controllers;
import com.baeldung.jstl.dbaccess.SQLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.sql.*;
import java.util.Calendar;
@Controller
public class JSTLController {
private static final Logger LOGGER = LoggerFactory.getLogger(JSTLController.class.getName());
@Autowired
ServletContext servletContext;
@PostConstruct
public void init() {
PreparedStatement preparedStatement = null;
Connection connection = null;
try {
connection = SQLConnection.getConnection();
preparedStatement = connection.prepareStatement("create table IF NOT EXISTS USERS " +
"( id int not null primary key AUTO_INCREMENT," +
" email VARCHAR(255) not null, first_name varchar (255), last_name varchar (255), registered DATE)");
int status = preparedStatement.executeUpdate();
preparedStatement = connection.prepareStatement("SELECT COUNT(*) AS total FROM USERS;");
ResultSet result = preparedStatement.executeQuery();
if(result!=null) {
result.next();
if (result.getInt("total") == 0) {
generateDummy(connection);
}
} else {
generateDummy(connection);
}
} catch (Exception e) {
LOGGER.error(e.getMessage());
} finally {
try {
if (preparedStatement != null) {
preparedStatement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
LOGGER.error(e.getMessage());
}
}
}
@RequestMapping(value = "/core_tags", method = RequestMethod.GET)
public ModelAndView coreTags(final Model model) {
ModelAndView mv = new ModelAndView("core_tags");
return mv;
}
@RequestMapping(value = "/core_tags_redirect", method = RequestMethod.GET)
public ModelAndView coreTagsRedirect(final Model model) {
ModelAndView mv = new ModelAndView("core_tags_redirect");
return mv;
}
@RequestMapping(value = "/formatting_tags", method = RequestMethod.GET)
public ModelAndView formattingTags(final Model model) {
ModelAndView mv = new ModelAndView("formatting_tags");
return mv;
}
@RequestMapping(value = "/sql_tags", method = RequestMethod.GET)
public ModelAndView sqlTags(final Model model) {
ModelAndView mv = new ModelAndView("sql_tags");
return mv;
}
@RequestMapping(value = "/xml_tags", method = RequestMethod.GET)
public ModelAndView xmlTags(final Model model) {
ModelAndView mv = new ModelAndView("xml_tags");
return mv;
}
@RequestMapping(value = "/items_xml", method = RequestMethod.GET)
@ResponseBody public FileSystemResource getFile(HttpServletRequest request, HttpServletResponse response) {
response.setContentType("application/xml");
return new FileSystemResource(new File(servletContext.getRealPath("/WEB-INF/items.xsl")));
}
@RequestMapping(value = "/function_tags", method = RequestMethod.GET)
public ModelAndView functionTags(final Model model) {
ModelAndView mv = new ModelAndView("function_tags");
return mv;
}
private void generateDummy(Connection connection) throws SQLException {
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO USERS " +
"(email, first_name, last_name, registered) VALUES (?, ?, ?, ?);");
preparedStatement.setString(1, "patrick@baeldung.com");
preparedStatement.setString(2, "Patrick");
preparedStatement.setString(3, "Frank");
preparedStatement.setDate(4, new Date(Calendar.getInstance().getTimeInMillis()));
preparedStatement.addBatch();
preparedStatement.setString(1, "bfrank@baeldung.com");
preparedStatement.setString(2, "Benjamin");
preparedStatement.setString(3, "Franklin");
preparedStatement.setDate(4, new Date(Calendar.getInstance().getTimeInMillis()));
preparedStatement.executeBatch();
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.jstl.dbaccess;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class SQLConnection {
private static String userName = "root";
private static String password = "";
private static final Logger LOGGER = LoggerFactory.getLogger(SQLConnection.class.getName());
public static Connection getConnection() throws Exception {
LOGGER.error("connecting...");
Class.forName("com.mysql.cj.jdbc.Driver");
LOGGER.error("class checked...");
Connection conn = null;
Properties connectionProps = new Properties();
connectionProps.put("user", userName);
connectionProps.put("password", password);
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test?autoReconnect=true&useSSL=false",
connectionProps);
LOGGER.info("Connected to database");
return conn;
}
}

View File

@ -23,7 +23,7 @@
</mvc:message-converters>
</mvc:annotation-driven>
<context:component-scan base-package="com.baeldung.spring.controller"/>
<context:component-scan base-package="com.baeldung.spring.controller, com.baeldung.jstl.controllers"/>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"/>

View File

@ -0,0 +1,27 @@
<?xml version = "1.0"?>
<xsl:stylesheet xmlns:xsl = "http://www.w3.org/1999/XSL/Transform" version = "1.0">
<xsl:output method = "html" indent = "yes"/>
<xsl:param name = "bgColor"/>
<xsl:template match = "/">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match = "items">
<table border = "1" width = "40%" bgColor = "{$bgColor}">
<xsl:for-each select = "item">
<tr>
<td><i><xsl:value-of select = "name"/></i></td>
<td><xsl:value-of select = "category"/></td>
<td><xsl:value-of select = "price"/></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>

View File

@ -7,7 +7,7 @@
http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.baeldung.spring.controller"/>
<context:component-scan base-package="com.baeldung.spring.controller, com.baeldung.jstl.controllers"/>
<!-- Start: Mapping by bean name (BeanNameUrlHandlerMapping) -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping">
@ -40,12 +40,6 @@
<bean id="helloController" class="com.baeldung.spring.controller.HelloController"/>
<!-- End: Mapping by SimpleUrlHandlerMapping -->
<!-- Start: Mapping by ControllerClassNameHandlerMapping -->
<bean
class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
<property name="caseSensitive" value="true"/>
<property name="order" value="0"/>
</bean>
<bean class="com.baeldung.spring.controller.HelloGuestController"/>
<!-- End: Mapping by ControllerClassNameHandlerMapping -->

View File

@ -0,0 +1,92 @@
<%@ page import="java.util.Random" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Calendar" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<c:set value="JSTL Core Tags Example" var="pageTitle"/>
<title>
<c:out value="${pageTitle}"/>
</title>
</head>
<body>
<h1>
<c:out value="${pageTitle}"/>
</h1>
<c:remove var="pageTitle"/>
<p><c:out value="${pageTitle}"/></p>
<div>
<h3>
<c:out value="<c:catch> Example"/>
</h3>
<c:catch var ="exceptionThrown">
<% int x = Integer.valueOf("a");%>
</c:catch>
<c:if test = "${exceptionThrown != null}">
<p>The exception is : ${exceptionThrown} <br />
There is an exception: ${exceptionThrown.message}</p>
</c:if>
</div>
<div>
<h3>
<c:out value="<c:choose> Example"/>
<c:set value="<%= Calendar.getInstance().get(Calendar.SECOND)%>" var="seconds"/>
</h3>
<p>
<c:choose>
<c:when test="${seconds le 30 }">
<c:out value="${seconds} is less than 30"/>
</c:when>
<c:when test="${seconds eq 30 }">
<c:out value="${seconds} is equal to 30"/>
</c:when>
<c:otherwise>
<c:out value="${seconds} is greater than 30"/>
</c:otherwise>
</c:choose>
</p>
</div>
<div>
<h3>
<c:out value="<c:import> Example"/>
</h3>
<c:import var = "data" url = "http://www.example.com"/>
<c:out value = "${data}"/>
</div>
<div>
<h3>
<c:out value="<c:forEach> Example"/>
</h3>
<c:forEach var = "i" items="1,4,5,6,7,8,9">
Item <c:out value = "No. ${i}"/><p>
</c:forEach>
</div>
<div>
<h3>
<c:out value="<c:forToken> Example"/>
</h3>
<c:forTokens items = "Patrick:Wilson:Ibrahima:Chris" delims = ":" var = "name">
<c:out value = "Name: ${name}"/><p>
</c:forTokens>
</div>
<div>
<h3>
<c:out value="<c:url> and <c:param> Example"/>
</h3>
<c:url value = "/core_tags" var = "myURL">
<c:param name = "parameter_1" value = "1234"/>
<c:param name = "parameter_2" value = "abcd"/>
</c:url>
<c:out value = "URL: ${myURL}"/>
</div>
</body>
</html>

View File

@ -0,0 +1,16 @@
<%@ page import="java.util.Random" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Calendar" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<c:set value="JSTL Core Tags Examples" var="pageTitle"/>
<title>
<c:out value="${pageTitle}"/>
</title>
</head>
<body>
<c:redirect url="/core_tags"/>
</body>
</html>

View File

@ -0,0 +1,213 @@
<%@ page import="java.util.Calendar" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<c:set value="JSTL Formatting Tags Example" var="pageTitle"/>
<title>
<c:out value="${pageTitle}"/>
</title>
</head>
<body>
<h1>
<c:out value="${pageTitle}"/>
</h1>
<div>
<h3>
<c:out value="<fmt:formatNumber> Example"/>
</h3>
<c:set var="fee" value="35050.1067"/>
<p>Formatted Number - Currency: <fmt:formatNumber value="${fee}"
type="currency"/></p>
<p>Formatted Number - Maximum Integer Digits: <fmt:formatNumber type="number"
maxIntegerDigits="2" value="${fee}"/></p>
<p>Formatted Number - Maximum Fraction Digits: <fmt:formatNumber type="number"
maxFractionDigits="2" value="${fee}"/></p>
<p>Formatted Number - Grouping: <fmt:formatNumber type="number"
groupingUsed="false" value="${fee}"/></p>
<p>Formatted Number - Percent with Maximum Integer Digits: <fmt:formatNumber type="percent"
maxIntegerDigits="3"
value="${fee}"/></p>
<p>Formatted Number - Percent with Minimum Fraction Digits: <fmt:formatNumber type="percent"
minFractionDigits="10"
value="${fee}"/></p>
<p>Formatted Number Percent with Minimum Integer Digits: <fmt:formatNumber type="percent"
minIntegerDigits="4" value="${fee}"/></p>
<p>Formatted Number - with Pattern: <fmt:formatNumber type="number"
pattern="###.##E0" value="${fee}"/></p>
<p>Formatted Number - Currency with Internationalization :
<fmt:setLocale value="en_US"/>
<fmt:formatNumber value="${fee}" type="currency"/>
</p>
</div>
<div>
<h3>
<c:out value="<fmt:parseNumber> Example"/>
</h3>
<fmt:parseNumber var="i" type="number" value="${fee}"/>
<p>Parsed Number : <c:out value="${i}"/></p>
<fmt:parseNumber var="i" integerOnly="true"
type="number" value="${fee}"/>
<p>Parsed Number - with Integer Only set to True: <c:out value="${i}"/></p>
</div>
<div>
<h3>
<c:out value="<fmt:formatDate> Example"/>
<c:set var="now" value="<%= new java.util.Date()%>"/>
</h3>
<p>Formatted Date - with type set to time: <fmt:formatDate type="time"
value="${now}"/></p>
<p>Formatted Date - with type set to date: <fmt:formatDate type="date"
value="${now}"/></p>
<p>Formatted Date - with type set to both: <fmt:formatDate type="both"
value="${now}"/></p>
<p>Formatted Date - with short style for both date and time: <fmt:formatDate type="both"
dateStyle="short" timeStyle="short"
value="${now}"/></p>
<p>Formatted Date - with medium style for both date and time: <fmt:formatDate type="both"
dateStyle="medium" timeStyle="medium"
value="${now}"/></p>
<p>Formatted Date - with long style for both date and time: <fmt:formatDate type="both"
dateStyle="long" timeStyle="long"
value="${now}"/></p>
<p>Formatted Date - with pattern: <fmt:formatDate pattern="yyyy-MM-dd"
value="${now}"/></p>
</div>
<div>
<h3>
<c:out value="<fmt:parseDate> Example"/>
</h3>
<c:set var="today" value="28-03-2018"/>
<fmt:parseDate value="${today}" var="parsedDate" pattern="dd-MM-yyyy"/>
<p>Parsed Date: <c:out value="${parsedDate}"/></p>
</div>
<div>
<h3>
<c:out value="<fmt:bundle> and <fmt:message> Example"/>
</h3>
<p>
<fmt:bundle basename="com.baeldung.jstl.bundles.CustomMessage" prefix="verb.">
<fmt:message key="go"/><br/>
<fmt:message key="come"/><br/>
<fmt:message key="sit"/><br/>
<fmt:message key="stand"/><br/>
</fmt:bundle>
</p>
</div>
<div>
<h3>
<c:out value="<fmt:setLocale> Example"/>
</h3>
<p>
<fmt:setLocale value="fr_FR"/>
<fmt:bundle basename="com.baeldung.jstl.bundles.CustomMessage" prefix="verb.">
<fmt:message key="go"/><br/>
<fmt:message key="come"/><br/>
<fmt:message key="sit"/><br/>
<fmt:message key="stand"/><br/>
</fmt:bundle>
</p>
</div>
<div>
<h3>
<c:out value="<fmt:setBundle> Example"/>
</h3>
<p>
<fmt:setLocale value="En"/>
<fmt:setBundle basename="com.baeldung.jstl.bundles.CustomMessage" var="lang"/>
<fmt:message key="verb.go" bundle="${lang}"/><br/>
<fmt:message key="verb.come" bundle="${lang}"/><br/>
<fmt:message key="verb.sit" bundle="${lang}"/><br/>
<fmt:message key="verb.stand" bundle="${lang}"/><br/>
</p>
</div>
<div>
<h3>
<c:out value="<fmt:timeZone> Example"/>
</h3>
<table border="1" width="40%">
<tr>
<td width="100%" colspan="2">
<p align="center">
<b>
<font size="4">Time being formatted:
<fmt:formatDate value="${now}" type="both"
timeStyle="long" dateStyle="long"/>
</font>
</b>
</p>
</td>
</tr>
<c:forEach var="zone"
items="<%= java.util.TimeZone.getAvailableIDs()%>" end="4">
<tr>
<td width="51%">
<c:out value="${zone}"/>
</td>
<td width="49%">
<fmt:timeZone value="${zone}">
<fmt:formatDate value="${now}" timeZone="${zn}"
type="both"/>
</fmt:timeZone>
</td>
</tr>
</c:forEach>
</table>
</div>
<div>
<h3>
<c:out value="<fmt:setTimeZone> Example"/>
</h3>
<p>Current Date with Default Time Zone: <fmt:formatDate value="${now}"
type="both" timeStyle="long" dateStyle="long"/></p>
<p>Change Time Zone to GMT+9</p>
<fmt:setTimeZone value="GMT+9"/>
<p>Date in Changed Zone: <fmt:formatDate value="${now}"
type="both" timeStyle="long" dateStyle="long"/></p>
</div>
<div>
<h3>
<c:out value="<fmt:requestEncoding> Example"/>
</h3>
<fmt:requestEncoding value = "UTF-8" />
<fmt:setLocale value = "fr_FR"/>
<fmt:setBundle basename = "com.baeldung.jstl.bundles.CustomMessage" var = "lang"/>
<fmt:message key="verb.go" bundle="${lang}"/><br/>
<fmt:message key="verb.come" bundle="${lang}"/><br/>
<fmt:message key="verb.sit" bundle="${lang}"/><br/>
<fmt:message key="verb.stand" bundle="${lang}"/><br/>
</div>
</body>
</html>

View File

@ -0,0 +1,151 @@
<%@ page import="java.util.Random" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Calendar" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix = "fn"
uri = "http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<c:set value="JSTL Function Tags Example" var="pageTitle"/>
<title>
<c:out value="${pageTitle}"/>
</title>
</head>
<body>
<h1>
<c:out value="${pageTitle}"/>
</h1>
<c:set var = "string1" value = "This is first string"/>
<c:set var = "string2" value = "This is second string with <tag>test XML</tag>"/>
<div>
<h3>
<c:out value="fn:contains() Example"/>
</h3>
<c:if test = "${fn:contains(string1, 'first')}">
<p>Found 'first' in string<p>
</c:if>
</div>
<div>
<h3>
<c:out value="fn:containsIgnoreCase() Example"/>
</h3>
<c:if test = "${fn:containsIgnoreCase(string1, 'first')}">
<p>Found 'first' string<p>
</c:if>
<c:if test = "${fn:containsIgnoreCase(string1, 'FIRST')}">
<p>Found 'FIRST' string<p>
</c:if>
</div>
<div>
<h3>
<c:out value="fn:endsWith() Example"/>
</h3>
<c:if test = "${fn:endsWith(string1, 'string')}">
<p>String ends with 'string'<p>
</c:if>
</div>
<div>
<h3>
<c:out value="fn:escapeXml() Example"/>
</h3>
<p>With escapeXml() Function:</p>
<p>string (1) : ${fn:escapeXml(string1)}</p>
<p>string (2) : ${fn:escapeXml(string2)}</p>
<p>Without escapeXml() Function:</p>
<p>string (1) : ${string1}</p>
<p>string (2) : ${string2}</p>
</div>
<div>
<h3>
<c:out value="fn:indexOf() Example"/>
</h3>
<p>Index (1) : ${fn:indexOf(string1, "first")}</p>
<p>Index (2) : ${fn:indexOf(string2, "second")}</p>
</div>
<div>
<h3>
<c:out value="fn:join() and fn:split() Example"/>
</h3>
<c:set var = "string3" value = "${fn:split(string1, ' ')}" />
<c:set var = "string4" value = "${fn:join(string3, '-')}" />
<p>Final String : ${string4}</p>
</div>
<div>
<h3>
<c:out value="fn:length() Example"/>
</h3>
<p>Length of String (1) : ${fn:length(string1)}</p>
<p>Length of String (2) : ${fn:length(string2)}</p>
</div>
<div>
<h3>
<c:out value="fn:replace() Example"/>
</h3>
<c:set var = "string3" value = "${fn:replace(string1, 'first', 'third')}" />
<p>Final String : ${string3}</p>
</div>
<div>
<h3>
<c:out value="fn:startsWith() Example"/>
</h3>
<c:if test = "${fn:startsWith(string1, 'This')}">
<p>String starts with 'This'</p>
</c:if>
</div>
<div>
<h3>
<c:out value="fn:substring() Example"/>
</h3>
<c:set var = "string3" value = "${fn:substring(string1, 5, 15)}" />
<p>Final sub string : ${string3}</p>
</div>
<div>
<h3>
<c:out value="fn:substringAfter() Example"/>
</h3>
<c:set var = "string3" value = "${fn:substringAfter(string1, 'is')}" />
<p>Final sub string : ${string3}</p>
</div>
<div>
<h3>
<c:out value="fn:substringBefore() Example"/>
</h3>
<c:set var = "string3" value = "${fn:substringBefore(string1, 'is')}" />
<p>Final sub string : ${string3}</p>
</div>
<div>
<h3>
<c:out value="fn:toLowerCase() Example"/>
</h3>
<c:set var = "string3" value = "${fn:toLowerCase(string1)}" />
<p>Final string : ${string3}</p>
</div>
<div>
<h3>
<c:out value="fn:toUpperCase() Example"/>
</h3>
<c:set var = "string3" value = "${fn:toUpperCase(string1)}" />
<p>Final string : ${string3}</p>
</div>
<div>
<h3>
<c:out value="fn:trim() Example"/>
</h3>
<c:set var = "string1" value = "This is first String "/>
<p>String (1) Length : ${fn:length(string1)}</p>
<c:set var = "string2" value = "${fn:trim(string1)}" />
<p>String (2) Length : ${fn:length(string2)}</p>
<p>Final string : "${string2}"</p>
</div>
</body>
</html>

View File

@ -0,0 +1,198 @@
<%@ page import="java.util.Random" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Calendar" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<html>
<head>
<c:set value="JSTL SQL Tags Example" var="pageTitle"/>
<title>
<c:out value="${pageTitle}"/>
</title>
</head>
<body>
<h1>
<c:out value="${pageTitle}"/>
</h1>
<!--
sql:setDataSource Example
-->
<sql:setDataSource var="dataSource" driver="com.mysql.cj.jdbc.Driver"
url="jdbc:mysql://localhost/test"
user="root" password=""/>
<div>
<h3>
<c:out value="<sql:query> Example"/>
</h3>
<sql:query dataSource="${dataSource}" var="result">
SELECT * from USERS;
</sql:query>
<table border="1" width="50%">
<tr>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Registered</th>
</tr>
<c:forEach var="user" items="${result.rows}" varStatus="iterator">
<tr>
<td><c:out value="${iterator.index + 1}"/></td>
<td><c:out value="${user.first_name}"/></td>
<td><c:out value="${user.last_name}"/></td>
<td><c:out value="${user.email}"/></td>
<td><c:out value="${user.registered}"/></td>
</tr>
</c:forEach>
</table>
</div>
<div>
<h3>
<c:out value="<sql:update> Example"/>
</h3>
<sql:update dataSource="${dataSource}" var="count">
INSERT INTO USERS(first_name, last_name, email) VALUES ('Grace', 'Adams', 'gracea@domain.com');
</sql:update>
<sql:query dataSource="${dataSource}" var="result">
SELECT * from USERS;
</sql:query>
<table border="1" width="50%">
<tr>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Registered</th>
</tr>
<c:forEach var="user" items="${result.rows}" varStatus="iterator">
<tr>
<td><c:out value="${iterator.index + 1}"/></td>
<td><c:out value="${user.first_name}"/></td>
<td><c:out value="${user.last_name}"/></td>
<td><c:out value="${user.email}"/></td>
<td><c:out value="${user.registered}"/></td>
</tr>
</c:forEach>
</table>
</div>
<div>
<h3>
<c:out value="<sql:param> Example"/>
</h3>
<sql:update dataSource = "${dataSource}" var = "count">
DELETE FROM USERS WHERE email = ?
<sql:param value = "gracea@domain.com" />
</sql:update>
<sql:query dataSource="${dataSource}" var="result">
SELECT * from USERS;
</sql:query>
<table border="1" width="50%">
<tr>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Registered</th>
</tr>
<c:forEach var="user" items="${result.rows}" varStatus="iterator">
<tr>
<td><c:out value="${iterator.index + 1}"/></td>
<td><c:out value="${user.first_name}"/></td>
<td><c:out value="${user.last_name}"/></td>
<td><c:out value="${user.email}"/></td>
<td><c:out value="${user.registered}"/></td>
</tr>
</c:forEach>
</table>
</div>
<div>
<h3>
<c:out value="<sql:dateParam> Example"/>
</h3>
<%
Date registered = new Date("2018/03/31");
String email = "patrick@baeldung.com";
%>
<sql:update dataSource = "${dataSource}" var = "count">
UPDATE Users SET registered = ? WHERE email = ?
<sql:dateParam value = "<%=registered%>" type = "DATE" />
<sql:param value = "<%=email%>" />
</sql:update>
<sql:query dataSource="${dataSource}" var="result">
SELECT * from USERS;
</sql:query>
<table border="1" width="50%">
<tr>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Registered</th>
</tr>
<c:forEach var="user" items="${result.rows}" varStatus="iterator">
<tr>
<td><c:out value="${iterator.index + 1}"/></td>
<td><c:out value="${user.first_name}"/></td>
<td><c:out value="${user.last_name}"/></td>
<td><c:out value="${user.email}"/></td>
<td><c:out value="${user.registered}"/></td>
</tr>
</c:forEach>
</table>
</div>
<div>
<h3>
<c:out value="<sql:transaction> Example"/>
</h3>
<sql:transaction dataSource = "${dataSource}">
<sql:update var = "count">
UPDATE Users SET first_name = 'Patrick-Ellis' WHERE email='patrick@baeldung.com'
</sql:update>
<sql:update var = "count">
UPDATE Users SET last_name = 'Nelson' WHERE email = 'patrick@baeldung.com'
</sql:update>
<sql:update var = "count">
INSERT INTO Users(first_name, last_name, email) VALUES ('Grace', 'Adams', 'gracea@domain.com');
</sql:update>
</sql:transaction>
<sql:query dataSource="${dataSource}" var="result">
SELECT * from USERS;
</sql:query>
<table border="1" width="50%">
<tr>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Registered</th>
</tr>
<c:forEach var="user" items="${result.rows}" varStatus="iterator">
<tr>
<td><c:out value="${iterator.index + 1}"/></td>
<td><c:out value="${user.first_name}"/></td>
<td><c:out value="${user.last_name}"/></td>
<td><c:out value="${user.email}"/></td>
<td><c:out value="${user.registered}"/></td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>

View File

@ -0,0 +1,99 @@
<%@ page import="java.util.Random" %>
<%@ page import="java.util.Date" %>
<%@ page import="java.util.Calendar" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %>
<html>
<head>
<c:set value="JSTL XML Tags Example" var="pageTitle"/>
<title>
<c:out value="${pageTitle}"/>
</title>
</head>
<body>
<h1>
<c:out value="${pageTitle}"/>
</h1>
<c:remove var="pageTitle"/>
<p><c:out value="${pageTitle}"/></p>
<div>
<h3>
<c:out value="<x:transform>, <x::param>, <x:parse>, <x:set>, <x:out>, and <x:if> Examples"/>
</h3>
<h3>Store Items:</h3>
<c:set var="xmltext">
<items>
<item>
<name>Steve Madden</name>
<category>Sneakers</category>
<price>34</price>
</item>
<item>
<name>Pearl Izumi</name>
<category>Sneakers</category>
<price>80</price>
</item>
<item>
<name>Katy Perry</name>
<category>Heels</category>
<price>72</price>
</item>
</items>
</c:set>
<x:parse xml="${xmltext}" var="output"/>
<b>The name of the first item listed in the store is</b>:
<x:out select="$output/items/item[1]/name"/> with price $<x:out select="$output/items/item[1]/price"/>
<br>
<x:set var="fragment" select="$output//item"/>
<b>The second item is </b>:
<c:out value="${fragment}"/>
<x:if select="$output//item">
Document has at least one
<item> element.
</x:if>
<br/>
<c:import url="/items_xml" var="xslt"/>
<x:transform xml="${xmltext}" xslt="${xslt}">
<x:param name="bgColor" value="blue"/>
</x:transform>
</div>
<div>
<h3>
<c:out value="<x:forEach> Example"/>
</h3>
<ul class="items">
<x:forEach select="$output/items/item/name" var="item">
<li>Item Name: <x:out select="$item"/></li>
</x:forEach>
</ul>
</div>
<div>
<h3>
<c:out value="<x:choose>, <x:when> and <x:otherwise> Example"/>
</h3>
<x:choose>
<x:when select="$output//item/category = 'Sneakers'">
Item category is Sneakers
</x:when>
<x:when select="$output//item/category = 'Heels'">
Item category is Heels
</x:when>
<x:otherwise>
Unknown category.
</x:otherwise>
</x:choose>
</div>
</body>
</html>

View File

@ -27,3 +27,6 @@ http://localhost:8082/spring-thymeleaf/addStudent/
http://localhost:8082/spring-thymeleaf/listStudents/
The first URL is the home page of the application. The home page has links to the other two pages.
### Security
The user/password required is: user1/user1Pass

View File

@ -1,210 +1,210 @@
<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-thymeleaf</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<java-version>1.8</java-version>
<!-- spring -->
<org.springframework-version>4.3.4.RELEASE</org.springframework-version>
<springframework-security.version>4.2.0.RELEASE</springframework-security.version>
<javax.servlet-version>3.1.0</javax.servlet-version>
<!-- thymeleaf -->
<org.thymeleaf-version>3.0.3.RELEASE</org.thymeleaf-version>
<org.thymeleaf.extras-version>3.0.0.RELEASE</org.thymeleaf.extras-version>
<thymeleaf-layout-dialect.version>2.1.2</thymeleaf-layout-dialect.version>
<!-- validation -->
<javax.validation-version>1.1.0.Final</javax.validation-version>
<hibernate-validator.version>5.3.3.Final</hibernate-validator.version>
<org.hibernate-version>5.2.5.Final</org.hibernate-version>
<!-- Maven plugins -->
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
<tomcat7-maven-plugin.version>2.2</tomcat7-maven-plugin.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${springframework-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${springframework-security.version}</version>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${org.thymeleaf-version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${org.thymeleaf-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect -->
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>${thymeleaf-layout-dialect.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>${org.thymeleaf.extras-version}</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-version}</version>
<scope>provided</scope>
</dependency>
<!-- Validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${javax.validation-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-test -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${springframework-security.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>${cargo-maven2-plugin.version}</version>
<configuration>
<wait>true</wait>
<container>
<containerId>jetty8x</containerId>
<type>embedded</type>
<systemProperties>
</systemProperties>
</container>
<configuration>
<properties>
<cargo.servlet.port>8082</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat7-maven-plugin.version}</version>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
<configuration>
<path>/</path>
<enableNaming>false</enableNaming>
<finalName>webapp.jar</finalName>
<charset>utf-8</charset>
</configuration>
</execution>
</executions>
</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>
<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-thymeleaf</artifactId>
<version>0.1-SNAPSHOT</version>
<packaging>war</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<properties>
<java-version>1.8</java-version>
<!-- spring -->
<org.springframework-version>4.3.4.RELEASE</org.springframework-version>
<springframework-security.version>4.2.0.RELEASE</springframework-security.version>
<javax.servlet-version>3.1.0</javax.servlet-version>
<!-- thymeleaf -->
<org.thymeleaf-version>3.0.9.RELEASE</org.thymeleaf-version>
<org.thymeleaf.extras-version>3.0.0.RELEASE</org.thymeleaf.extras-version>
<thymeleaf-layout-dialect.version>2.1.2</thymeleaf-layout-dialect.version>
<!-- validation -->
<javax.validation-version>1.1.0.Final</javax.validation-version>
<hibernate-validator.version>5.3.3.Final</hibernate-validator.version>
<org.hibernate-version>5.2.5.Final</org.hibernate-version>
<!-- Maven plugins -->
<maven-war-plugin.version>2.6</maven-war-plugin.version>
<cargo-maven2-plugin.version>1.6.1</cargo-maven2-plugin.version>
<tomcat7-maven-plugin.version>2.2</tomcat7-maven-plugin.version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Spring Security -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>${springframework-security.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>${springframework-security.version}</version>
</dependency>
<!-- Thymeleaf -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf</artifactId>
<version>${org.thymeleaf-version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring4</artifactId>
<version>${org.thymeleaf-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/nz.net.ultraq.thymeleaf/thymeleaf-layout-dialect -->
<dependency>
<groupId>nz.net.ultraq.thymeleaf</groupId>
<artifactId>thymeleaf-layout-dialect</artifactId>
<version>${thymeleaf-layout-dialect.version}</version>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-java8time</artifactId>
<version>${org.thymeleaf.extras-version}</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${javax.servlet-version}</version>
<scope>provided</scope>
</dependency>
<!-- Validation -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>${javax.validation-version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>${hibernate-validator.version}</version>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.security/spring-security-test -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<version>${springframework-security.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>${maven-war-plugin.version}</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.cargo</groupId>
<artifactId>cargo-maven2-plugin</artifactId>
<version>${cargo-maven2-plugin.version}</version>
<configuration>
<wait>true</wait>
<container>
<containerId>jetty8x</containerId>
<type>embedded</type>
<systemProperties>
</systemProperties>
</container>
<configuration>
<properties>
<cargo.servlet.port>8082</cargo.servlet.port>
</properties>
</configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>${tomcat7-maven-plugin.version}</version>
<executions>
<execution>
<id>tomcat-run</id>
<goals>
<goal>exec-war-only</goal>
</goals>
<phase>package</phase>
<configuration>
<path>/</path>
<enableNaming>false</enableNaming>
<finalName>webapp.jar</finalName>
<charset>utf-8</charset>
</configuration>
</execution>
</executions>
</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>
</project>

View File

@ -77,14 +77,14 @@ public class WebMVCConfig extends WebMvcConfigurerAdapter implements Application
return resolver;
}
private TemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addDialect(new LayoutDialect(new GroupingStrategy()));
engine.addDialect(new Java8TimeDialect());
engine.setTemplateResolver(templateResolver);
engine.setTemplateEngineMessageSource(messageSource());
return engine;
}
private TemplateEngine templateEngine(ITemplateResolver templateResolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.addDialect(new LayoutDialect(new GroupingStrategy()));
engine.addDialect(new Java8TimeDialect());
engine.setTemplateResolver(templateResolver);
engine.setTemplateEngineMessageSource(messageSource());
return engine;
}
private ITemplateResolver htmlTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
@ -142,7 +142,8 @@ public class WebMVCConfig extends WebMvcConfigurerAdapter implements Application
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/WEB-INF/resources/");
registry.addResourceHandler("/resources/**", "/css/**")
.addResourceLocations("/WEB-INF/resources/", "/WEB-INF/css/");
}
@Override

View File

@ -0,0 +1,33 @@
package com.baeldung.thymeleaf.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.baeldung.thymeleaf.utils.StudentUtils;
@Controller
public class FragmentsController {
@GetMapping("/fragments")
public String getHome() {
return "fragments.html";
}
@GetMapping("/markup")
public String markupPage() {
return "markup.html";
}
@GetMapping("/params")
public String paramsPage() {
return "params.html";
}
@GetMapping("/other")
public String otherPage(Model model) {
model.addAttribute("data", StudentUtils.buildStudents());
return "other.html";
}
}

View File

@ -1,9 +1,9 @@
msg.id=ID
msg.name=Name
msg.gender=Gender
msg.percent=Percentage
welcome.message=Welcome Student !!!
msg.AddStudent=Add Student
msg.ListStudents=List Students
msg.Home=Home
msg.id=ID
msg.name=Name
msg.gender=Gender
msg.percent=Percentage
welcome.message=Welcome Student !!!
msg.AddStudent=Add Student
msg.ListStudents=List Students
msg.Home=Home

View File

@ -0,0 +1,13 @@
body {
background-color: lightGray
}
.dark {
background-color: black;
color: white;
}
.light {
background-color: #f1f1f1;
color: #ccc;
}

View File

@ -1,43 +1,43 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Add Student</title>
</head>
<body>
<h1>Add Student</h1>
<form action="#" th:action="@{/saveStudent}" th:object="${student}"
method="post">
<ul>
<li th:errors="*{id}" />
<li th:errors="*{name}" />
<li th:errors="*{gender}" />
<li th:errors="*{percentage}" />
</ul>
<table border="1">
<tr>
<td><label th:text="#{msg.id}" /></td>
<td><input type="number" th:field="*{id}" /></td>
</tr>
<tr>
<td><label th:text="#{msg.name}" /></td>
<td><input type="text" th:field="*{name}" /></td>
</tr>
<tr>
<td><label th:text="#{msg.gender}" /></td>
<td><select th:field="*{gender}">
<option th:value="'M'" th:text="Male"></option>
<option th:value="'F'" th:text="Female"></option>
</select></td>
</tr>
<tr>
<td><label th:text="#{msg.percent}" /></td>
<td><input type="text" th:field="*{percentage}" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Add Student</title>
</head>
<body>
<h1>Add Student</h1>
<form action="#" th:action="@{/saveStudent}" th:object="${student}"
method="post">
<ul>
<li th:errors="*{id}" />
<li th:errors="*{name}" />
<li th:errors="*{gender}" />
<li th:errors="*{percentage}" />
</ul>
<table border="1">
<tr>
<td><label th:text="#{msg.id}" /></td>
<td><input type="number" th:field="*{id}" /></td>
</tr>
<tr>
<td><label th:text="#{msg.name}" /></td>
<td><input type="text" th:field="*{name}" /></td>
</tr>
<tr>
<td><label th:text="#{msg.gender}" /></td>
<td><select th:field="*{gender}">
<option th:value="'M'" th:text="Male"></option>
<option th:value="'F'" th:text="Female"></option>
</select></td>
</tr>
<tr>
<td><label th:text="#{msg.percent}" /></td>
<td><input type="text" th:field="*{percentage}" /></td>
</tr>
<tr>
<td><input type="submit" value="Submit" /></td>
</tr>
</table>
</form>
</body>
</html>

View File

@ -0,0 +1,12 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Fragments: home</title>
<!--/*/ <th:block th:include="fragments/general.html :: headerfiles"></th:block> /*/-->
</head>
<body>
<header th:insert="fragments/general.html :: header"> </header>
<p>Go to the next page to see fragments in action</p>
<div th:replace="fragments/general.html :: footer"></div>
</body>
</html>

View File

@ -0,0 +1,12 @@
<div th:fragment="formField (field, value, size)">
<div>
<label th:for="${#strings.toLowerCase(field)}"> <span
th:text="${field}">Field</span>
</label>
</div>
<div>
<input type="text" th:id="${#strings.toLowerCase(field)}"
th:name="${#strings.toLowerCase(field)}" th:value="${value}"
th:size="${size}">
</div>
</div>

View File

@ -0,0 +1,23 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="headerfiles">
<meta charset="UTF-8" />
<link th:href="@{/css/styles.css}" rel="stylesheet">
</head>
<body>
<div th:fragment="header">
<h1>Thymeleaf Fragments sample</h1>
</div>
<p>Go to the next page to see fragments in action</p>
<aside>
<div>This is a sidebar</div>
</aside>
<div class="another">This is another sidebar</div>
<footer th:fragment="footer">
<a th:href="@{/fragments}">Fragments Index</a> |
<a th:href="@{/markup}">Markup inclussion</a> |
<a th:href="@{/params}">Fragment params</a> |
<a th:href="@{/other}">Other</a>
</footer>
</body>
</html>

View File

@ -0,0 +1,2 @@
<div th:fragment="dataPresent">Data received</div>
<div th:fragment="noData">No data</div>

View File

@ -0,0 +1 @@
<div><p id="parag">This is a subtitle</p></div>

View File

@ -0,0 +1,14 @@
<table>
<thead th:fragment="fields(theadFields)">
<tr th:replace="${theadFields}">
</tr>
</thead>
<tbody th:fragment="tableBody(tableData)">
<tr th:each="row: ${tableData}">
<td th:text="${row.id}">0</td>
<td th:text="${row.name}">Name</td>
</tr>
</tbody>
<tfoot>
</tfoot>
</table>

View File

@ -1,45 +1,45 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Student List</title>
</head>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url : "/spring-thymeleaf/js",
});
});
</script>
<body>
<h1>Student List</h1>
<table border="1">
<thead>
<tr>
<th th:text="#{msg.id}" />
<th th:text="#{msg.name}" />
<th th:text="#{msg.gender}" />
<th th:text="#{msg.percent}" />
</tr>
</thead>
<tbody>
<tr th:each="student: ${students}">
<td th:text="${student.id}" />
<td th:text="${{student.name}}" />
<td th:switch="${student.gender}"><span th:case="'M'"
th:text="Male" /> <span th:case="'F'" th:text="Female" /></td>
<td th:text="${#conversions.convert(student.percentage, 'Integer')}" />
</tr>
</tbody>
</table>
<div>
<p>
<a th:href="@{/}" th:text="#{msg.Home}" />
</p>
</div>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<title>Student List</title>
</head>
<script type="text/javascript"
src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script>
$(document).ready(function() {
$.ajax({
url : "/spring-thymeleaf/js",
});
});
</script>
<body>
<h1>Student List</h1>
<table border="1">
<thead>
<tr>
<th th:text="#{msg.id}" />
<th th:text="#{msg.name}" />
<th th:text="#{msg.gender}" />
<th th:text="#{msg.percent}" />
</tr>
</thead>
<tbody>
<tr th:each="student: ${students}">
<td th:text="${student.id}" />
<td th:text="${{student.name}}" />
<td th:switch="${student.gender}"><span th:case="'M'"
th:text="Male" /> <span th:case="'F'" th:text="Female" /></td>
<td th:text="${#conversions.convert(student.percentage, 'Integer')}" />
</tr>
</tbody>
</table>
<div>
<p>
<a th:href="@{/}" th:text="#{msg.Home}" />
</p>
</div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Thymeleaf Fragments: markup</title>
</head>
<body>
<header th:insert="fragments/general.html :: header"> </header>
<div th:replace="fragments/general.html :: aside"></div>
<div th:replace="fragments/general.html :: div.another"></div>
<div th:replace="fragments/general.html :: footer"></div>
</body>
</html>

View File

@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Thymeleaf Fragments: other</title>
</head>
<body>
<header th:replace="fragments/general.html :: header"> </header>
<div
th:replace="${#lists.size(data) > 0} ?
~{fragments/menus.html :: dataPresent} :
~{fragments/menus.html :: noData}">
</div>
<table>
<thead
th:replace="fragments/tables.html :: fields(~{ :: .myFields})">
<tr class="myFields">
<th>Id</th>
<th>Name</th>
</tr>
</thead>
<div
th:replace="fragments/tables.html :: tableBody(tableData=${data})"></div>
</table>
<div th:replace="fragments/general.html :: footer"></div>
</body>
</html>

View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Thymeleaf Fragments: params</title>
</head>
<body>
<header th:insert="fragments/general.html :: header"> </header>
<div
th:replace="fragments/forms.html :: formField(field='Name', value='John Doe',size='40')">
</div>
<div th:replace="fragments/general.html :: footer"></div>
</body>
</html>

View File

@ -0,0 +1,90 @@
package com.baeldung.thymeleaf.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.baeldung.thymeleaf.config.InitSecurity;
import com.baeldung.thymeleaf.config.WebApp;
import com.baeldung.thymeleaf.config.WebMVCConfig;
import com.baeldung.thymeleaf.config.WebMVCSecurity;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import javax.servlet.Filter;
import static org.hamcrest.Matchers.containsString;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = { WebApp.class, WebMVCConfig.class, WebMVCSecurity.class, InitSecurity.class })
public class FragmentsTest {
@Autowired
WebApplicationContext wac;
@Autowired
MockHttpSession session;
private MockMvc mockMvc;
@Autowired
private Filter springSecurityFilterChain;
private RequestPostProcessor testUser() {
return user("user1").password("user1Pass").roles("USER");
}
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).addFilters(springSecurityFilterChain).build();
}
@Test
public void whenAccessingFragmentsRoute_thenViewHasExpectedContent() throws Exception {
this.mockMvc
.perform(get("/fragments").with(testUser()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString("<title>Thymeleaf Fragments: home</title>")));
}
@Test
public void whenAccessingParamsRoute_thenViewHasExpectedContent() throws Exception {
this.mockMvc
.perform(get("/params").with(testUser()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString("<span>Name</span>")));
}
@Test
public void whenAccessingMarkupRoute_thenViewHasExpectedContent() throws Exception {
this.mockMvc
.perform(get("/markup").with(testUser()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString("<div class=\"another\">This is another sidebar</div>")));
}
@Test
public void whenAccessingOtherRoute_thenViewHasExpectedContent() throws Exception {
this.mockMvc
.perform(get("/other").with(testUser()))
.andDo(print())
.andExpect(status().isOk())
.andExpect(content().string(containsString("<td>John Smith</td>")));
}
}

View File

@ -10,7 +10,7 @@ public class BaeldungReaderMockDelegationTest {
EasyMockSupport easyMockSupport = new EasyMockSupport();
@Test
public void givenBaeldungReader_whenReadAndWrite_thenOperationSupported() {
public void givenBaeldungReader_whenReadAndWriteSequencially_thenWorks() {
ArticleReader mockArticleReader = easyMockSupport.createMock(ArticleReader.class);
IArticleWriter mockArticleWriter = easyMockSupport.createMock(IArticleWriter.class);
BaeldungReader baeldungReader = new BaeldungReader(mockArticleReader, mockArticleWriter);

View File

@ -17,7 +17,7 @@ public class BaeldungReaderMockSupportTest extends EasyMockSupport {
@Mock IArticleWriter mockArticleWriter;
@Test
public void givenBaeldungReader_whenReadAndWrite_thenOperationSupported() {
public void givenBaeldungReader_whenReadAndWriteSequencially_thenWorks() {
expect(mockArticleReader.next())
.andReturn(null)
.times(2)