Merge branch 'master' of https://github.com/eugenp/tutorials into BAEL-633
This commit is contained in:
		
						commit
						06f69c29d8
					
				
							
								
								
									
										3
									
								
								JGit/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								JGit/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [A Guide to JGit](http://www.baeldung.com/jgit) | ||||
							
								
								
									
										3
									
								
								algorithms/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								algorithms/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Dijkstra Algorithm in Java](http://www.baeldung.com/java-dijkstra) | ||||
| @ -41,4 +41,23 @@ | ||||
| 			</plugins> | ||||
| 		</pluginManagement> | ||||
| 	</build> | ||||
| 	<reporting> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>org.codehaus.mojo</groupId> | ||||
| 				<artifactId>cobertura-maven-plugin</artifactId> | ||||
| 				<version>2.7</version> | ||||
| 				<configuration> | ||||
| 					<instrumentation> | ||||
| 						<ignores> | ||||
| 							<ignore>com/baeldung/algorithms/dijkstra/*</ignore> | ||||
| 						</ignores> | ||||
| 						<excludes> | ||||
| 							<exclude>com/baeldung/algorithms/dijkstra/*</exclude> | ||||
| 						</excludes> | ||||
| 					</instrumentation> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</reporting> | ||||
| </project> | ||||
							
								
								
									
										2
									
								
								apache-bval/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								apache-bval/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| ### Relevant Articles: | ||||
| - [Intro to Apache BVal](http://www.baeldung.com/apache-bval) | ||||
							
								
								
									
										51
									
								
								apache-bval/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								apache-bval/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| <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>apache-bval</groupId> | ||||
| 	<artifactId>apache-bval</artifactId> | ||||
| 	<version>0.0.1-SNAPSHOT</version> | ||||
| 
 | ||||
| 	<dependencies> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.bval</groupId> | ||||
| 			<artifactId>bval-jsr</artifactId> | ||||
| 			<version>${bval.version}</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>javax.validation</groupId> | ||||
| 			<artifactId>validation-api</artifactId> | ||||
| 			<version>1.1.0.Final</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.bval</groupId> | ||||
| 			<artifactId>bval-extras</artifactId> | ||||
| 			<version>${bval.version}</version> | ||||
| 		</dependency> | ||||
| 
 | ||||
| 		<dependency> | ||||
| 			<groupId>junit</groupId> | ||||
| 			<artifactId>junit</artifactId> | ||||
| 			<version>${junit.version}</version> | ||||
| 			<scope>test</scope> | ||||
| 		</dependency> | ||||
| 	</dependencies> | ||||
| 
 | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-compiler-plugin</artifactId> | ||||
| 				<version>${maven-compiler-plugin.version}</version> | ||||
| 				<configuration> | ||||
| 					<source>1.8</source> | ||||
| 					<target>1.8</target> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| 	<properties> | ||||
| 		<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version> | ||||
| 		<junit.version>4.12</junit.version> | ||||
| 		<bval.version>1.1.2</bval.version> | ||||
| 	</properties> | ||||
| </project> | ||||
							
								
								
									
										120
									
								
								apache-bval/src/main/java/com/baeldung/model/User.java
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								apache-bval/src/main/java/com/baeldung/model/User.java
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,120 @@ | ||||
| package com.baeldung.model; | ||||
| 
 | ||||
| import java.io.File; | ||||
| 
 | ||||
| import javax.validation.constraints.Min; | ||||
| import javax.validation.constraints.NotNull; | ||||
| import javax.validation.constraints.Size; | ||||
| 
 | ||||
| import org.apache.bval.constraints.Email; | ||||
| import org.apache.bval.constraints.NotEmpty; | ||||
| import org.apache.bval.extras.constraints.checkdigit.IBAN; | ||||
| import org.apache.bval.extras.constraints.creditcard.Visa; | ||||
| import org.apache.bval.extras.constraints.file.Directory; | ||||
| import org.apache.bval.extras.constraints.net.InetAddress; | ||||
| 
 | ||||
| import com.baeldung.validation.Password; | ||||
| 
 | ||||
| public class User { | ||||
|     @NotNull | ||||
|     @Email | ||||
|     private String email; | ||||
| 
 | ||||
|     @NotEmpty | ||||
|     @Password | ||||
|     private String password; | ||||
| 
 | ||||
|     @Size(min = 1, max = 20) | ||||
|     private String name; | ||||
| 
 | ||||
|     @Min(18) | ||||
|     private int age; | ||||
| 
 | ||||
|     @Visa | ||||
|     private String cardNumber = ""; | ||||
| 
 | ||||
|     @IBAN | ||||
|     private String iban = ""; | ||||
| 
 | ||||
|     @InetAddress | ||||
|     private String website = ""; | ||||
| 
 | ||||
|     @Directory | ||||
|     private File mainDirectory=new File("."); | ||||
| 
 | ||||
|     public User() { | ||||
|     } | ||||
| 
 | ||||
|     public User(String email, String password, String name, int age) { | ||||
|         super(); | ||||
|         this.email = email; | ||||
|         this.password = password; | ||||
|         this.name = name; | ||||
|         this.age = age; | ||||
|     } | ||||
| 
 | ||||
|     public String getEmail() { | ||||
|         return email; | ||||
|     } | ||||
| 
 | ||||
|     public void setEmail(String email) { | ||||
|         this.email = email; | ||||
|     } | ||||
| 
 | ||||
|     public String getPassword() { | ||||
|         return password; | ||||
|     } | ||||
| 
 | ||||
|     public void setPassword(String password) { | ||||
|         this.password = password; | ||||
|     } | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public int getAge() { | ||||
|         return age; | ||||
|     } | ||||
| 
 | ||||
|     public void setAge(int age) { | ||||
|         this.age = age; | ||||
|     } | ||||
| 
 | ||||
|     public String getCardNumber() { | ||||
|         return cardNumber; | ||||
|     } | ||||
| 
 | ||||
|     public void setCardNumber(String cardNumber) { | ||||
|         this.cardNumber = cardNumber; | ||||
|     } | ||||
| 
 | ||||
|     public String getIban() { | ||||
|         return iban; | ||||
|     } | ||||
| 
 | ||||
|     public void setIban(String iban) { | ||||
|         this.iban = iban; | ||||
|     } | ||||
| 
 | ||||
|     public String getWebsite() { | ||||
|         return website; | ||||
|     } | ||||
| 
 | ||||
|     public void setWebsite(String website) { | ||||
|         this.website = website; | ||||
|     } | ||||
| 
 | ||||
|     public File getMainDirectory() { | ||||
|         return mainDirectory; | ||||
|     } | ||||
| 
 | ||||
|     public void setMainDirectory(File mainDirectory) { | ||||
|         this.mainDirectory = mainDirectory; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,25 @@ | ||||
| package com.baeldung.validation; | ||||
| 
 | ||||
| import java.lang.annotation.Retention; | ||||
| import java.lang.annotation.RetentionPolicy; | ||||
| import java.lang.annotation.Target; | ||||
| 
 | ||||
| import javax.validation.Constraint; | ||||
| import javax.validation.Payload; | ||||
| 
 | ||||
| import static java.lang.annotation.ElementType.*; | ||||
| 
 | ||||
| @Constraint(validatedBy = { PasswordValidator.class }) | ||||
| @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER }) | ||||
| @Retention(RetentionPolicy.RUNTIME) | ||||
| public @interface Password { | ||||
|     String message() default "Invalid password"; | ||||
| 
 | ||||
|     Class<?>[] groups() default {}; | ||||
| 
 | ||||
|     Class<? extends Payload>[] payload() default {}; | ||||
| 
 | ||||
|     int length() default 6; | ||||
| 
 | ||||
|     int nonAlpha() default 1; | ||||
| } | ||||
| @ -0,0 +1,35 @@ | ||||
| package com.baeldung.validation; | ||||
| 
 | ||||
| import javax.validation.ConstraintValidator; | ||||
| import javax.validation.ConstraintValidatorContext; | ||||
| 
 | ||||
| public class PasswordValidator implements ConstraintValidator<Password, String> { | ||||
| 
 | ||||
|     private int length; | ||||
|     private int nonAlpha; | ||||
| 
 | ||||
|     @Override | ||||
|     public void initialize(Password password) { | ||||
|         this.length = password.length(); | ||||
|         this.nonAlpha = password.nonAlpha(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public boolean isValid(String value, ConstraintValidatorContext context) { | ||||
|         if (value.length() < length) { | ||||
|             return false; | ||||
|         } | ||||
|         int nonAlphaNr = 0; | ||||
|         for (int i = 0; i < value.length(); i++) { | ||||
|             if (!Character.isLetterOrDigit(value.charAt(i))) { | ||||
|                 nonAlphaNr++; | ||||
|             } | ||||
|         } | ||||
|         if (nonAlphaNr < nonAlpha) { | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,97 @@ | ||||
| package com.baeldung.validation; | ||||
| 
 | ||||
| import java.io.File; | ||||
| import java.util.Set; | ||||
| 
 | ||||
| import javax.validation.ConstraintViolation; | ||||
| import javax.validation.Validation; | ||||
| import javax.validation.Validator; | ||||
| import javax.validation.ValidatorFactory; | ||||
| 
 | ||||
| import org.apache.bval.jsr.ApacheValidationProvider; | ||||
| import org.junit.AfterClass; | ||||
| import org.junit.BeforeClass; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import static org.junit.Assert.*; | ||||
| 
 | ||||
| import com.baeldung.model.User; | ||||
| 
 | ||||
| public class ValidationTest { | ||||
|     private static ValidatorFactory validatorFactory; | ||||
|     private static Validator validator; | ||||
| 
 | ||||
|     @BeforeClass | ||||
|     public static void setup() { | ||||
|         validatorFactory = Validation.byProvider(ApacheValidationProvider.class) | ||||
|             .configure() | ||||
|             .buildValidatorFactory(); | ||||
|         validator = validatorFactory.getValidator(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenUser_whenValidate_thenValidationViolations() { | ||||
|         User user = new User("ana@yahoo.com", "pass", "nameTooLong_______________", 15); | ||||
| 
 | ||||
|         Set<ConstraintViolation<User>> violations = validator.validate(user); | ||||
|         assertTrue("no violations", violations.size() > 0); | ||||
|     } | ||||
| 	 | ||||
|     @Test | ||||
|     public void givenInvalidAge_whenValidateProperty_thenConstraintViolation() { | ||||
|         User user = new User("ana@yahoo.com", "pass", "Ana", 12); | ||||
| 
 | ||||
|         Set<ConstraintViolation<User>> propertyViolations = validator.validateProperty(user, "age"); | ||||
|         assertEquals("size is not 1", 1, propertyViolations.size()); | ||||
|     } | ||||
| 	 | ||||
|     @Test | ||||
|     public void givenValidAge_whenValidateValue_thenNoConstraintViolation() { | ||||
|         User user = new User("ana@yahoo.com", "pass", "Ana", 18); | ||||
|      | ||||
|         Set<ConstraintViolation<User>> valueViolations = validator.validateValue(User.class, "age", 20); | ||||
|         assertEquals("size is not 0", 0, valueViolations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenValidateNonJSR_thenCorrect() { | ||||
|         User user = new User("ana@yahoo.com", "pass", "Ana", 20); | ||||
|         user.setCardNumber("1234"); | ||||
|         user.setIban("1234"); | ||||
|         user.setWebsite("10.0.2.50"); | ||||
|         user.setMainDirectory(new File(".")); | ||||
| 		 | ||||
|         Set<ConstraintViolation<User>> violations = validator.validateProperty(user, "iban"); | ||||
|         assertEquals("size is not 1", 1, violations.size()); | ||||
| 
 | ||||
|         violations = validator.validateProperty(user, "website"); | ||||
|         assertEquals("size is not 0", 0, violations.size()); | ||||
| 
 | ||||
|         violations = validator.validateProperty(user, "mainDirectory"); | ||||
|         assertEquals("size is not 0", 0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenInvalidPassword_whenValidatePassword_thenConstraintViolation() { | ||||
|         User user = new User("ana@yahoo.com", "password", "Ana", 20); | ||||
|         Set<ConstraintViolation<User>> violations = validator.validateProperty(user, "password"); | ||||
|         assertEquals("message incorrect", "Invalid password", violations.iterator() | ||||
|             .next() | ||||
|             .getMessage()); | ||||
|     } | ||||
| 	 | ||||
|     @Test | ||||
|     public void givenValidPassword_whenValidatePassword_thenNoConstraintViolation() { | ||||
|         User user = new User("ana@yahoo.com", "password#", "Ana", 20); | ||||
| 		 | ||||
|         Set<ConstraintViolation<User>>  violations = validator.validateProperty(user, "password"); | ||||
|         assertEquals("size is not 0", 0, violations.size()); | ||||
|     } | ||||
| 
 | ||||
|     @AfterClass | ||||
|     public static void close() { | ||||
|         if (validatorFactory != null) { | ||||
|             validatorFactory.close(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										50
									
								
								apache-solrj/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								apache-solrj/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,50 @@ | ||||
| <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>apache-solrj</artifactId> | ||||
| 	<version>0.0.1-SNAPSHOT</version> | ||||
|     <packaging>jar</packaging> | ||||
|     <name>apache-solrj</name> | ||||
| 
 | ||||
| 	<properties> | ||||
| 		<junit.version>4.12</junit.version> | ||||
| 		<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version> | ||||
| 	</properties> | ||||
| 
 | ||||
| 	<dependencies> | ||||
| 		<dependency> | ||||
| 			<groupId>org.apache.solr</groupId> | ||||
| 			<artifactId>solr-solrj</artifactId> | ||||
| 			<version>6.4.0</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>junit</groupId> | ||||
| 			<artifactId>junit</artifactId> | ||||
| 			<version>${junit.version}</version> | ||||
| 			<scope>test</scope> | ||||
| 		</dependency> | ||||
| 	</dependencies> | ||||
| 
 | ||||
| 	<build> | ||||
| 		<plugins> | ||||
| 			<plugin> | ||||
| 				<artifactId>maven-compiler-plugin</artifactId> | ||||
| 				<version>2.3.2</version> | ||||
| 			</plugin> | ||||
| 			<plugin> | ||||
| 				<groupId>org.apache.maven.plugins</groupId> | ||||
| 				<artifactId>maven-surefire-plugin</artifactId> | ||||
| 				<version>${maven-surefire-plugin.version}</version> | ||||
| 				<configuration> | ||||
| 					<source>1.8</source> | ||||
| 					<target>1.8</target> | ||||
| 					<excludes> | ||||
| 						<exclude>**/*IntegrationTest.java</exclude> | ||||
| 						<exclude>**/*LiveTest.java</exclude> | ||||
| 					</excludes> | ||||
| 				</configuration> | ||||
| 			</plugin> | ||||
| 		</plugins> | ||||
| 	</build> | ||||
| </project> | ||||
| @ -0,0 +1,43 @@ | ||||
| package com.baeldung.solrjava; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import org.apache.solr.client.solrj.SolrServerException; | ||||
| import org.apache.solr.client.solrj.impl.HttpSolrClient; | ||||
| import org.apache.solr.client.solrj.impl.XMLResponseParser; | ||||
| import org.apache.solr.common.SolrInputDocument; | ||||
| 
 | ||||
| public class SolrJavaIntegration { | ||||
| 
 | ||||
|     private HttpSolrClient solrClient; | ||||
| 
 | ||||
|     public SolrJavaIntegration(String clientUrl) { | ||||
| 
 | ||||
|         solrClient = new HttpSolrClient.Builder(clientUrl).build(); | ||||
|         solrClient.setParser(new XMLResponseParser()); | ||||
|     } | ||||
| 
 | ||||
|     public void addSolrDocument(String documentId, String itemName, String itemPrice) throws SolrServerException, IOException { | ||||
| 
 | ||||
|         SolrInputDocument document = new SolrInputDocument(); | ||||
|         document.addField("id", documentId); | ||||
|         document.addField("name", itemName); | ||||
|         document.addField("price", itemPrice); | ||||
|         solrClient.add(document); | ||||
|         solrClient.commit(); | ||||
|     } | ||||
| 
 | ||||
|     public void deleteSolrDocument(String documentId) throws SolrServerException, IOException { | ||||
| 
 | ||||
|         solrClient.deleteById(documentId); | ||||
|         solrClient.commit(); | ||||
|     } | ||||
| 
 | ||||
|     protected HttpSolrClient getSolrClient() { | ||||
|         return solrClient; | ||||
|     } | ||||
| 
 | ||||
|     protected void setSolrClient(HttpSolrClient solrClient) { | ||||
|         this.solrClient = solrClient; | ||||
|     } | ||||
| } | ||||
| @ -6,32 +6,21 @@ import java.io.IOException; | ||||
| 
 | ||||
| import org.apache.solr.client.solrj.SolrQuery; | ||||
| import org.apache.solr.client.solrj.SolrServerException; | ||||
| import org.apache.solr.client.solrj.impl.HttpSolrClient; | ||||
| import org.apache.solr.client.solrj.impl.XMLResponseParser; | ||||
| import org.apache.solr.client.solrj.response.QueryResponse; | ||||
| import org.apache.solr.common.SolrDocument; | ||||
| import org.apache.solr.common.SolrDocumentList; | ||||
| import org.apache.solr.common.SolrInputDocument; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| public class SolrJavaIntegrationTest { | ||||
| 
 | ||||
|     private HttpSolrClient solr; | ||||
|     private SolrInputDocument document; | ||||
|     private SolrJavaIntegration solrJavaIntegration; | ||||
| 
 | ||||
|     @Before | ||||
|     public void setUp() throws Exception { | ||||
| 
 | ||||
|         solr = new HttpSolrClient("http://localhost:8983/solr/bigboxstore"); | ||||
|         solr.setParser(new XMLResponseParser()); | ||||
|          | ||||
|         document = new SolrInputDocument(); | ||||
|         document.addField("id", "123456"); | ||||
|         document.addField("name", "Kenmore Dishwasher"); | ||||
|         document.addField("price", "599.99"); | ||||
|         solr.add(document); | ||||
|         solr.commit(); | ||||
|         solrJavaIntegration = new SolrJavaIntegration("http://localhost:8983/solr/bigboxstore"); | ||||
|         solrJavaIntegration.addSolrDocument("123456", "Kenmore Dishwasher", "599.99"); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
| @ -41,7 +30,7 @@ public class SolrJavaIntegrationTest { | ||||
|         query.set("q", "id:123456"); | ||||
|         QueryResponse response = null; | ||||
| 
 | ||||
|         response = solr.query(query); | ||||
|         response = solrJavaIntegration.getSolrClient().query(query); | ||||
| 
 | ||||
|         SolrDocumentList docList = response.getResults(); | ||||
|         assertEquals(docList.getNumFound(), 1); | ||||
| @ -55,14 +44,13 @@ public class SolrJavaIntegrationTest { | ||||
|     @Test | ||||
|     public void whenDelete_thenVerifyDeleted() throws SolrServerException, IOException { | ||||
| 
 | ||||
|         solr.deleteById("123456"); | ||||
|         solr.commit(); | ||||
|         solrJavaIntegration.deleteSolrDocument("123456"); | ||||
| 
 | ||||
|         SolrQuery query = new SolrQuery(); | ||||
|         query.set("q", "id:123456"); | ||||
|         QueryResponse response = null; | ||||
| 
 | ||||
|         response = solr.query(query); | ||||
|         response = solrJavaIntegration.getSolrClient().query(query); | ||||
| 
 | ||||
|         SolrDocumentList docList = response.getResults(); | ||||
|         assertEquals(docList.getNumFound(), 0); | ||||
							
								
								
									
										3
									
								
								apache-thrift/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								apache-thrift/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Working with Apache Thrift](http://www.baeldung.com/apache-thrift) | ||||
							
								
								
									
										3
									
								
								apache-velocity/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								apache-velocity/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Introduction to Apache Velocity](http://www.baeldung.com/apache-velocity) | ||||
| @ -6,3 +6,5 @@ | ||||
| 
 | ||||
| ### Relevant Articles: | ||||
| - [Java 9 Stream API Improvements](http://www.baeldung.com/java-9-stream-api) | ||||
| - [Java 9 Convenience Factory Methods for Collections](http://www.baeldung.com/java-9-collections-factory-methods)  | ||||
| - [New Stream Collectors in Java 9](http://www.baeldung.com/java9-stream-collectors) | ||||
|  | ||||
| @ -58,3 +58,24 @@ | ||||
| - [Guide to java.util.concurrent.BlockingQueue](http://www.baeldung.com/java-blocking-queue) | ||||
| - [Guide to CountDownLatch in Java](http://www.baeldung.com/java-countdown-latch) | ||||
| - [How to Design a Genetic Algorithm in Java](http://www.baeldung.com/java-genetic-algorithm) | ||||
| - [A Guide to ConcurrentMap](http://www.baeldung.com/java-concurrent-map) | ||||
| - [Guide to PriorityBlockingQueue in Java](http://www.baeldung.com/java-priority-blocking-queue) | ||||
| - [Guide to Java 8 groupingBy Collector](http://www.baeldung.com/java-groupingby-collector) | ||||
| - [Avoiding the ConcurrentModificationException in Java](http://www.baeldung.com/java-concurrentmodificationexception) | ||||
| - [Guide to WeakHashMap in Java](http://www.baeldung.com/java-weakhashmap) | ||||
| - [Strategy Design Pattern in Java 8](http://www.baeldung.com/java-strategy-pattern) | ||||
| - [Java 8 and Infinite Streams](http://www.baeldung.com/java-inifinite-streams) | ||||
| - [Custom Thread Pools In Java 8 Parallel Streams](http://www.baeldung.com/java-8-parallel-streams-custom-threadpool) | ||||
| - [String Operations with Java Streams](http://www.baeldung.com/java-stream-operations-on-strings) | ||||
| - [Spring Security – Cache Control Headers](http://www.baeldung.com/spring-security-cache-control-headers) | ||||
| - [Basic Introduction to JMX](http://www.baeldung.com/java-management-extensions) | ||||
| - [AWS Lambda With Java](http://www.baeldung.com/java-aws-lambda) | ||||
| - [Introduction to Nashorn](http://www.baeldung.com/java-nashorn) | ||||
| - [Exceptions in Java 8 Lambda Expressions](http://www.baeldung.com/java-lambda-exceptions) | ||||
| - [Guide to the Guava BiMap](http://www.baeldung.com/guava-bimap) | ||||
| - [Iterable to Stream in Java](http://www.baeldung.com/java-iterable-to-stream) | ||||
| - [Java 8 Stream findFirst() vs. findAny()](http://www.baeldung.com/java-stream-findfirst-vs-findany) | ||||
| - [Chained Exceptions in Java](http://www.baeldung.com/java-chained-exceptions) | ||||
| - [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap) | ||||
| - [A Guide to LinkedHashMap in Java](http://www.baeldung.com/java-linked-hashmap) | ||||
| - [A Guide to TreeMap in Java](http://www.baeldung.com/java-treemap) | ||||
|  | ||||
| @ -1,2 +0,0 @@ | ||||
| ### Relevant Articles: | ||||
| - [The Java HashMap Under the Hood](http://www.baeldung.com/java-hashmap) | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| @ -15,7 +15,7 @@ public class DivisibilityTest { | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenNumber_whenDivisiblebyTwo_thenCorrect() { | ||||
|     public void givenNumber_whenDivisibleByTwo_thenCorrect() { | ||||
|         assertEquals(number % 2, 0); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,34 @@ | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import org.junit.Assert; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.Parameterized; | ||||
| import org.junit.runners.Parameterized.Parameters; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| @RunWith(value = Parameterized.class) | ||||
| public class ParametrizedTests { | ||||
| 
 | ||||
|     private int value; | ||||
|     private boolean isEven; | ||||
| 
 | ||||
|     public ParametrizedTests(int value, boolean isEven) { | ||||
|         this.value = value; | ||||
|         this.isEven = isEven; | ||||
|     } | ||||
| 
 | ||||
|     @Parameters | ||||
|     public static Collection<Object[]> data() { | ||||
|         Object[][] data = new Object[][]{{1, false}, {2, true}, {4, true}}; | ||||
|         return Arrays.asList(data); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenParametrizedNumber_ifEvenCheckOK_thenCorrect() { | ||||
|         Assert.assertEquals(isEven, value % 2 == 0); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,15 @@ | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| 
 | ||||
| public class RegistrationTest { | ||||
|     private static final Logger LOGGER = LoggerFactory.getLogger(RegistrationTest.class); | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCalledFromSuite_thanOK() { | ||||
|         LOGGER.info("Registration successful"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,14 @@ | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import org.junit.Test; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| public class SignInTest { | ||||
|     private static final Logger LOGGER = LoggerFactory.getLogger(SignInTest.class); | ||||
| 
 | ||||
|     @Test | ||||
|     public void whenCalledFromSuite_thanOK() { | ||||
|         LOGGER.info("SignIn successful"); | ||||
|     } | ||||
| } | ||||
| @ -1,4 +1,4 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import static org.junit.Assert.assertEquals; | ||||
| 
 | ||||
| @ -1,10 +1,10 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.Suite; | ||||
| 
 | ||||
| @RunWith(Suite.class) | ||||
| @Suite.SuiteClasses({ StringCaseTest.class, DivisibilityTest.class }) | ||||
| @Suite.SuiteClasses({ RegistrationTest.class, SignInTest.class }) | ||||
| public class SuiteTest { | ||||
| 
 | ||||
| } | ||||
| @ -1,8 +1,4 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| 
 | ||||
| import java.security.Security; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| package com.baeldung.junit4vstestng; | ||||
| 
 | ||||
| import org.junit.After; | ||||
| import org.junit.AfterClass; | ||||
| @ -12,6 +8,9 @@ import org.junit.BeforeClass; | ||||
| import org.junit.Ignore; | ||||
| import org.junit.Test; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class SummationServiceTest { | ||||
|     private static List<Integer> numbers; | ||||
| 
 | ||||
| @ -1,46 +0,0 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| 
 | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| public class DependentTests { | ||||
| 
 | ||||
|     private EmailValidator emailValidator; | ||||
|     private LoginValidator loginValidator; | ||||
|     private String validEmail = "abc@qwe.com"; | ||||
| 
 | ||||
|     @BeforeClass | ||||
|     public void setup() { | ||||
|         emailValidator = new EmailValidator(); | ||||
|         loginValidator = new LoginValidator(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenEmail_ifValid_thenTrue() { | ||||
|         boolean valid = emailValidator.validate(validEmail); | ||||
|         Assert.assertEquals(valid, true); | ||||
|     } | ||||
| 
 | ||||
|     @Test(dependsOnMethods = { "givenEmail_ifValid_thenTrue" }) | ||||
|     public void givenValidEmail_whenLoggedin_thenTrue() { | ||||
|         boolean valid = loginValidator.validate(); | ||||
|         Assert.assertEquals(valid, true); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| class EmailValidator { | ||||
| 
 | ||||
|     public boolean validate(String validEmail) { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| class LoginValidator { | ||||
| 
 | ||||
|     public boolean validate() { | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,49 +0,0 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.Collection; | ||||
| 
 | ||||
| import org.junit.Assert; | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.Parameterized; | ||||
| import org.junit.runners.Parameterized.Parameters; | ||||
| 
 | ||||
| @RunWith(value = Parameterized.class) | ||||
| public class MyParameterisedUnitTest { | ||||
| 
 | ||||
|     private String name; | ||||
|     private NameCheck nameCheck; | ||||
| 
 | ||||
|     @Before | ||||
|     public void initialSetup() { | ||||
|         nameCheck = new NameCheck(); | ||||
|     } | ||||
| 
 | ||||
|     public MyParameterisedUnitTest(String myName) { | ||||
|         this.name = myName; | ||||
|     } | ||||
| 
 | ||||
|     @Parameters | ||||
|     public static Collection<Object[]> data() { | ||||
|         Object[][] data = new Object[][] { { "Peter" }, { "Sam" }, { "Tim" }, { "Lucy" } }; | ||||
|         return Arrays.asList(data); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenName_whenValidLength_thenTrue() { | ||||
|         boolean valid = nameCheck.nameCheck(name); | ||||
|         Assert.assertEquals(valid, true); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| class NameCheck { | ||||
| 
 | ||||
|     public boolean nameCheck(String name) { | ||||
|         if (name.length() > 0) | ||||
|             return true; | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,81 +0,0 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| 
 | ||||
| import org.testng.Assert; | ||||
| import org.testng.annotations.BeforeClass; | ||||
| import org.testng.annotations.DataProvider; | ||||
| import org.testng.annotations.Parameters; | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| public class MyParameterisedUnitTestNg { | ||||
| 
 | ||||
|     private PrimeNumberCheck primeNumberChecker; | ||||
| 
 | ||||
|     @BeforeClass | ||||
|     public void intialSetup() { | ||||
|         primeNumberChecker = new PrimeNumberCheck(); | ||||
|     } | ||||
| 
 | ||||
|     @Test(enabled = false) | ||||
|     @Parameters({ "num", "expectedResult" }) | ||||
|     public void givenNumber_ifPrime_thenCorrect(int number, boolean expectedResult) { | ||||
|         Assert.assertEquals(expectedResult, primeNumberChecker.validate(number)); | ||||
|     } | ||||
| 
 | ||||
|     @DataProvider(name = "test1") | ||||
|     public static Object[][] primeNumbers() { | ||||
|         return new Object[][] { { 2, true }, { 6, false }, { 19, true }, { 22, false }, { 23, true } }; | ||||
|     } | ||||
| 
 | ||||
|     @Test(dataProvider = "test1") | ||||
|     public void givenNumber_whenPrime_thenCorrect(Integer inputNumber, Boolean expectedResult) { | ||||
|         Assert.assertEquals(expectedResult, primeNumberChecker.validate(inputNumber)); | ||||
|     } | ||||
| 
 | ||||
|     @Test(dataProvider = "myDataProvider") | ||||
|     public void parameterCheckTest(User user) { | ||||
|         Assert.assertEquals("sam", user.getName()); | ||||
|         Assert.assertEquals(12, user.getAge()); | ||||
|     } | ||||
| 
 | ||||
|     @DataProvider(name = "myDataProvider") | ||||
|     public Object[][] parameterProvider() { | ||||
|         User usr = new User(); | ||||
|         usr.setName("sam"); | ||||
|         usr.setAge(12); | ||||
|         return new Object[][] { { usr } }; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| class PrimeNumberCheck { | ||||
| 
 | ||||
|     public Object validate(int number) { | ||||
|         for (int i = 2; i < number; i++) { | ||||
|             if (number % i == 0) | ||||
|                 return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| class User { | ||||
|     private String name; | ||||
|     private int age; | ||||
| 
 | ||||
|     public String getName() { | ||||
|         return name; | ||||
|     } | ||||
| 
 | ||||
|     public void setName(String name) { | ||||
|         this.name = name; | ||||
|     } | ||||
| 
 | ||||
|     public int getAge() { | ||||
|         return age; | ||||
|     } | ||||
| 
 | ||||
|     public void setAge(int age) { | ||||
|         this.age = age; | ||||
|     } | ||||
| } | ||||
| @ -1,11 +0,0 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| 
 | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| public class RegistrationTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenEmail_ifValid_thenCorrect() { | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -1,12 +0,0 @@ | ||||
| package com.baeldung.test.comparison; | ||||
| 
 | ||||
| import org.testng.annotations.Test; | ||||
| 
 | ||||
| public class SignInTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenUsername_ifValid_thenCorrect() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,10 +0,0 @@ | ||||
| <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > | ||||
| <suite name="My test suite"> | ||||
|     <test name="testing"> | ||||
|        <parameter name="num" value="2"/>     | ||||
|        <parameter name="expectedResult" value="true"/> | ||||
|     <classes> | ||||
|         <class name="com.baeldung.test.comparison.MyParameterisedUnitTestNg"/> | ||||
|     </classes> | ||||
|     </test> | ||||
| </suite> | ||||
| @ -1,13 +0,0 @@ | ||||
| <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > | ||||
| <suite name="regression_test"> | ||||
| <test name="testing"> | ||||
|     <groups> | ||||
|         <run> | ||||
|             <include name="sanity" /> | ||||
|         </run> | ||||
|     </groups> | ||||
|     <classes> | ||||
|         <class name="com.baeldung.test.comparison.SummationServiceTestTestNg" /> | ||||
|     </classes> | ||||
| </test> | ||||
| </suite> | ||||
| @ -1,9 +0,0 @@ | ||||
| <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > | ||||
| <suite name="Evaluation_Suite"> | ||||
|     <test name="Sanity"> | ||||
|         <classes> | ||||
|             <class name="com.baeldung.test.comparison.RegistrationTest" /> | ||||
|             <class name="com.baeldung.test.comparison.SignInTest" /> | ||||
|         </classes> | ||||
|     </test> | ||||
| </suite> | ||||
| @ -4,6 +4,7 @@ | ||||
| - [Introduction to Couchbase SDK for Java](http://www.baeldung.com/java-couchbase-sdk) | ||||
| - [Using Couchbase in a Spring Application](http://www.baeldung.com/couchbase-sdk-spring) | ||||
| - [Asynchronous Batch Opereations in Couchbase](http://www.baeldung.com/async-batch-operations-in-couchbase) | ||||
| - [Querying Couchbase with MapReduce Views](http://www.baeldung.com/couchbase-query-mapreduce-view) | ||||
| 
 | ||||
| ### Overview | ||||
| This Maven project contains the Java code for the Couchbase entities and Spring services | ||||
|  | ||||
| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Concurrency with LMAX Disruptor – An Introduction](http://www.baeldung.com/lmax-disruptor-concurrency) | ||||
							
								
								
									
										3
									
								
								ejb/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								ejb/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Guide to EJB Set-up](http://www.baeldung.com/ejb-intro) | ||||
| @ -16,3 +16,11 @@ | ||||
| - [Guava – Sets](http://www.baeldung.com/guava-sets) | ||||
| - [Guava – Maps](http://www.baeldung.com/guava-maps) | ||||
| - [Guava Set + Function = Map](http://www.baeldung.com/guava-set-function-map-tutorial) | ||||
| - [Guide to Guava’s Ordering](http://www.baeldung.com/guava-ordering) | ||||
| - [Guide to Guava’s PreConditions](http://www.baeldung.com/guava-preconditions) | ||||
| - [Introduction to Guava CacheLoader](http://www.baeldung.com/guava-cacheloader) | ||||
| - [Guide to Guava’s EventBus](http://www.baeldung.com/guava-eventbus) | ||||
| - [Guide to Guava Multimap](http://www.baeldung.com/guava-multimap) | ||||
| - [Guide to Guava RangeSet](http://www.baeldung.com/guava-rangeset) | ||||
| - [Guide to Guava RangeMap](http://www.baeldung.com/guava-rangemap) | ||||
| - [Guide to Guava Table](http://www.baeldung.com/guava-table) | ||||
|  | ||||
| @ -19,3 +19,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring | ||||
| - [Multipart Upload with HttpClient 4](http://www.baeldung.com/httpclient-multipart-upload) | ||||
| - [HttpAsyncClient Tutorial](http://www.baeldung.com/httpasyncclient-tutorial) | ||||
| - [HttpClient 4 Tutorial](http://www.baeldung.com/httpclient-guide) | ||||
| - [Advanced HttpClient Configuration](http://www.baeldung.com/httpclient-advanced-config) | ||||
|  | ||||
| @ -25,3 +25,4 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring | ||||
| - [More Jackson Annotations](http://www.baeldung.com/jackson-advanced-annotations) | ||||
| - [Inheritance with Jackson](http://www.baeldung.com/jackson-inheritance) | ||||
| - [Guide to @JsonFormat in Jackson](http://www.baeldung.com/jackson-jsonformat) | ||||
| - [A Guide to Optional with Jackson](http://www.baeldung.com/jackson-optional) | ||||
|  | ||||
							
								
								
									
										3
									
								
								java-mongodb/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								java-mongodb/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [A Guide to MongoDB with Java](http://www.baeldung.com/java-mongodb) | ||||
| @ -1,2 +1,4 @@ | ||||
| ### Relevant Articles: | ||||
| - [Introduction to Javaslang](http://www.baeldung.com/javaslang) | ||||
| - [Guide to Try in Javaslang](http://www.baeldung.com/javaslang-try) | ||||
| - [Guide to Pattern Matching in Javaslang](http://www.baeldung.com/javaslang-pattern-matching) | ||||
|  | ||||
| @ -1,2 +1,3 @@ | ||||
| ### Relevant Articles: | ||||
| - [Scheduling in Java EE](http://www.baeldung.com/scheduling-in-java-enterprise-edition) | ||||
| - [JSON Processing in Java EE 7](http://www.baeldung.com/jee7-json) | ||||
|  | ||||
| @ -0,0 +1,57 @@ | ||||
| package com.baeldung.javaeeannotations; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| 
 | ||||
| import javax.servlet.ServletConfig; | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.annotation.HttpConstraint; | ||||
| import javax.servlet.annotation.HttpMethodConstraint; | ||||
| import javax.servlet.annotation.ServletSecurity; | ||||
| import javax.servlet.annotation.WebInitParam; | ||||
| import javax.servlet.annotation.WebServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| 
 | ||||
| @WebServlet( | ||||
|   name = "BankAccountServlet",  | ||||
|   description = "Represents a Bank Account and it's transactions",  | ||||
|   urlPatterns = {"/account", "/bankAccount" },  | ||||
|   initParams = { @WebInitParam(name = "type", value = "savings") } | ||||
|   ) | ||||
| @ServletSecurity( | ||||
|   value = @HttpConstraint(rolesAllowed = {"admin"}), | ||||
|   httpMethodConstraints = {@HttpMethodConstraint(value = "POST", rolesAllowed = {"admin"})} | ||||
|   ) | ||||
| public class AccountServlet extends javax.servlet.http.HttpServlet { | ||||
| 
 | ||||
|     String accountType = null; | ||||
| 
 | ||||
|     @Override | ||||
|     public void init(ServletConfig config) throws ServletException { | ||||
|         accountType = config.getInitParameter("type"); | ||||
|     } | ||||
| 
 | ||||
|     public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { | ||||
|         PrintWriter writer = response.getWriter(); | ||||
|         writer.println("<html>Hello, I am an AccountServlet!</html>"); | ||||
|         writer.flush(); | ||||
|     } | ||||
| 
 | ||||
|     public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { | ||||
|         double accountBalance = 1000d; | ||||
|         double interestRate = Double.parseDouble(request.getAttribute("interest").toString()); | ||||
| 
 | ||||
|         String paramDepositAmt = request.getParameter("dep"); | ||||
|         double depositAmt = Double.parseDouble(paramDepositAmt); | ||||
| 
 | ||||
|         accountBalance = accountBalance + depositAmt; | ||||
| 
 | ||||
|         PrintWriter writer = response.getWriter(); | ||||
|         writer.println("<html> Balance of " + accountType + " account is: " +  | ||||
|            accountBalance + "<br> This account bares an interest rate of " + interestRate +  | ||||
|            " % </html>"); | ||||
|         writer.flush(); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,17 @@ | ||||
| package com.baeldung.javaeeannotations; | ||||
| 
 | ||||
| import javax.servlet.ServletContextEvent; | ||||
| import javax.servlet.ServletContextListener; | ||||
| import javax.servlet.annotation.WebListener; | ||||
| 
 | ||||
| @WebListener | ||||
| public class BankAppServletContextListener implements ServletContextListener { | ||||
| 
 | ||||
|     public void contextInitialized(ServletContextEvent sce) {  | ||||
|         sce.getServletContext().setAttribute("ATTR_DEFAULT_LANGUAGE", "english");  | ||||
|     }  | ||||
|      | ||||
|     public void contextDestroyed(ServletContextEvent sce) {  | ||||
|         System.out.println("CONTEXT DESTROYED");  | ||||
|     }  | ||||
| } | ||||
| @ -0,0 +1,36 @@ | ||||
| package com.baeldung.javaeeannotations; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import javax.servlet.FilterChain; | ||||
| import javax.servlet.FilterConfig; | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.ServletRequest; | ||||
| import javax.servlet.ServletResponse; | ||||
| import javax.servlet.annotation.WebFilter; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| 
 | ||||
| @WebFilter( | ||||
|   urlPatterns = "/bankAccount/*", | ||||
|   filterName = "LoggingFilter", | ||||
|   description = "Filter all account transaction URLs" | ||||
|   ) | ||||
| public class LoggingFilter implements javax.servlet.Filter { | ||||
|     @Override | ||||
|     public void init(FilterConfig filterConfig) throws ServletException { | ||||
|     } | ||||
| 
 | ||||
|     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { | ||||
|         HttpServletRequest req = (HttpServletRequest) request; | ||||
|         HttpServletResponse res = (HttpServletResponse) response; | ||||
| 
 | ||||
|         res.sendRedirect(req.getContextPath() + "/login.jsp"); | ||||
|         chain.doFilter(request, response); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void destroy() { | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,29 @@ | ||||
| package com.baeldung.javaeeannotations; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.annotation.MultipartConfig; | ||||
| import javax.servlet.annotation.WebServlet; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import javax.servlet.http.Part; | ||||
| 
 | ||||
| @WebServlet(urlPatterns = { "/uploadCustDocs" }) | ||||
| @MultipartConfig( | ||||
|   fileSizeThreshold = 1024 * 1024 * 20, | ||||
|   maxFileSize = 1024 * 1024 * 20, | ||||
|   maxRequestSize = 1024 * 1024 * 25, | ||||
|   location = "D:/custDocs" | ||||
|   ) | ||||
| public class UploadCustomerDocumentsServlet extends HttpServlet { | ||||
| 
 | ||||
|     protected void doPost( | ||||
|      HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||||
|         for (Part part : request.getParts()) { | ||||
|             part.write("myFile"); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
							
								
								
									
										11
									
								
								jee7/src/main/webapp/WEB-INF/web.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								jee7/src/main/webapp/WEB-INF/web.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" | ||||
|          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee | ||||
|                              http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> | ||||
| 
 | ||||
|     <login-config> | ||||
|         <auth-method>BASIC</auth-method> | ||||
|         <realm-name>default</realm-name> | ||||
|     </login-config> | ||||
| 
 | ||||
| </web-app> | ||||
							
								
								
									
										16
									
								
								jee7/src/main/webapp/index.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								jee7/src/main/webapp/index.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||
|     pageEncoding="ISO-8859-1"%> | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||
| <title>My Account</title> | ||||
| </head> | ||||
| <body> | ||||
| <form action="account" method="post"> | ||||
|         Width: <input type="text" size="5" name="dep"/>  | ||||
|            | ||||
|         <input type="submit" value="Deposit" /> | ||||
| </form> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										12
									
								
								jee7/src/main/webapp/login.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								jee7/src/main/webapp/login.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||
|     pageEncoding="ISO-8859-1"%> | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||
| <title>Login</title> | ||||
| </head> | ||||
| <body> | ||||
| Login Here... | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										16
									
								
								jee7/src/main/webapp/upload.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								jee7/src/main/webapp/upload.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| <%@ page language="java" contentType="text/html; charset=ISO-8859-1" | ||||
|     pageEncoding="ISO-8859-1"%> | ||||
| <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> | ||||
| <html> | ||||
| <head> | ||||
| <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> | ||||
| <title>Insert title here</title> | ||||
| </head> | ||||
| <body> | ||||
| <form action="uploadCustDocs" method="post" enctype="multipart/form-data"> | ||||
| <input type="file" name="file" size="50" /> | ||||
| <br /> | ||||
| <input type="submit" value="Upload File" /> | ||||
| </form> | ||||
| </body> | ||||
| </html> | ||||
							
								
								
									
										3
									
								
								kotlin/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								kotlin/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Introduction to the Kotlin Language](http://www.baeldung.com/kotlin) | ||||
| @ -97,7 +97,6 @@ | ||||
| 		<commons-dbcp2.version>2.1.1</commons-dbcp2.version> | ||||
| 		<log4j-core.version>2.7</log4j-core.version> | ||||
| 		<junit.version>4.12</junit.version> | ||||
|          | ||||
| 		<maven-compiler-plugin.version>3.6.0</maven-compiler-plugin.version> | ||||
| 		<maven-surefire-plugin.version>2.19.1</maven-surefire-plugin.version> | ||||
| 	</properties> | ||||
|  | ||||
| @ -1,32 +0,0 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.apache.logging.log4j.junit.LoggerContextRule; | ||||
| import org.junit.Rule; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| 
 | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class AsyncFileAppenderUsingJsonLayoutTest { | ||||
|     @Rule | ||||
|     public LoggerContextRule contextRule = | ||||
|       new LoggerContextRule("log4j2-async-file-appender_json-layout.xml"); | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithAsyncConfig_shouldLogToJsonFile() | ||||
|       throws Exception { | ||||
|         Logger logger = contextRule.getLogger(getClass().getSimpleName()); | ||||
|         final int count = 88; | ||||
|         for (int i = 0; i < count; i++) { | ||||
|             logger.info("This is async JSON message #{} at INFO level.", count); | ||||
|         } | ||||
|         long logEventsCount = Files.lines(Paths.get("target/logfile.json")).count(); | ||||
|         assertTrue(logEventsCount > 0 && logEventsCount <= count); | ||||
|     } | ||||
| } | ||||
| @ -1,21 +0,0 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class ConsoleAppenderUsingDefaultLayoutTest { | ||||
|     @Test | ||||
|     public void givenLoggerWithDefaultConfig_shouldLogToConsole() | ||||
|       throws Exception { | ||||
|         Logger logger = LogManager.getLogger(getClass()); | ||||
|         Exception e = new RuntimeException("This is only a test!"); | ||||
|         logger.info("This is a simple message at INFO level. " + | ||||
|           "It will be hidden."); | ||||
|         logger.error("This is a simple message at ERROR level. " + | ||||
|           "This is the minimum visible level.", e); | ||||
|     } | ||||
| } | ||||
| @ -1,51 +0,0 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.apache.logging.log4j.Marker; | ||||
| import org.apache.logging.log4j.MarkerManager; | ||||
| import org.apache.logging.log4j.ThreadContext; | ||||
| import org.apache.logging.log4j.junit.LoggerContextRule; | ||||
| import org.junit.Rule; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class ConsoleAppenderUsingPatternLayoutWithColorsTest { | ||||
|     @Rule | ||||
|     public LoggerContextRule contextRule = | ||||
|       new LoggerContextRule("log4j2-console-appender_pattern-layout.xml"); | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithConsoleConfig_shouldLogToConsoleInColors() | ||||
|       throws Exception { | ||||
|         Logger logger = contextRule.getLogger(getClass().getSimpleName()); | ||||
|         logger.trace("This is a colored message at TRACE level."); | ||||
|         logger.debug("This is a colored message at DEBUG level. " + | ||||
|           "This is the minimum visible level."); | ||||
|         logger.info("This is a colored message at INFO level."); | ||||
|         logger.warn("This is a colored message at WARN level."); | ||||
|         Exception e = new RuntimeException("This is only a test!"); | ||||
|         logger.error("This is a colored message at ERROR level.", e); | ||||
|         logger.fatal("This is a colored message at FATAL level."); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithConsoleConfig_shouldFilterByMarker() throws Exception { | ||||
|         Logger logger = contextRule.getLogger("ConnTrace"); | ||||
|         Marker appError = MarkerManager.getMarker("APP_ERROR"); | ||||
|         logger.error(appError, "This marker message at ERROR level should be hidden."); | ||||
|         Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE"); | ||||
|         logger.trace(connectionTrace, "This is a marker message at TRACE level."); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithConsoleConfig_shouldFilterByThreadContext() throws Exception { | ||||
|         Logger logger = contextRule.getLogger("UserAudit"); | ||||
|         ThreadContext.put("userId", "1000"); | ||||
|         logger.info("This is a log-visible user login. Maybe from an admin account?"); | ||||
|         ThreadContext.put("userId", "1001"); | ||||
|         logger.info("This is a log-invisible user login."); | ||||
|         boolean b = true; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,122 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| import java.sql.Connection; | ||||
| import java.sql.ResultSet; | ||||
| 
 | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.apache.logging.log4j.Marker; | ||||
| import org.apache.logging.log4j.MarkerManager; | ||||
| import org.apache.logging.log4j.ThreadContext; | ||||
| import org.junit.BeforeClass; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| import com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class CustomLoggingTest { | ||||
| 
 | ||||
|     @BeforeClass | ||||
|     public static void setup() throws Exception { | ||||
|         Connection connection = ConnectionFactory.getConnection(); | ||||
|         connection.createStatement() | ||||
|           .execute("CREATE TABLE logs(" + "when TIMESTAMP," + "logger VARCHAR(255)," + "level VARCHAR(255)," + "message VARCHAR(4096)," + "throwable TEXT)"); | ||||
|         connection.commit(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithDefaultConfig_shouldLogToConsole() throws Exception { | ||||
|         Logger logger = LogManager.getLogger(getClass()); | ||||
|         Exception e = new RuntimeException("This is only a test!"); | ||||
|         logger.info("This is a simple message at INFO level. " + "It will be hidden."); | ||||
|         logger.error("This is a simple message at ERROR level. " + "This is the minimum visible level.", e); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithConsoleConfig_shouldLogToConsoleInColors() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER"); | ||||
|         logger.trace("This is a colored message at TRACE level."); | ||||
|         logger.debug("This is a colored message at DEBUG level. " + "This is the minimum visible level."); | ||||
|         logger.info("This is a colored message at INFO level."); | ||||
|         logger.warn("This is a colored message at WARN level."); | ||||
|         Exception e = new RuntimeException("This is only a test!"); | ||||
|         logger.error("This is a colored message at ERROR level.", e); | ||||
|         logger.fatal("This is a colored message at FATAL level."); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithConsoleConfig_shouldFilterByMarker() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER"); | ||||
|         Marker appError = MarkerManager.getMarker("APP_ERROR"); | ||||
|         logger.error(appError, "This marker message at ERROR level should be hidden."); | ||||
|         Marker connectionTrace = MarkerManager.getMarker("CONN_TRACE"); | ||||
|         logger.trace(connectionTrace, "This is a marker message at TRACE level."); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithConsoleConfig_shouldFilterByThreadContext() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT"); | ||||
|         ThreadContext.put("userId", "1000"); | ||||
|         logger.info("This is a log-visible user login. Maybe from an admin account?"); | ||||
|         ThreadContext.put("userId", "1001"); | ||||
|         logger.info("This is a log-invisible user login."); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithAsyncConfig_shouldLogToJsonFile() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("ASYNC_JSON_FILE_APPENDER"); | ||||
|         final int count = 88; | ||||
|         for (int i = 0; i < count; i++) { | ||||
|             logger.info("This is async JSON message #{} at INFO level.", count); | ||||
|         } | ||||
|         long logEventsCount = Files.lines(Paths.get("target/logfile.json")) | ||||
|                 .count(); | ||||
|         assertTrue(logEventsCount > 0 && logEventsCount <= count); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithFailoverConfig_shouldLog() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("FAIL_OVER_SYSLOG_APPENDER"); | ||||
|         logger.trace("This is a syslog message at TRACE level."); | ||||
|         logger.debug("This is a syslog message at DEBUG level."); | ||||
|         logger.info("This is a syslog message at INFO level. This is the minimum visible level."); | ||||
|         logger.warn("This is a syslog message at WARN level."); | ||||
|         Exception e = new RuntimeException("This is only a test!"); | ||||
|         logger.error("This is a syslog message at ERROR level.", e); | ||||
|         logger.fatal("This is a syslog message at FATAL level."); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithJdbcConfig_shouldLogToDataSource() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("JDBC_APPENDER"); | ||||
|         final int count = 88; | ||||
|         for (int i = 0; i < count; i++) { | ||||
|             logger.info("This is JDBC message #{} at INFO level.", count); | ||||
|         } | ||||
|         Connection connection = ConnectionFactory.getConnection(); | ||||
|         ResultSet resultSet = connection.createStatement() | ||||
|                 .executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs"); | ||||
|         int logCount = 0; | ||||
|         if (resultSet.next()) { | ||||
|             logCount = resultSet.getInt("ROW_COUNT"); | ||||
|         } | ||||
|         assertTrue(logCount == count); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithRollingFileConfig_shouldLogToXMLFile() throws Exception { | ||||
|         Logger logger = LogManager.getLogger("XML_ROLLING_FILE_APPENDER"); | ||||
|         final int count = 88; | ||||
|         for (int i = 0; i < count; i++) { | ||||
|             logger.info("This is rolling file XML message #{} at INFO level.", i); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -1,27 +0,0 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.apache.logging.log4j.junit.LoggerContextRule; | ||||
| import org.junit.Rule; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class FailoverSyslogConsoleAppenderTest { | ||||
|     @Rule | ||||
|     public LoggerContextRule contextRule =  | ||||
|       new LoggerContextRule("log4j2-failover-syslog-console-appender_pattern-layout.xml"); | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithFailoverConfig_shouldLog() throws Exception { | ||||
|         Logger logger = contextRule.getLogger(getClass().getSimpleName()); | ||||
|         logger.trace("This is a syslog message at TRACE level."); | ||||
|         logger.debug("This is a syslog message at DEBUG level."); | ||||
|         logger.info("This is a syslog message at INFO level. This is the minimum visible level."); | ||||
|         logger.warn("This is a syslog message at WARN level."); | ||||
|         Exception e = new RuntimeException("This is only a test!"); | ||||
|         logger.error("This is a syslog message at ERROR level.", e); | ||||
|         logger.fatal("This is a syslog message at FATAL level."); | ||||
|     } | ||||
| } | ||||
| @ -1,51 +0,0 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.apache.logging.log4j.junit.LoggerContextRule; | ||||
| import org.junit.BeforeClass; | ||||
| import org.junit.Rule; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.ResultSet; | ||||
| 
 | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class JDBCAppenderTest { | ||||
|     @Rule | ||||
|     public LoggerContextRule contextRule = new LoggerContextRule("log4j2-jdbc-appender.xml"); | ||||
| 
 | ||||
|     @BeforeClass | ||||
|     public static void setup() throws Exception { | ||||
|         Connection connection = ConnectionFactory.getConnection(); | ||||
|         connection.createStatement() | ||||
|           .execute("CREATE TABLE logs(" + | ||||
|             "when TIMESTAMP," + | ||||
|             "logger VARCHAR(255)," + | ||||
|             "level VARCHAR(255)," + | ||||
|             "message VARCHAR(4096)," + | ||||
|             "throwable TEXT)"); | ||||
|         //connection.commit(); | ||||
|     } | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithJdbcConfig_shouldLogToDataSource() throws Exception { | ||||
|         Logger logger = contextRule.getLogger(getClass().getSimpleName()); | ||||
|         final int count = 88; | ||||
|         for (int i = 0; i < count; i++) { | ||||
|             logger.info("This is JDBC message #{} at INFO level.", count); | ||||
|         } | ||||
|         Connection connection = ConnectionFactory.getConnection(); | ||||
|         ResultSet resultSet = connection.createStatement() | ||||
|           .executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs"); | ||||
|         int logCount = 0; | ||||
|         if (resultSet.next()) { | ||||
|             logCount = resultSet.getInt("ROW_COUNT"); | ||||
|         } | ||||
|         assertTrue(logCount == count); | ||||
|     } | ||||
| } | ||||
| @ -1,34 +0,0 @@ | ||||
| package com.baeldung.logging.log4j2.tests; | ||||
| 
 | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.apache.logging.log4j.junit.LoggerContextRule; | ||||
| import org.junit.Rule; | ||||
| import org.junit.Test; | ||||
| import org.junit.runner.RunWith; | ||||
| import org.junit.runners.JUnit4; | ||||
| 
 | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.stream.Collectors; | ||||
| 
 | ||||
| import static org.junit.Assert.assertTrue; | ||||
| 
 | ||||
| @RunWith(JUnit4.class) | ||||
| public class RollingFileAppenderUsingXMLLayoutTest { | ||||
|     @Rule | ||||
|     public LoggerContextRule contextRule = | ||||
|       new LoggerContextRule("log4j2-rolling-file-appender_xml-layout.xml"); | ||||
| 
 | ||||
|     @Test | ||||
|     public void givenLoggerWithRollingFileConfig_shouldLogToXMLFile() throws Exception { | ||||
|         Logger logger = contextRule.getLogger(getClass().getSimpleName()); | ||||
|         final int count = 88; | ||||
|         for (int i = 0; i < count; i++) { | ||||
|             logger.info("This is rolling file XML message #{} at INFO level.", i); | ||||
|         } | ||||
|         String[] logEvents = Files.readAllLines(Paths.get("target/logfile.xml")).stream() | ||||
|           .collect(Collectors.joining(System.lineSeparator())) | ||||
|           .split("\\n\\n+"); | ||||
|         assertTrue(logEvents.length == 39); | ||||
|     } | ||||
| } | ||||
| @ -1,17 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN"> | ||||
|     <Appenders> | ||||
|         <File name="JSONLogfileAppender" fileName="target/logfile.json"> | ||||
|             <JSONLayout compact="true" eventEol="true"/> | ||||
|             <BurstFilter level="INFO" rate="2" maxBurst="10"/> | ||||
|         </File> | ||||
|         <Async name="AsyncAppender" bufferSize="80"> | ||||
|             <AppenderRef ref="JSONLogfileAppender"/> | ||||
|         </Async> | ||||
|     </Appenders> | ||||
|     <Loggers> | ||||
|         <Root level="INFO"> | ||||
|             <AppenderRef ref="AsyncAppender"/> | ||||
|         </Root> | ||||
|     </Loggers> | ||||
| </Configuration> | ||||
| @ -1,27 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN" xmlns:xi="http://www.w3.org/2001/XInclude"> | ||||
|     <Appenders> | ||||
|         <xi:include href="log4j2-includes/console-appender_pattern-layout_colored.xml"/> | ||||
|         <Console name="ConsoleRedAppender" target="SYSTEM_OUT"> | ||||
|             <PatternLayout pattern="%style{%message}{red}%n"/> | ||||
|             <MarkerFilter marker="CONN_TRACE"/> | ||||
|         </Console> | ||||
|         <Console name="ConsoleGreenAppender" target="SYSTEM_OUT"> | ||||
|             <PatternLayout pattern="%style{userId=%X{userId}:}{white} %style{%message}{green}%n"/> | ||||
|         </Console> | ||||
|     </Appenders> | ||||
|     <Loggers> | ||||
|         <Logger name="ConnTrace" level="TRACE" additivity="false"> | ||||
|             <AppenderRef ref="ConsoleRedAppender"/> | ||||
|         </Logger> | ||||
|         <Logger name="UserAudit" level="INFO" additivity="false"> | ||||
|             <AppenderRef ref="ConsoleGreenAppender"/> | ||||
|             <ThreadContextMapFilter> | ||||
|                 <KeyValuePair key="userId" value="1000"/> | ||||
|             </ThreadContextMapFilter> | ||||
|         </Logger> | ||||
|         <Root level="DEBUG"> | ||||
|             <AppenderRef ref="ConsoleAppender"/> | ||||
|         </Root> | ||||
|     </Loggers> | ||||
| </Configuration> | ||||
| @ -1,20 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN" xmlns:xi="http://www.w3.org/2001/XInclude"> | ||||
|     <Appenders> | ||||
| 
 | ||||
|         <xi:include href="log4j2-includes/console-appender_pattern-layout_colored.xml"/> | ||||
| 
 | ||||
|         <Syslog name="Syslog" host="localhost" port="514" protocol="TCP" ignoreExceptions="false"/> | ||||
| 
 | ||||
|         <Failover name="FailoverAppender" primary="Syslog"> | ||||
|             <Failovers> | ||||
|                 <AppenderRef ref="ConsoleAppender"/> | ||||
|             </Failovers> | ||||
|         </Failover> | ||||
|     </Appenders> | ||||
|     <Loggers> | ||||
|         <Root level="TRACE"> | ||||
|             <AppenderRef ref="FailoverAppender"/> | ||||
|         </Root> | ||||
|     </Loggers> | ||||
| </Configuration> | ||||
| @ -1,4 +1,5 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Console name="ConsoleAppender" target="SYSTEM_OUT"> | ||||
|     <PatternLayout pattern="%style{%date{DEFAULT}}{yellow} [%style{%thread}{white}] %highlight{%-5level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green, DEBUG=cyan, TRACE=blue} %style{%logger{36}}{cyan}:%n[+] %message%n%throwable"/> | ||||
|     <PatternLayout | ||||
| 	  pattern="%style{%date{DEFAULT}}{yellow} [%style{%thread}{white}] %highlight{%-5level}{FATAL=bg_red, ERROR=red, WARN=yellow, INFO=green, DEBUG=cyan, TRACE=blue} %style{%logger{36}}{cyan}:%n[+] %message%n%throwable" /> | ||||
| </Console> | ||||
|  | ||||
| @ -1,19 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN"> | ||||
|     <Appenders> | ||||
|         <JDBC name="JDBCAppender" tableName="logs"> | ||||
|             <ConnectionFactory class="com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory" | ||||
|                                method="getConnection"/> | ||||
|             <Column name="when" isEventTimestamp="true"/> | ||||
|             <Column name="logger" pattern="%logger"/> | ||||
|             <Column name="level" pattern="%level"/> | ||||
|             <Column name="message" pattern="%message"/> | ||||
|             <Column name="throwable" pattern="%ex{full}"/> | ||||
|         </JDBC> | ||||
|     </Appenders> | ||||
|     <Loggers> | ||||
|         <Root level="trace"> | ||||
|             <AppenderRef ref="JDBCAppender"/> | ||||
|         </Root> | ||||
|     </Loggers> | ||||
| </Configuration> | ||||
| @ -1,18 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN"> | ||||
|     <Appenders> | ||||
|         <RollingFile name="XMLLogfileAppender" | ||||
|                      fileName="target/logfile.xml" | ||||
|                      filePattern="target/logfile-%d{yyyy-MM-dd}-%i.log.gz"> | ||||
|             <XMLLayout/> | ||||
|             <Policies> | ||||
|                 <SizeBasedTriggeringPolicy size="17 kB"/> | ||||
|             </Policies> | ||||
|         </RollingFile> | ||||
|     </Appenders> | ||||
|     <Loggers> | ||||
|         <Root level="TRACE"> | ||||
|             <AppenderRef ref="XMLLogfileAppender"/> | ||||
|         </Root> | ||||
|     </Loggers> | ||||
| </Configuration> | ||||
| @ -1,13 +1,69 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Configuration status="WARN"> | ||||
| <Configuration xmlns:xi="http://www.w3.org/2001/XInclude" status="WARN"> | ||||
|     <Appenders> | ||||
|         <xi:include href="log4j2-includes/console-appender_pattern-layout_colored.xml" /> | ||||
|         <Console name="ConsoleAppender" target="SYSTEM_OUT"> | ||||
|             <PatternLayout pattern="%d [%t] %-5level %logger{36} - %msg%n%throwable"/> | ||||
|             <PatternLayout pattern="%d [%t] %-5level %logger{36} - %msg%n%throwable" /> | ||||
|         </Console> | ||||
|         <Console name="ConsoleRedAppender" target="SYSTEM_OUT"> | ||||
|             <PatternLayout pattern="%style{%message}{red}%n" /> | ||||
|             <MarkerFilter marker="CONN_TRACE" /> | ||||
|         </Console> | ||||
|         <Console name="ConsoleGreenAppender" target="SYSTEM_OUT"> | ||||
|             <PatternLayout pattern="%style{userId=%X{userId}:}{white} %style{%message}{green}%n" /> | ||||
|         </Console> | ||||
|         <File name="JSONLogfileAppender" fileName="target/logfile.json"> | ||||
|             <JSONLayout compact="true" eventEol="true" /> | ||||
|             <BurstFilter level="INFO" rate="2" maxBurst="10" /> | ||||
|         </File> | ||||
|         <Async name="AsyncAppender" bufferSize="80"> | ||||
|             <AppenderRef ref="JSONLogfileAppender" /> | ||||
|         </Async> | ||||
|         <Syslog name="Syslog" format="RFC5424" host="localhost" port="514" protocol="TCP" facility="local3" connectTimeoutMillis="10000" reconnectionDelayMillis="5000" /> | ||||
|         <Failover name="FailoverAppender" primary="Syslog"> | ||||
|             <Failovers> | ||||
|                 <AppenderRef ref="ConsoleAppender" /> | ||||
|             </Failovers> | ||||
|         </Failover> | ||||
|         <JDBC name="JDBCAppender" tableName="logs"> | ||||
|             <ConnectionFactory class="com.baeldung.logging.log4j2.tests.jdbc.ConnectionFactory" method="getConnection" /> | ||||
|             <Column name="when" isEventTimestamp="true" /> | ||||
|             <Column name="logger" pattern="%logger" /> | ||||
|             <Column name="level" pattern="%level" /> | ||||
|             <Column name="message" pattern="%message" /> | ||||
|             <Column name="throwable" pattern="%ex{full}" /> | ||||
|         </JDBC> | ||||
|         <RollingFile name="XMLRollingfileAppender" fileName="target/logfile.xml" filePattern="target/logfile-%d{yyyy-MM-dd}-%i.log.gz"> | ||||
|             <XMLLayout /> | ||||
|             <Policies> | ||||
|                 <SizeBasedTriggeringPolicy size="17 kB" /> | ||||
|             </Policies> | ||||
|         </RollingFile> | ||||
|     </Appenders> | ||||
|     <Loggers> | ||||
|         <Root level="ERROR"> | ||||
|             <AppenderRef ref="ConsoleAppender"/> | ||||
|         <Logger name="CONSOLE_PATTERN_APPENDER_MARKER" level="TRACE" additivity="false"> | ||||
|             <AppenderRef ref="ConsoleRedAppender" /> | ||||
|         </Logger> | ||||
|         <Logger name="CONSOLE_PATTERN_APPENDER_THREAD_CONTEXT" level="INFO" additivity="false"> | ||||
|             <AppenderRef ref="ConsoleGreenAppender" /> | ||||
|             <ThreadContextMapFilter> | ||||
|                 <KeyValuePair key="userId" value="1000" /> | ||||
|             </ThreadContextMapFilter> | ||||
|         </Logger> | ||||
|         <Logger name="ASYNC_JSON_FILE_APPENDER" level="INFO" additivity="false"> | ||||
|             <AppenderRef ref="AsyncAppender" /> | ||||
|         </Logger> | ||||
|         <Logger name="FAIL_OVER_SYSLOG_APPENDER" level="INFO" additivity="false"> | ||||
|             <AppenderRef ref="FailoverAppender" /> | ||||
|         </Logger> | ||||
|         <Logger name="JDBC_APPENDER" level="INFO" additivity="false"> | ||||
|             <AppenderRef ref="JDBCAppender" /> | ||||
|         </Logger> | ||||
|         <Logger name="XML_ROLLING_FILE_APPENDER" level="INFO" additivity="false"> | ||||
|             <AppenderRef ref="XMLRollingfileAppender" /> | ||||
|         </Logger> | ||||
|         <Root level="DEBUG"> | ||||
|             <AppenderRef ref="ConsoleAppender" /> | ||||
|         </Root> | ||||
|     </Loggers> | ||||
| </Configuration> | ||||
							
								
								
									
										3
									
								
								metrics/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								metrics/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Intro to Dropwizard Metrics](http://www.baeldung.com/dropwizard-metrics) | ||||
| @ -1,2 +1,3 @@ | ||||
| ### Relevant Articles: | ||||
| - [PDF Conversions in Java](http://www.baeldung.com/pdf-conversions-java) | ||||
| - [Creating PDF Files in Java](http://www.baeldung.com/java-pdf-creation) | ||||
|  | ||||
							
								
								
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								pom.xml
									
									
									
									
									
								
							| @ -110,6 +110,7 @@ | ||||
|         <module>spring-autowire</module> | ||||
|         <module>spring-batch</module> | ||||
|         <module>spring-boot</module> | ||||
|         <module>spring-boot-servlet</module> | ||||
|         <module>spring-cloud-data-flow</module> | ||||
|         <module>spring-cloud</module> | ||||
|         <module>spring-core</module> | ||||
| @ -183,6 +184,7 @@ | ||||
|         <module>spring-reactor</module> | ||||
| 
 | ||||
|         <module>testing</module> | ||||
|         <module>testng</module> | ||||
| 
 | ||||
|         <module>video-tutorials</module> | ||||
| 
 | ||||
| @ -194,7 +196,7 @@ | ||||
| 
 | ||||
|         <module>struts2</module> | ||||
|         <module>apache-velocity</module> | ||||
| 
 | ||||
|         <module>apache-solrj</module> | ||||
| 
 | ||||
|     </modules> | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										4
									
								
								rxjava/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								rxjava/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Dealing with Backpressure with RxJava](http://www.baeldung.com/rxjava-backpressure) | ||||
| - [How to Test RxJava?](http://www.baeldung.com/rxjava-testing) | ||||
| @ -16,3 +16,5 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring | ||||
| - [Quick Guide to Spring Controllers](http://www.baeldung.com/spring-controllers) | ||||
| - [Quick Guide to Spring Bean Scopes](http://www.baeldung.com/spring-bean-scopes) | ||||
| - [Introduction To Ehcache](http://www.baeldung.com/ehcache) | ||||
| - [A Guide to the Spring Task Scheduler](http://www.baeldung.com/spring-task-scheduler) | ||||
| - [Guide to Spring Retry](http://www.baeldung.com/spring-retry) | ||||
|  | ||||
							
								
								
									
										3
									
								
								spring-amqp/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								spring-amqp/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| ## Relevant articles: | ||||
| 
 | ||||
| - [Messaging With Spring AMQP](http://www.baeldung.com/spring-amqp) | ||||
							
								
								
									
										4
									
								
								spring-boot-servlet/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								spring-boot-servlet/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| /target/ | ||||
| .settings/ | ||||
| .classpath | ||||
| .project | ||||
							
								
								
									
										2
									
								
								spring-boot-servlet/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								spring-boot-servlet/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| ###Relevant Articles: | ||||
| - [How to Register a Servlet in a Java Web Application](http://www.baeldung.com/how-to-register-a-servlet-in-a-java-web-application/) | ||||
							
								
								
									
										55
									
								
								spring-boot-servlet/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								spring-boot-servlet/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| <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-boot-servlet</artifactId> | ||||
|     <version>0.0.1-SNAPSHOT</version> | ||||
|     <packaging>war</packaging> | ||||
|     <name>spring-boot-servlet</name> | ||||
| 
 | ||||
|     <parent> | ||||
|         <groupId>org.springframework.boot</groupId> | ||||
|         <artifactId>spring-boot-dependencies</artifactId> | ||||
|         <version>1.5.1.RELEASE</version> | ||||
|     </parent> | ||||
| 
 | ||||
|     <dependencies> | ||||
|         <!-- Spring Boot Dependencies --> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-web</artifactId> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-tomcat</artifactId> | ||||
|             <scope>provided</scope> | ||||
|         </dependency> | ||||
|         <!-- Embedded EmbeddedTomcatExample Dependencies --> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.tomcat.embed</groupId> | ||||
|             <artifactId>tomcat-embed-core</artifactId> | ||||
|             <version>${tomcat.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.tomcat.embed</groupId> | ||||
|             <artifactId>tomcat-embed-jasper</artifactId> | ||||
|             <version>${tomcat.version}</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
| 
 | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <plugin> | ||||
|                 <groupId>org.springframework.boot</groupId> | ||||
|                 <artifactId>spring-boot-maven-plugin</artifactId> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| 
 | ||||
|     <properties> | ||||
|         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||
|         <java.version>1.8</java.version> | ||||
|         <tomcat.version>8.5.11</tomcat.version> | ||||
|     </properties> | ||||
| 
 | ||||
| </project> | ||||
							
								
								
									
										2
									
								
								spring-boot-servlet/src/main/java/META-INF/MANIFEST.MF
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								spring-boot-servlet/src/main/java/META-INF/MANIFEST.MF
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,2 @@ | ||||
| Manifest-Version: 1.0 | ||||
| Main-Class: com.baeldung.ApplicationMain | ||||
| @ -0,0 +1,19 @@ | ||||
| package com.baeldung; | ||||
| 
 | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.boot.builder.SpringApplicationBuilder; | ||||
| import org.springframework.boot.web.support.SpringBootServletInitializer; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| public class ApplicationMain extends SpringBootServletInitializer { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(ApplicationMain.class, args); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { | ||||
|         return application.sources(ApplicationMain.class); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,32 @@ | ||||
| package com.baeldung.configuration; | ||||
| 
 | ||||
| import org.springframework.web.WebApplicationInitializer; | ||||
| import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; | ||||
| import org.springframework.web.context.support.XmlWebApplicationContext; | ||||
| import org.springframework.web.servlet.DispatcherServlet; | ||||
| import javax.servlet.ServletContext; | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.ServletRegistration; | ||||
| 
 | ||||
| public class WebAppInitializer implements WebApplicationInitializer { | ||||
| 
 | ||||
|     public void onStartup(ServletContext container) throws ServletException { | ||||
| 
 | ||||
|         AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); | ||||
|         ctx.register(WebMvcConfigure.class); | ||||
|         ctx.setServletContext(container); | ||||
| 
 | ||||
|         ServletRegistration.Dynamic servletOne = container.addServlet("SpringProgrammaticDispatcherServlet", new DispatcherServlet(ctx)); | ||||
|         servletOne.setLoadOnStartup(1); | ||||
|         servletOne.addMapping("/"); | ||||
| 
 | ||||
|         XmlWebApplicationContext xctx = new XmlWebApplicationContext(); | ||||
|         xctx.setConfigLocation("/WEB-INF/context.xml"); | ||||
|         xctx.setServletContext(container); | ||||
| 
 | ||||
|         ServletRegistration.Dynamic servletTwo = container.addServlet("SpringProgrammaticXMLDispatcherServlet", new DispatcherServlet(xctx)); | ||||
|         servletTwo.setLoadOnStartup(1); | ||||
|         servletTwo.addMapping("/"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,40 @@ | ||||
| package com.baeldung.configuration; | ||||
| 
 | ||||
| import org.springframework.boot.web.support.ErrorPageFilter; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.web.servlet.ViewResolver; | ||||
| import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; | ||||
| import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | ||||
| import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; | ||||
| import org.springframework.web.servlet.resource.PathResourceResolver; | ||||
| import org.springframework.web.servlet.view.InternalResourceViewResolver; | ||||
| 
 | ||||
| @Configuration | ||||
| public class WebMvcConfigure extends WebMvcConfigurerAdapter { | ||||
| 
 | ||||
|     @Bean | ||||
|     public ViewResolver getViewResolver() { | ||||
|         InternalResourceViewResolver resolver = new InternalResourceViewResolver(); | ||||
|         resolver.setPrefix("/WEB-INF/"); | ||||
|         resolver.setSuffix(".jsp"); | ||||
|         return resolver; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { | ||||
|         configurer.enable(); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     @Override | ||||
|     public void addResourceHandlers(ResourceHandlerRegistry registry) { | ||||
|         registry.addResourceHandler("/resources/**").addResourceLocations("/resources/").setCachePeriod(3600).resourceChain(true).addResolver(new PathResourceResolver()); | ||||
|     } | ||||
| 
 | ||||
|     @Bean | ||||
|     public ErrorPageFilter errorPageFilter() { | ||||
|         return new ErrorPageFilter(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -0,0 +1,20 @@ | ||||
| package com.baeldung.props; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| 
 | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| public final class Constants { | ||||
| 
 | ||||
|     @Autowired | ||||
|     PropertySourcesLoader psl; | ||||
| 
 | ||||
|     public static final String breakLine = System.getProperty("line.separator"); | ||||
|     private static final PropertyLoader pl = new PropertyLoader(); | ||||
|     private static final Properties mainProps = pl.getProperties("custom.properties"); | ||||
|     public static final String DISPATCHER_SERVLET_NAME = mainProps.getProperty("dispatcher.servlet.name"); | ||||
|     public static final String DISPATCHER_SERVLET_MAPPING = mainProps.getProperty("dispatcher.servlet.mapping"); | ||||
|     private final String EXAMPLE_SERVLET_NAME = psl.getProperty("example.servlet.name"); | ||||
|     private final String EXAMPLE_SERVLET_MAPPING = psl.getProperty("example.servlet.mapping"); | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,27 @@ | ||||
| package com.baeldung.props; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.Properties; | ||||
| 
 | ||||
| public class PropertyLoader { | ||||
|     private static final Logger log = LoggerFactory.getLogger(PropertyLoader.class); | ||||
| 
 | ||||
|     public Properties getProperties(String file) { | ||||
|         Properties prop = new Properties(); | ||||
|         InputStream input = null; | ||||
|         try { | ||||
|             input = getClass().getResourceAsStream(file); | ||||
|             prop.load(input); | ||||
|             if (input != null) { | ||||
|                 input.close(); | ||||
|             } | ||||
|         } catch (IOException ex) { | ||||
|             log.error("IOException: " + ex); | ||||
|         } | ||||
|         return prop; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,23 @@ | ||||
| package com.baeldung.props; | ||||
| 
 | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.annotation.ComponentScan; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.context.annotation.PropertySource; | ||||
| import org.springframework.core.env.ConfigurableEnvironment; | ||||
| 
 | ||||
| @Configuration | ||||
| @ComponentScan(basePackages = { "com.baeldung.*" }) | ||||
| @PropertySource("classpath:custom.properties") public class PropertySourcesLoader { | ||||
| 
 | ||||
|     private static final Logger log = LoggerFactory.getLogger(PropertySourcesLoader.class); | ||||
| 
 | ||||
|     @Autowired | ||||
|     ConfigurableEnvironment env; | ||||
| 
 | ||||
|     public String getProperty(String key) { | ||||
|         return env.getProperty(key); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,18 @@ | ||||
| package com.baeldung.servlets; | ||||
| 
 | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| 
 | ||||
| public class GenericCustomServlet extends HttpServlet { | ||||
| 
 | ||||
|     @Override | ||||
|     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||||
|         response.setContentType("text/html"); | ||||
|         PrintWriter out = response.getWriter(); | ||||
|         out.println("<p>Hello World</p>"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package com.baeldung.servlets.javaee; | ||||
| 
 | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.annotation.WebServlet; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| @WebServlet(name = "AnnotationServlet", | ||||
|     description = "Example Servlet Using Annotations", | ||||
|     urlPatterns = { "/annotationservlet" }) | ||||
| public class AnnotationServlet extends HttpServlet { | ||||
|     private static final long serialVersionUID = 1L; | ||||
| 
 | ||||
|     @Override | ||||
|     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||||
|         request.getRequestDispatcher("/annotationservlet.jsp").forward(request, response); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,20 @@ | ||||
| package com.baeldung.servlets.javaee; | ||||
| 
 | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| 
 | ||||
| public class EEWebXmlServlet extends HttpServlet { | ||||
| 
 | ||||
|     private static final long serialVersionUID = 1L; | ||||
| 
 | ||||
|     @Override | ||||
|     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { | ||||
|         response.setContentType("text/html"); | ||||
|         PrintWriter out = response.getWriter(); | ||||
|         out.println("<p>Hello World</p>"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,19 @@ | ||||
| package com.baeldung.servlets.springboot; | ||||
| 
 | ||||
| import com.baeldung.servlets.GenericCustomServlet; | ||||
| import org.springframework.boot.web.servlet.ServletRegistrationBean; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| 
 | ||||
| @Configuration | ||||
| public class SpringRegistrationBeanServlet { | ||||
| 
 | ||||
|     @Bean | ||||
|     public ServletRegistrationBean genericCustomServlet() { | ||||
|         ServletRegistrationBean bean = new ServletRegistrationBean(new GenericCustomServlet(), "/springregistrationbeanservlet/*"); | ||||
|         bean.setLoadOnStartup(1); | ||||
|         return bean; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,16 @@ | ||||
| package com.baeldung.servlets.springboot.embedded; | ||||
| 
 | ||||
| import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; | ||||
| import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; | ||||
| import org.springframework.context.annotation.Bean; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| 
 | ||||
| @Configuration | ||||
| public class EmbeddedTomcatExample { | ||||
| 
 | ||||
|     @Bean | ||||
|     public EmbeddedServletContainerFactory servletContainer() { | ||||
|         TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory(); | ||||
|         return tomcat; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,10 @@ | ||||
| #Server Configuration | ||||
| #server.port=8080 | ||||
| #server.context-path=/javabootdata | ||||
| #Resource Handling | ||||
| #spring.resources.static-locations=classpath:/WEB-INF/resources | ||||
| #spring.mvc.view.prefix=/WEB-INF/ | ||||
| #spring.mvc.view.suffix=.jsp | ||||
| #spring.resources.cache-period=3600 | ||||
| servlet.name=dispatcherExample | ||||
| servlet.mapping=/dispatcherExampleURL | ||||
							
								
								
									
										4
									
								
								spring-boot-servlet/src/main/resources/custom.properties
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								spring-boot-servlet/src/main/resources/custom.properties
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| dispatcher.servlet.name=dispatcherExample | ||||
| dispatcher.servlet.mapping=/dispatcherExampleURL | ||||
| example.servlet.name=dispatcherExample | ||||
| example.servlet.mapping=/dispatcherExampleURL | ||||
							
								
								
									
										12
									
								
								spring-boot-servlet/src/main/webapp/WEB-INF/context.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								spring-boot-servlet/src/main/webapp/WEB-INF/context.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | ||||
| <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|        xmlns:context="http://www.springframework.org/schema/context" | ||||
|        xmlns="http://www.springframework.org/schema/beans" | ||||
|        xsi:schemaLocation="http://www.springframework.org/schema/beans | ||||
|                            http://www.springframework.org/schema/beans/spring-beans-4.3.xsd | ||||
|                            http://www.springframework.org/schema/context | ||||
|                            http://www.springframework.org/schema/context/spring-context-4.3.xsd"> | ||||
| 
 | ||||
|     <context:component-scan base-package="com.baeldung"/> | ||||
| 
 | ||||
|     <bean class="com.baeldung.configuration.WebAppInitializer"/> | ||||
| </beans> | ||||
							
								
								
									
										16
									
								
								spring-boot-servlet/src/main/webapp/WEB-INF/dispatcher.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								spring-boot-servlet/src/main/webapp/WEB-INF/dispatcher.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | ||||
| <beans xmlns:context="http://www.springframework.org/schema/context" | ||||
|        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|        xmlns="http://www.springframework.org/schema/beans" | ||||
|        xsi:schemaLocation=" | ||||
|    http://www.springframework.org/schema/beans | ||||
|    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd | ||||
|    http://www.springframework.org/schema/context | ||||
|    http://www.springframework.org/schema/context/spring-context-3.0.xsd"> | ||||
| 
 | ||||
|     <context:component-scan base-package="com.baeldung"/> | ||||
| 
 | ||||
|     <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> | ||||
|         <property name="prefix" value="/WEB-INF/jsp/"/> | ||||
|         <property name="suffix" value=".jsp"/> | ||||
|     </bean> | ||||
| </beans> | ||||
							
								
								
									
										40
									
								
								spring-boot-servlet/src/main/webapp/WEB-INF/web.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								spring-boot-servlet/src/main/webapp/WEB-INF/web.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" | ||||
|          xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" | ||||
|          id="WebApp_ID" version="3.1"> | ||||
|     <display-name>JSP</display-name> | ||||
|     <welcome-file-list> | ||||
|         <welcome-file>index.html</welcome-file> | ||||
|         <welcome-file>index.htm</welcome-file> | ||||
|         <welcome-file>index.jsp</welcome-file> | ||||
|     </welcome-file-list> | ||||
| 
 | ||||
|     <!-- Java EE Servlets --> | ||||
|     <servlet> | ||||
|         <servlet-name>EEWebXmlServlet</servlet-name> | ||||
|         <servlet-class>com.baeldung.servlets.javaee.EEWebXmlServlet</servlet-class> | ||||
|     </servlet> | ||||
| 
 | ||||
|     <servlet-mapping> | ||||
|         <servlet-name>EEWebXmlServlet</servlet-name> | ||||
|         <url-pattern>/eewebxmlservlet</url-pattern> | ||||
|     </servlet-mapping> | ||||
| 
 | ||||
|     <!-- Spring Boot Servlets --> | ||||
|     <servlet> | ||||
|         <servlet-name>SpringBootWebXmlServlet</servlet-name> | ||||
|         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | ||||
|         <init-param> | ||||
|             <param-name>contextConfigLocation</param-name> | ||||
|             <param-value>/WEB-INF/dispatcher.xml</param-value> | ||||
|         </init-param> | ||||
|         <load-on-startup>1</load-on-startup> | ||||
|     </servlet> | ||||
| 
 | ||||
|     <servlet-mapping> | ||||
|         <servlet-name>SpringBootWebXmlServlet</servlet-name> | ||||
|         <url-pattern>/</url-pattern> | ||||
|     </servlet-mapping> | ||||
| </web-app> | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1 @@ | ||||
| <p>Annotation Servlet!</p> | ||||
							
								
								
									
										1
									
								
								spring-boot-servlet/src/main/webapp/index.jsp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								spring-boot-servlet/src/main/webapp/index.jsp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| <p>Hello!</p> | ||||
| @ -7,3 +7,6 @@ The "REST With Spring" Classes: http://bit.ly/restwithspring | ||||
| - [A Guide to Spring in Eclipse STS](http://www.baeldung.com/eclipse-sts-spring) | ||||
| - [Introduction to WebJars](http://www.baeldung.com/maven-webjars) | ||||
| - [Create a Fat Jar App with Spring Boot](http://www.baeldung.com/deployable-fat-jar-spring-boot) | ||||
| - [The @ServletComponentScan Annotation in Spring Boot](http://www.baeldung.com/spring-servletcomponentscan) | ||||
| - [A Custom Data Binder in Spring MVC](http://www.baeldung.com/spring-mvc-custom-data-binder) | ||||
| - [Intro to Building an Application with Spring Boot](http://www.baeldung.com/intro-to-spring-boot) | ||||
|  | ||||
| @ -0,0 +1,41 @@ | ||||
| package com.baeldung.utils; | ||||
| 
 | ||||
| import org.junit.Before; | ||||
| import org.junit.Test; | ||||
| import org.mockito.InjectMocks; | ||||
| import org.mockito.MockitoAnnotations; | ||||
| import org.springframework.test.web.servlet.MockMvc; | ||||
| import org.springframework.test.web.servlet.setup.MockMvcBuilders; | ||||
| 
 | ||||
| import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; | ||||
| import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; | ||||
| 
 | ||||
| 
 | ||||
| import com.baeldung.utils.controller.UtilsController; | ||||
| 
 | ||||
| public class UtilsControllerTest { | ||||
| 
 | ||||
| 	@InjectMocks | ||||
|     private UtilsController utilsController; | ||||
| 	 | ||||
|     private MockMvc mockMvc; | ||||
|      | ||||
|     @Before | ||||
|     public void setup() { | ||||
|         MockitoAnnotations.initMocks(this); | ||||
|         this.mockMvc = MockMvcBuilders.standaloneSetup(utilsController) | ||||
|                 .build(); | ||||
| 
 | ||||
|     } | ||||
|    | ||||
|     @Test | ||||
|     public void givenParameter_setRequestParam_andSetSessionAttribute() throws Exception { | ||||
|     	String param = "testparam"; | ||||
|     	this.mockMvc.perform( | ||||
| 				post("/setParam") | ||||
| 					.param("param", param) | ||||
|                     .sessionAttr("parameter", param)) | ||||
| 				.andExpect(status().isOk()); | ||||
|     } | ||||
| 	 | ||||
| } | ||||
| @ -1,69 +0,0 @@ | ||||
| package com.baeldung.spring.cloud.bootstrap.gateway; | ||||
| 
 | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.springframework.boot.test.web.client.TestRestTemplate; | ||||
| import org.springframework.http.*; | ||||
| import org.springframework.util.LinkedMultiValueMap; | ||||
| import org.springframework.util.MultiValueMap; | ||||
| 
 | ||||
| public class GatewayApplicationLiveTest { | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAccess() throws Exception { | ||||
|         TestRestTemplate testRestTemplate = new TestRestTemplate(); | ||||
|         String testUrl = "http://localhost:8080"; | ||||
| 
 | ||||
|         ResponseEntity<String> response = testRestTemplate.getForEntity(testUrl + "/book-service/books", String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|         Assert.assertNotNull(response.getBody()); | ||||
| 
 | ||||
|         //try the protected resource and confirm the redirect to login | ||||
|         response = testRestTemplate.getForEntity(testUrl + "/book-service/books/1", String.class); | ||||
|         Assert.assertEquals(HttpStatus.FOUND, response.getStatusCode()); | ||||
|         Assert.assertEquals("http://localhost:8080/login", response.getHeaders().get("Location").get(0)); | ||||
| 
 | ||||
|         //login as user/password | ||||
|         MultiValueMap<String, String> form = new LinkedMultiValueMap<>(); | ||||
|         form.add("username", "user"); | ||||
|         form.add("password", "password"); | ||||
|         response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class); | ||||
| 
 | ||||
|         //extract the session from the cookie and propagate it to the next request | ||||
|         String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0]; | ||||
|         HttpHeaders headers = new HttpHeaders(); | ||||
|         headers.add("Cookie", sessionCookie); | ||||
|         HttpEntity<String> httpEntity = new HttpEntity<>(headers); | ||||
| 
 | ||||
|         //request the protected resource | ||||
|         response = testRestTemplate.exchange(testUrl + "/book-service/books/1", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|         Assert.assertNotNull(response.getBody()); | ||||
| 
 | ||||
|         //request the admin protected resource to determine it is still protected | ||||
|         response = testRestTemplate.exchange(testUrl + "/rating-service/ratings/all", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode()); | ||||
| 
 | ||||
|         //login as the admin | ||||
|         form.clear(); | ||||
|         form.add("username", "admin"); | ||||
|         form.add("password", "admin"); | ||||
|         response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class); | ||||
| 
 | ||||
|         //extract the session from the cookie and propagate it to the next request | ||||
|         sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0]; | ||||
|         headers = new HttpHeaders(); | ||||
|         headers.add("Cookie", sessionCookie); | ||||
|         httpEntity = new HttpEntity<>(headers); | ||||
| 
 | ||||
|         //request the protected resource | ||||
|         response = testRestTemplate.exchange(testUrl + "/rating-service/ratings/all", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|         Assert.assertNotNull(response.getBody()); | ||||
| 
 | ||||
|         //request the discovery resources as the admin | ||||
|         response = testRestTemplate.exchange(testUrl + "/discovery", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,201 @@ | ||||
| package com.baeldung.spring.cloud.bootstrap.gateway; | ||||
| 
 | ||||
| import com.fasterxml.jackson.annotation.JsonIgnoreProperties; | ||||
| import org.apache.http.entity.ContentType; | ||||
| import org.junit.Assert; | ||||
| import org.junit.Test; | ||||
| import org.springframework.boot.test.web.client.TestRestTemplate; | ||||
| import org.springframework.http.*; | ||||
| import org.springframework.util.LinkedMultiValueMap; | ||||
| import org.springframework.util.MultiValueMap; | ||||
| 
 | ||||
| public class IntegrationLiveTest { | ||||
| 
 | ||||
|     private TestRestTemplate testRestTemplate = new TestRestTemplate(); | ||||
|     private String testUrl = "http://localhost:8080"; | ||||
| 
 | ||||
|     @Test | ||||
|     public void testAccess() throws Exception { | ||||
|         ResponseEntity<String> response = testRestTemplate.getForEntity(testUrl + "/book-service/books", String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|         Assert.assertNotNull(response.getBody()); | ||||
| 
 | ||||
|         //try the protected resource and confirm the redirect to login | ||||
|         response = testRestTemplate.getForEntity(testUrl + "/book-service/books/1", String.class); | ||||
|         Assert.assertEquals(HttpStatus.FOUND, response.getStatusCode()); | ||||
|         Assert.assertEquals("http://localhost:8080/login", response.getHeaders().get("Location").get(0)); | ||||
| 
 | ||||
|         //login as user/password | ||||
|         MultiValueMap<String, String> form = new LinkedMultiValueMap<>(); | ||||
|         form.add("username", "user"); | ||||
|         form.add("password", "password"); | ||||
|         response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class); | ||||
| 
 | ||||
|         //extract the session from the cookie and propagate it to the next request | ||||
|         String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0]; | ||||
|         HttpHeaders headers = new HttpHeaders(); | ||||
|         headers.add("Cookie", sessionCookie); | ||||
|         HttpEntity<String> httpEntity = new HttpEntity<>(headers); | ||||
| 
 | ||||
|         addBook(); | ||||
| 
 | ||||
|         //request the protected resource | ||||
|         response = testRestTemplate.exchange(testUrl + "/book-service/books/1", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|         Assert.assertNotNull(response.getBody()); | ||||
| 
 | ||||
|         addRatings(); | ||||
| 
 | ||||
|         //request the admin protected resource to determine it is still protected | ||||
|         response = testRestTemplate.exchange(testUrl + "/rating-service/ratings", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.FORBIDDEN, response.getStatusCode()); | ||||
| 
 | ||||
|         //login as the admin | ||||
|         form.clear(); | ||||
|         form.add("username", "admin"); | ||||
|         form.add("password", "admin"); | ||||
|         response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class); | ||||
| 
 | ||||
|         //extract the session from the cookie and propagate it to the next request | ||||
|         sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0]; | ||||
|         headers = new HttpHeaders(); | ||||
|         headers.add("Cookie", sessionCookie); | ||||
|         httpEntity = new HttpEntity<>(headers); | ||||
| 
 | ||||
|         //request the protected resource | ||||
|         response = testRestTemplate.exchange(testUrl + "/rating-service/ratings", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|         Assert.assertNotNull(response.getBody()); | ||||
| 
 | ||||
|         //request the discovery resources as the admin | ||||
|         response = testRestTemplate.exchange(testUrl + "/discovery", HttpMethod.GET, httpEntity, String.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, response.getStatusCode()); | ||||
|     } | ||||
| 
 | ||||
|     private void addRatings() { | ||||
|         //login as user/password | ||||
|         MultiValueMap<String, String> form = new LinkedMultiValueMap<>(); | ||||
|         form.add("username", "user"); | ||||
|         form.add("password", "password"); | ||||
|         ResponseEntity<String> response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class); | ||||
| 
 | ||||
|         //extract the session from the cookie and propagate it to the next request | ||||
|         String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0]; | ||||
|         HttpHeaders headers = new HttpHeaders(); | ||||
|         headers.add("Cookie", sessionCookie); | ||||
|         headers.add("ContentType", ContentType.APPLICATION_JSON.getMimeType()); | ||||
|         Rating rating = new Rating(1L, 4); | ||||
| 
 | ||||
|         HttpEntity<Rating> httpEntity = new HttpEntity<>(rating, headers); | ||||
| 
 | ||||
|         //request the protected resource | ||||
|         ResponseEntity<Rating> bookResponse = testRestTemplate.postForEntity(testUrl + "/rating-service/ratings", httpEntity, Rating.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, bookResponse.getStatusCode()); | ||||
|         Assert.assertEquals(rating.getBookId(), bookResponse.getBody().getBookId()); | ||||
|         Assert.assertEquals(rating.getStars(), bookResponse.getBody().getStars()); | ||||
|     } | ||||
| 
 | ||||
|     private void addBook(){ | ||||
|         //login as user/password | ||||
|         MultiValueMap<String, String> form = new LinkedMultiValueMap<>(); | ||||
|         form.add("username", "admin"); | ||||
|         form.add("password", "admin"); | ||||
|         ResponseEntity<String> response = testRestTemplate.postForEntity(testUrl + "/login", form, String.class); | ||||
| 
 | ||||
|         //extract the session from the cookie and propagate it to the next request | ||||
|         String sessionCookie = response.getHeaders().get("Set-Cookie").get(0).split(";")[0]; | ||||
|         HttpHeaders headers = new HttpHeaders(); | ||||
|         headers.add("Cookie", sessionCookie); | ||||
|         headers.add("ContentType", ContentType.APPLICATION_JSON.getMimeType()); | ||||
|         Book book = new Book("Baeldung", "How to spring cloud"); | ||||
| 
 | ||||
|         HttpEntity<Book> httpEntity = new HttpEntity<>(book, headers); | ||||
| 
 | ||||
|         //request the protected resource | ||||
|         ResponseEntity<Book> bookResponse = testRestTemplate.postForEntity(testUrl + "/book-service/books", httpEntity, Book.class); | ||||
|         Assert.assertEquals(HttpStatus.OK, bookResponse.getStatusCode()); | ||||
|         Assert.assertEquals(book.getAuthor(), bookResponse.getBody().getAuthor()); | ||||
|         Assert.assertEquals(book.getTitle(), bookResponse.getBody().getTitle()); | ||||
|     } | ||||
| 
 | ||||
|     @JsonIgnoreProperties(ignoreUnknown = true) | ||||
|     public static class Book { | ||||
| 
 | ||||
|         private Long id; | ||||
|         private String author; | ||||
|         private String title; | ||||
| 
 | ||||
|         public Book() { | ||||
|         } | ||||
| 
 | ||||
|         public Book(String author, String title) { | ||||
|             this.author = author; | ||||
|             this.title = title; | ||||
|         } | ||||
| 
 | ||||
|         public String getAuthor() { | ||||
|             return author; | ||||
|         } | ||||
| 
 | ||||
|         public void setAuthor(String author) { | ||||
|             this.author = author; | ||||
|         } | ||||
| 
 | ||||
|         public String getTitle() { | ||||
|             return title; | ||||
|         } | ||||
| 
 | ||||
|         public void setTitle(String title) { | ||||
|             this.title = title; | ||||
|         } | ||||
| 
 | ||||
|         public Long getId() { | ||||
|             return id; | ||||
|         } | ||||
| 
 | ||||
|         public void setId(Long id) { | ||||
|             this.id = id; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     @JsonIgnoreProperties(ignoreUnknown = true) | ||||
|     public static class Rating { | ||||
|         private Long id; | ||||
|         private Long bookId; | ||||
|         private int stars; | ||||
| 
 | ||||
|         public Rating() { | ||||
|         } | ||||
| 
 | ||||
|         public Rating(Long bookId, int stars) { | ||||
|             this.bookId = bookId; | ||||
|             this.stars = stars; | ||||
|         } | ||||
| 
 | ||||
|         public Long getId() { | ||||
|             return id; | ||||
|         } | ||||
| 
 | ||||
|         public void setId(Long id) { | ||||
|             this.id = id; | ||||
|         } | ||||
| 
 | ||||
|         public Long getBookId() { | ||||
|             return bookId; | ||||
|         } | ||||
| 
 | ||||
|         public void setBookId(Long bookId) { | ||||
|             this.bookId = bookId; | ||||
|         } | ||||
| 
 | ||||
|         public int getStars() { | ||||
|             return stars; | ||||
|         } | ||||
| 
 | ||||
|         public void setStars(int stars) { | ||||
|             this.stars = stars; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -42,6 +42,17 @@ | ||||
|             <artifactId>spring-boot-starter-data-redis</artifactId> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-data-jpa</artifactId> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>com.h2database</groupId> | ||||
|             <artifactId>h2</artifactId> | ||||
|             <scope>runtime</scope> | ||||
|         </dependency> | ||||
| 
 | ||||
|         <dependency> | ||||
|             <groupId>org.springframework.boot</groupId> | ||||
|             <artifactId>spring-boot-starter-test</artifactId> | ||||
|  | ||||
| @ -3,35 +3,11 @@ package com.baeldung.spring.cloud.bootstrap.svcbook; | ||||
| import org.springframework.boot.SpringApplication; | ||||
| import org.springframework.boot.autoconfigure.SpringBootApplication; | ||||
| import org.springframework.cloud.netflix.eureka.EnableEurekaClient; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.bind.annotation.RequestMapping; | ||||
| import org.springframework.web.bind.annotation.RestController; | ||||
| 
 | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| 
 | ||||
| @SpringBootApplication | ||||
| @EnableEurekaClient | ||||
| @RestController | ||||
| @RequestMapping("/books") | ||||
| public class BookServiceApplication { | ||||
|     public static void main(String[] args) { | ||||
|         SpringApplication.run(BookServiceApplication.class, args); | ||||
|     } | ||||
| 
 | ||||
|     private List<Book> bookList = Arrays.asList( | ||||
|         new Book(1L, "Baeldung goes to the market", "Tim Schimandle"), | ||||
|         new Book(2L, "Baeldung goes to the park", "Slavisa") | ||||
|     ); | ||||
| 
 | ||||
|     @GetMapping("") | ||||
|     public List<Book> findAllBooks() { | ||||
|         return bookList; | ||||
|     } | ||||
| 
 | ||||
|     @GetMapping("/{bookId}") | ||||
|     public Book findBook(@PathVariable Long bookId) { | ||||
|         return bookList.stream().filter(b -> b.getId().equals(bookId)).findFirst().orElse(null); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,6 +2,7 @@ package com.baeldung.spring.cloud.bootstrap.svcbook; | ||||
| 
 | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.context.annotation.Configuration; | ||||
| import org.springframework.http.HttpMethod; | ||||
| 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; | ||||
| @ -22,8 +23,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { | ||||
|         http.httpBasic() | ||||
|             .disable() | ||||
|         .authorizeRequests() | ||||
|             .antMatchers("/books").permitAll() | ||||
|             .antMatchers("/books/*").hasAnyRole("USER", "ADMIN") | ||||
|             .antMatchers(HttpMethod.GET, "/books").permitAll() | ||||
|             .antMatchers(HttpMethod.GET, "/books/*").permitAll() | ||||
|             .antMatchers(HttpMethod.POST, "/books").hasRole("ADMIN") | ||||
|             .antMatchers(HttpMethod.PATCH, "/books/*").hasRole("ADMIN") | ||||
|             .antMatchers(HttpMethod.DELETE, "/books/*").hasRole("ADMIN") | ||||
|             .anyRequest().authenticated() | ||||
|             .and() | ||||
|         .csrf() | ||||
|  | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user