Spring Master Class - Course Guide: Master The Most Popular Java Framework in Six Easy Levels!
Spring Master Class - Course Guide: Master The Most Popular Java Framework in Six Easy Levels!
Cla ss - Co ur se
Guide
1. Congratulations
2. About in28Minutes
3. Troubleshooting Guide
4. Getting Started
on APIs, Web Services and Microservices with Spring, Spring Boot and
Spring Cloud.
About in28Minutes
What's that?
You need to get insight into the in28Minutes world to answer that.
What do we love?
Continuous Learning
Hands-on
Step By Step
Code on Github
Interview Guides
Building a connect
Socially Conscious
We love what we do
Troubleshooting Guide
We love all our 100,000 learners. We want to help you in every way
possible.
This 50 page troubleshooting guide and faq is our way of thanking you for
Recommended Versions
Installation
Video : [Link]
list=PLBBog2r6uMCSmMVTW_QmDLyASBvovyAO3
PDF
: [Link]
e-JavaEclipseAndMaven_v2.pdf
More Details : [Link]
Troubleshooting
A 50 page troubleshooting guide with more than 200 Errors and Questions
answered
Spring Master Class - Course
Overview
Github Repository :
[Link]
Unit Testing with Spring Framework Spring - Level 3 Project Folder on Github
Basic Web Application with Spring MVC Introduction Project Folder on Github
Spring Level 1 - First 10 Steps in
Spring
Step 2 : Understanding Tight Coupling using the Binary Search Algorithm Example
Set up an example of tight coupling with Binary Search and Bubble Sort Algorithm as
shown in the picture below.
package [Link].springin5steps;
In the previous steps - we wrote code to create objects of the bubble sort
algorithm and binary search. We also managed the dependencies. It would
be great actually if some framework can take control of creation of the
beans and autowiring the dependencies.
Notes
@Component
public class BinarySearchImpl {
@Autowired
private SortAlgorithm sortAlgorithm;
@Component
public class BubbleSortAlgorithm implements SortAlgorithm {
public int[] sort(int[] numbers) {
// Logic for Bubble Sort
return numbers;
}
}
Step 5 : What is happening in the background?
Enable debug logging and check what’s happening in the background.
/src/main/resources/[Link]
[Link] = debug
Spring does a Component scan on the parent package
“[Link].springin5steps” to find the components - classes
that have @Component on them.
It identifies components and dependencies
It identifies that BinarySearchImpl has a dependency SortAlgorithm
It identifies that SortAlgorithm does not have a dependency. So, it creates an
instance of it and autowires it into an instance of BinarySearchImpl
package [Link].springin5steps;
import [Link];
@Component
public class QuickSortAlgorithm implements SortAlgorithm {
public int[] sort(int[] numbers) {
// Logic for Quick Sort
return numbers;
} }
There are now two matching SortAlgorithm instances. Spring throws an exception
because it does not know which one to use.
package [Link].springin5steps;
import [Link];
import [Link];
@Component
@Primary
public class BubbleSortAlgorithm implements SortAlgorithm {
public int[] sort(int[] numbers) {
// Logic for Bubble Sort
return numbers;
}
}
Step 7 : Constructor and Setter Injection
Constructor Injection
Setter Injection
Step 8 : Spring Modules
Spring is built in a very modular way and this enables use to use specific modules
without using the other modules of Spring.
Spring has not really restricted itself to just the Spring framework and got
involved in a lot of wide variety of projects.
@Autowired
@Qualifier("bubble")
private SortAlgorithm sortAlgorithm;
@Component
@Qualifier("bubble")
public class BubbleSortAlgorithm implements SortAlgorithm {
@Component
@Qualifier("quick")
public class QuickSortAlgorithm implements SortAlgorithm {
Step 14 - Scope of a Bean - Prototype and Singleton
Step 15 - Complex scenarios with Scope of a Spring Bean - Mix of Prototype and
Singleton
package [Link];
import
[Link]
ctory;
import [Link];
import
[Link];
import [Link];
@Component
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public class JdbcConnection {
public JdbcConnection() {
[Link]("JDBC Connection");
}
}
package [Link];
import
[Link];
import [Link];
@Component
public class PersonDAO {
@Autowired
JdbcConnection jdbcConnection;
package [Link].springin5steps;
import [Link];
import [Link];
import [Link];
import
[Link]
n;
import [Link];
import
[Link]
O;
@SpringBootApplication
public class SpringIn5StepsScopeApplication
{
[Link]([Link]
s);
ApplicationContext applicationContext =
[Link]([Link],
args);
PersonDAO personDao =
[Link]([Link]);
PersonDAO personDao2 =
[Link]([Link]);
[Link]("{}", personDao);
[Link]("{}",
[Link]());
[Link]("{}", personDao2);
[Link]("{}",
[Link]());
}
}
Step 15B - Difference Between Spring Singleton and GOF Singleton
Step 16 - Using Component Scan to scan for beans
package [Link];
import
[Link];
import [Link];
@Component
public class ComponentDAO {
@Autowired
ComponentJdbcConnection jdbcConnection;
public void
setComponentJdbcConnection(ComponentJdbcConnection
jdbcConnection) {
[Link] = jdbcConnection;
}
}
package [Link];
import
[Link]
ctory;
import [Link];
import
[Link];
import [Link];
@Component
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ComponentJdbcConnection {
public ComponentJdbcConnection() {
[Link]("JDBC Connection");
}
}
package [Link].springin5steps;
import [Link];
import [Link];
import [Link];
import
[Link]
n;
import [Link];
import
[Link];
import
[Link];
@SpringBootApplication
@ComponentScan("[Link]
")
public class SpringIn5StepsComponentScanApplication {
[Link](SpringIn5StepsComponentScanApplicat
[Link]);
ApplicationContext applicationContext =
[Link](SpringIn5StepsComponentScanApplicatio
[Link], args);
ComponentDAO componentDAO =
[Link]([Link]);
[Link]("{}",
componentDAO);
}
}
Step 17 - Lifecycle of a Bean - @PostConstruct and @PreDestroy
[Link]
@PostConstruct
public void postConstruct() {
[Link]("postConstruct");
}
@PreDestroy
public void preDestroy() {
[Link]("preDestroy");
}
<dependency>
<groupId>[Link]</groupId>
<artifactId>[Link]</artifactId>
<version>1</version>
</dependency>
package [Link].springin5steps;
import [Link];
import [Link];
import [Link];
import
[Link]
n;
import [Link];
import
[Link]
siness;
@SpringBootApplication
public class SpringIn5StepsCdiApplication {
[Link]([Link])
;
ApplicationContext applicationContext =
[Link]([Link],
args);
SomeCdiBusiness business =
[Link]([Link]);
package [Link];
import [Link];
import [Link];
@Named
public class SomeCdiBusiness {
@Inject
SomeCdiDao someCdiDao;
public SomeCdiDao getSomeCDIDAO() {
return someCdiDao;
}
package [Link];
import [Link];
@Named
public class SomeCdiDao {
}
Step 19 - Removing Spring Boot in Basic Application
[Link]
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
package [Link].springin5steps;
import [Link];
import
[Link]
icationContext;
import
[Link];
import
[Link];
import
[Link]
archImpl;
@Configuration
@ComponentScan
public class SpringIn5StepsBasicApplication {
ApplicationContext applicationContext =
new
AnnotationConfigApplicationContext(SpringIn5StepsBasicAppli
[Link]);
Step 20 - Fixing minor stuff - Add Logback and Close Application Context
<dependency>
<groupId>[Link]</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
@Configuration
@ComponentScan
public class SpringIn5StepsBasicApplication {
try (AnnotationConfigApplicationContext
applicationContext =
new
AnnotationConfigApplicationContext(
[Link])) {
//No change in code
}
}
}
Same changes in
SpringIn5StepsCdiApplication
SpringIn5StepsComponentScanApplication
SpringIn5StepsScopeApplication
import
[Link];
import
[Link];
import
[Link]
Context;
import
[Link]
AO;
@Configuration
@ComponentScan
public class SpringIn5StepsXMLContextApplication {
public static void main(String[] args) {
try (ClassPathXmlApplicationContext
applicationContext = new ClassPathXmlApplicationContext(
"[Link]"))
{
XmlPersonDAO personDao =
[Link]([Link]);
[Link](personDao);
[Link]([Link]());
}
}
}
package [Link];
package [Link];
XmlJdbcConnection xmlJdbcConnection;
xsi:schemaLocation="[Link]
eans
[Link]
[Link]">
<bean id="xmlJdbcConnection"
class="[Link]
JdbcConnection">
</bean>
<bean id="xmlPersonDAO"
class="[Link]
PersonDAO">
<property name="xmlJdbcConnection"
ref="xmlJdbcConnection"/>
</bean>
</beans>
Step 23 - Mixing XML Context with Component Scan for Beans defined with
Annotations
public class SpringIn5StepsXMLContextApplication {
try (ClassPathXmlApplicationContext
applicationContext = new ClassPathXmlApplicationContext(
"[Link]"))
{
<context:component-scan base-
package="[Link]"/>
Step 24 - IOC Container vs Application Context vs Bean Factory
Step 25 - @Component vs @Service vs @Repository vs @Controller
@Repository
public class ComponentDAO {
@Service
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public class BinarySearchImpl {
@Service
@Qualifier("bubble")
public class BubbleSortAlgorithm implements SortAlgorithm {
@Service
@Qualifier("quick")
public class QuickSortAlgorithm implements SortAlgorithm {
@Repository
public class PersonDAO {
Step 26 - Read values from external properties file
package [Link].springin5steps;
import
[Link]
icationContext;
import
[Link];
import
[Link];
import
[Link];
import
[Link]
eExternalService;
@Configuration
@ComponentScan
//
@PropertySource("classpath:[Link]")
public class SpringIn5StepsPropertiesApplication {
try (AnnotationConfigApplicationContext
applicationContext = new
AnnotationConfigApplicationContext(
[Link])) {
SomeExternalService service =
[Link]([Link]);
[Link]([Link]());
}
}
}
package
[Link];
import [Link];
import [Link];
@Component
public class SomeExternalService {
@Value("${[Link]}")
private String url;
}
/src/main/resources/[Link]
[Link]=[Link]
Spring Level 3 - Unit Testing
with Spring Framework
Unit Testing with Spring Framework Spring - Level 3 Project Folder on Github
@RunWith([Link])
//@SpringBootTest
public class SpringIn5StepsBasicApplicationTests {
package [Link];
import [Link];
import [Link];
import
[Link];
import
[Link];
import
[Link];
import
[Link].springin5steps.SpringIn5Steps
BasicApplication;
@Test
public void testBasicScenario() {
xmlns:context="[Link]
t"
xsi:schemaLocation="[Link]
eans
[Link]
[Link]
[Link]
[Link]
[Link]">
<import
resource="classpath:[Link]"/>
</beans>
package [Link];
import [Link];
import [Link];
import
[Link];
import
[Link];
import
[Link];
@Test
public void testBasicScenario() {
}
Step 29 - Spring Unit Testing with Mockito
public class SomeCdiBusiness {
}
Add a new method
package [Link];
import [Link];
@Named
public class SomeCdiDao {
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@RunWith([Link])
public class SomeCdiBusinessTest {
// Inject Mock
@InjectMocks
SomeCdiBusiness business;
// Create Mock
@Mock
SomeCdiDao daoMock;
@Test
public void testBasicScenario() {
[Link]([Link]()).thenReturn(new int[] { 2, 4
});
assertEquals(4, [Link]());
}
@Test
public void testBasicScenario_NoElements() {
@Test
public void testBasicScenario_EqualElements() {
[Link]([Link]()).thenReturn(new int[] {
2,2});
assertEquals(2, [Link]());
}
<dependency>
<groupId>[Link]</groupId>
<artifactId>mockito-core</artifactId>
</dependency>
Spring Level 4 - Introduction To
Spring Boot
Features
Embedded Servers
Tomcat, Jetty or Undertow
Production-ready features
metrics and health checks
externalized configuration
[Link]
package
[Link].springbootin10steps;
import [Link];
import [Link];
import [Link];
import
[Link];
@RestController
public class BooksController {
@GetMapping("/books")
public List<Book> getAllBooks() {
return [Link](
new Book(1l, "Mastering
Spring 5.2", "Ranga Karanam"));
}
}
Step 5 : What is Spring Boot Auto Configuration?
Spring based applications have a lot of configuration. When we use Spring MVC, we
need to configure component scan, dispatcher servlet, a view resolver, web jars(for
delivering static content) among other things. When we use Hibernate/JPA, we
would need to configure a datasource, an entity manager factory, a transaction
manager among a host of other things. Spring Boot brings in new thought process
around this - Can we bring more intelligence into this? When a spring mvc jar is
added into an application, can we auto configure some beans automatically?
Step 7 : Spring Boot Starter Projects - Starter Web and Starter JPA
Starters are a set of convenient dependency descriptors that you can include in
your application. You get a one-stop-shop for all the Spring and related technology
that you need, without having to hunt through sample code and copy paste loads
of dependency descriptors. For example, if you want to get started using Spring
and JPA for database access, just include the spring-boot-starter-data-jpa
dependency in your project, and you are good to go.
Examples
application info, metrics, dump, beans, env, config properties, audit events,
heap dump, loggers, trace, health mappings and auto config.
Notes
import
[Link];
import [Link];
@Service
public class Business1 {
@Autowired
private Dao1 dao1;
package [Link];
import
[Link];
import [Link];
@Service
public class Business2 {
@Autowired
private Dao2 dao2;
package [Link];
import [Link];
@Repository
public class Dao1 {
package [Link];
import [Link];
@Repository
public class Dao2 {
}
Step 03 - Defining an @Before advice
public class SpringAopApplication implements
CommandLineRunner {
@Autowired
private Business1 business1;
@Autowired
private Business2 business2;
@Override
public void run(String... args) throws Exception {
[Link]([Link]());
[Link]([Link]());
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
//AOP
//Configuration
@Aspect
@Configuration
public class UseAccessAspect {
@Before("execution(*
[Link].*.*(..))")
public void before(JoinPoint joinPoint){
[Link](" Check for user access ");
[Link](" Allowed execution for {}",
joinPoint);
}
}
Step 04 - Understand AOP Terminology - Pointcut, Advice, Aspect, Join Point, Weaving
and Weaver
Step 05 - Using @After, @AfterReturning, @AfterThrowing advices
Step 06 - Using @Around advice to implement performance tracing
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
//AOP
//Configuration
@Aspect
@Configuration
public class AfterAopAspect {
private Logger logger =
[Link]([Link]());
@AfterReturning(value = "execution(*
[Link].*.*(..))",
returning = "result")
public void afterReturning(JoinPoint joinPoint,
Object result) {
[Link]("{} returned with value {}",
joinPoint, result);
}
@After(value = "execution(*
[Link].*.*(..))")
public void after(JoinPoint joinPoint) {
[Link]("after execution of {}",
joinPoint);
}
}
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
@Aspect
@Configuration
public class MethodExecutionCalculationAspect {
[Link]();
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
//AOP
//Configuration
@Aspect
@Configuration
public class UserAccessAspect {
import [Link];
@Pointcut("execution(*
[Link].*.*(..))")
public void dataLayerExecution(){}
@Pointcut("execution(*
[Link].*.*(..))")
public void businessLayerExecution(){}
@Around("[Link]
[Link]()")
public class AfterAopAspect
@AfterReturning(value =
"[Link]
[Link]()", returning = "result")
@After(value =
"[Link]
[Link]()")
@Before("[Link]
[Link]()")
Step 08 - Quick summary of other Pointcuts
Step 09 - Creating Custom Annotation and an Aspect for Tracking Time
package [Link];
import [Link];
@Pointcut("execution(*
[Link].*.*(..))")
public void dataLayerExecution(){}
@Pointcut("execution(*
[Link].*.*(..))")
public void businessLayerExecution(){}
@Pointcut("dataLayerExecution() &&
businessLayerExecution()")
public void allLayerExecution(){}
@Pointcut("bean(*dao*)")
public void beanContainingDao(){}
@Pointcut("within([Link]
[Link]..*)")
public void dataLayerExecutionWithWithin(){}
@Pointcut("@annotation([Link].s
[Link])")
public void trackTimeAnnotation(){}
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Target([Link])
@Retention([Link])
public @interface TrackTime {
@Aspect
@Configuration
public class MethodExecutionCalculationAspect {
@Around("[Link]
[Link]()")
public void around(ProceedingJoinPoint joinPoint)
throws Throwable {
@TrackTime
public String calculateSomething(){
@Repository
public class Dao1 {
@TrackTime
public String retrieveSomething(){
Spring Level 6 - Spring JDBC
and JPA
Notes
[Link]=true
Launching H2
URL - [Link]
Make sure to check the db url - jdbc:h2:mem:testdb
import [Link];
}
/src/main/java/com/in28minutes/database/databasedemo/jdbc/[Link]
package [Link];
import [Link];
import
[Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Repository
public class PersonJbdcDao {
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
PersonJbdcDao dao;
@Override
public void run(String... args) throws Exception {
[Link]("All users -> {}",
[Link]());
Modified
@Repository
public class PersonJbdcDao {
@Autowired
JdbcTemplate jdbcTemplate;
package [Link];
import [Link];
import
[Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Repository
public class PersonJbdcDao {
@Autowired
JdbcTemplate jdbcTemplate;
}
DatabaseDemoApplication
[Link]() });
}
[Link]([Link]("location"));
[Link]([Link]("birth_date"));
return person;
}
import [Link];
import [Link];
import [Link];
import [Link];
@Entity
public class Person {
@Id
@GeneratedValue
private int id;
}
Step 15 - Implementing findById JPA Repository Method
DatabaseDemoApplication renamed to SpringJdbcDemoApplication
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Repository
@Transactional
public class PersonJpaRepository {
[Link]-sql=true
/src/main/resources/[Link] - Comment Everything
/*
*/
JpaDemoApplication
package [Link];
import [Link];
import [Link];
import
[Link];
import [Link];
import [Link];
import
[Link]
n;
import
[Link]
ry;
@SpringBootApplication
public class JpaDemoApplication implements
CommandLineRunner {
@Autowired
PersonJpaRepository repository;
[Link]([Link], args);
}
@Override
public void run(String... args) throws Exception {
/*
[Link]("All users -> {}",
[Link]());
[Link]("Deleting 10002 -> No of Rows
Deleted - {}",
[Link](10002));
@Entity
@NamedQuery(name="find_all_persons", query="select p from
Person p")
public class Person
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@Repository
@Transactional
public class PersonJpaRepository {
}
Step 19 - Introduction to Spring Data JPA
JpaDemoApplication - comment out @SpringBootApplication
package [Link];
import
[Link];
import [Link];
import [Link];
@Repository
public interface PersonSpringDataRepository
extends
JpaRepository<Person, Integer>{
}
package [Link];
import [Link];
import [Link];
import [Link];
import
[Link];
import [Link];
import [Link];
import
[Link]
n;
import [Link];
import
[Link]
ngDataRepository;
@SpringBootApplication
public class SpringDataDemoApplication implements
CommandLineRunner {
@Autowired
PersonSpringDataRepository repository;
[Link]([Link],
args);
}
@Override
public void run(String... args) throws Exception {
[Link](10002);
Steps
Install MySQL and Setup Schema
Remove H2 dependency from [Link]
Add MySQL (or your database) dependency to [Link] ```xml
mysql mysql-connector-java
- Configure [Link]
```properties
[Link]-auto=none
[Link]=jdbc:mysql://localhost:3306/person_ex
ample
[Link]=personuser
[Link]=YOUR_PASSWORD
Restart the app and You are ready!
Spring Boot can setup the database for you using Hibernate
Things to note:
Spring Boot chooses a default value for you based on whether it thinks your
database is embedded (default create-drop) or not (default none).
[Link]-auto is the setting to perform
SchemaManagementTool actions automatically
none : No action will be performed.
create-only : Database creation will be generated.
drop : Database dropping will be generated.
create : Database dropping will be generated followed by database creation.
validate : Validate the database schema
update : Update the database schema
Reference
: [Link]
[Link]#configurations-hbmddl
[Link]
Data
=========================
AUTO-CONFIGURATION REPORT
=========================
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes
'[Link]',
'[Link]
aseType'; @ConditionalOnMissingClass did not find unwanted
class (OnClassCondition)
DataSourceTransactionManagerAutoConfiguration matched:
- @ConditionalOnClass found required classes
'[Link]',
'[Link]
';
@ConditionalOnMissingClass did not find unwanted class
(OnClassCondition)
H2ConsoleAutoConfiguration matched:
- @ConditionalOnClass found required class
'[Link]'; @ConditionalOnMissingClass
did not find unwanted class (OnClassCondition)
- found ConfigurableWebEnvironment
(OnWebApplicationCondition)
- @ConditionalOnProperty
([Link]=true) matched
(OnPropertyCondition)
JdbcTemplateAutoConfiguration matched:
- @ConditionalOnClass found required classes
'[Link]',
'[Link]';
@ConditionalOnMissingClass did not find unwanted class
(OnClassCondition)
- @ConditionalOnSingleCandidate (types:
[Link]; SearchStrategy: all) found a primary
bean from beans 'dataSource' (OnBeanCondition)
[Link]#jdb
cTemplate matched:
- @ConditionalOnMissingBean (types:
[Link];
SearchStrategy: all) did not find any beans
(OnBeanCondition)
Bonus Introduction Sections
Tip : This is one of the few steps where you copy code in! We would want
to ensure that you have a running web application without any mistakes.
You can run the project using Run as > Maven build > tomcat7:run.
\[Link]
<project xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
.0 [Link]
<modelVersion>4.0.0</modelVersion>
<groupId>com.in28minutes</groupId>
<artifactId>in28Minutes-first-webapp</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-
api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>[Link]</groupId>
<artifactId>maven-
compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<verbose>true</verbose>
<source>1.7</source>
<target>1.7</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>[Link]</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<contextReloadable>true</contextReloadable>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
\src\main\java\webapp\[Link]
package webapp;
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
/*
* Browser sends Http Request to Web Server
*
* Code in Web Server => Input:HttpRequest, Output:
HttpResponse
* JEE with Servlets
*
* Web Server responds with Http Response
*/
@WebServlet(urlPatterns = "/[Link]")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PrintWriter out = [Link]();
[Link]("<html>");
[Link]("<head>");
[Link]("<title>Yahoo!!!!!!!!
</title>");
[Link]("</head>");
[Link]("<body>");
[Link]("My First Servlet");
[Link]("</body>");
[Link]("</html>");
}
\src\main\webapp\WEB-INF\[Link]
<display-name>To do List</display-name>
<welcome-file-list>
<welcome-file>[Link]</welcome-file>
</welcome-file-list>
</web-app>
Java Platform, Enterprise Edition (Java EE) JEE6
Servlet is a Java programming language class used to extend the capabilities of servers
that host applications accessed by means of a request-response programming model.
Notes
<welcome-file-list>
<welcome-file>[Link]</welcome-file>
</welcome-file-list>
\src\main\java\webapp\[Link]
request
.getRequestDispatcher("/WEB-INF/views/[Link]")
.forward(request, response);
\src\main\webapp\WEB-INF\views\[Link]
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
My First JSP!!!
</body>
</html>
Notes
Passing a Request Parameter Name
\src\main\java\webapp\[Link]
[Link]("name",
[Link]("name"));
\src\main\webapp\WEB-INF\views\[Link]
[Link]("password",
[Link]("password"));
\src\main\webapp\WEB-INF\views\[Link]
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
request
.getRequestDispatcher("/WEB-INF/views/[Link]")
.forward(request, response);
}
\src\main\webapp\WEB-INF\views\[Link]
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
<form action="/[Link]" method="POST">
Name : <input type="text" /> <input
type="submit" />
</form>
</body>
</html>
\src\main\webapp\WEB-INF\views\[Link]
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
Welcome ${name}
</body>
</html>
\src\main\java\webapp\[Link]
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse
response)
throws IOException, ServletException {
[Link]("name",
[Link]("name"));
[Link]("/WEB-
INF/views/[Link]").forward(request, response);
}
\src\main\webapp\WEB-INF\views\[Link]
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
Welcome ${name}
</body>
</html>
}
\src\main\java\webapp\[Link]
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
String name = [Link]("name");
String password = [Link]("password");
if (isValidUser) {
[Link]("name", name);
[Link]("/WEB-
INF/views/[Link]")
.forward(request,
response);
} else {
[Link]("errorMessage",
"Invalid Credentials!!");
[Link]("/WEB-
INF/views/[Link]")
.forward(request,
response);
}
}
\src\main\webapp\WEB-INF\views\[Link]
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
<p><font color="red">${errorMessage}</font></p>
<form action="/[Link]" method="POST">
Name : <input name="name" type="text" />
Password : <input name="password" type="password" /> <input
type="submit" />
</form>
</body>
</html>
Useful Snippets
[Link]
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-
webmvc</artifactId>
<version>[Link]</version>
</dependency>
[Link]
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
[Link]
</servlet-class>
<init-param>
<param-
name>contextConfigLocation</param-name>
<param-value>/WEB-INF/todo-
[Link]</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/spring-mvc/*</url-pattern>
</servlet-mapping>
[Link]
<beans
xmlns="[Link]
xmlns:context="[Link]
t"
xmlns:mvc="[Link]
xmlns:xsi="[Link]
instance"
xsi:schemaLocation="[Link]
eans [Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]">
<context:component-scan base-
package="com.in28minutes"
/>
<mvc:annotation-driven />
</beans>
Flows:
Flow 1. Login Servlet -> GET -> [Link]
Flow 2. Login Servlet -> POST (Success) -> [Link]
Flow 3. Login Servlet -> POST (Failure) -> [Link] (with error message)
Files List
\src\main\webapp\WEB-INF\views\[Link] Deleted
\[Link] Deleted
\src\main\java\webapp\[Link] Deleted
\src\main\java\webapp\[Link] Deleted
\src\main\webapp\WEB-INF\views\[Link] Deleted
\src\main\webapp\WEB-INF\[Link] Deleted
/[Link] New
<project xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
.0 [Link]
<modelVersion>4.0.0</modelVersion>
<groupId>com.in28minutes</groupId>
<artifactId>in28Minutes-springmvc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-
api</artifactId>
<version>6.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-
webmvc</artifactId>
<version>[Link]</version>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>[Link]</groupId>
<artifactId>maven-
compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<verbose>true</verbose>
<source>1.8</source>
<target>1.8</target>
<showWarnings>true</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>[Link]</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<path>/</path>
<contextReloadable>true</contextReloadable>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
/src/main/java/com/in28minutes/jee/[Link] New
package [Link];
}
/src/main/java/com/in28minutes/jee/[Link] New
package [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
import [Link];
@WebServlet(urlPatterns = "/[Link]")
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
[Link]("/WEB-
INF/views/[Link]").forward(
request, response);
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
String name = [Link]("name");
String password =
[Link]("password");
boolean isValidUser =
[Link](name, password);
if (isValidUser) {
[Link]("name", name);
[Link]("/WEB-
INF/views/[Link]").forward(
request, response);
} else {
[Link]("errorMessage", "Invalid
Credentials!!");
[Link]("/WEB-
INF/views/[Link]").forward(
request, response);
}
}
}
/src/main/webapp/WEB-INF/[Link] New
<beans xmlns="[Link]
xmlns:context="[Link]
t"
xmlns:mvc="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
eans [Link]
[Link]
[Link]
[Link]
[Link]
[Link]
[Link]">
<context:component-scan base-package="com.in28minutes"
/>
<mvc:annotation-driven />
</beans>
/src/main/webapp/WEB-INF/views/[Link] New
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
<p><font color="red">${errorMessage}</font></p>
<form action="/[Link]" method="POST">
Name : <input name="name" type="text" /> Password :
<input name="password" type="password" /> <input
type="submit" />
</form>
</body>
</html>
/src/main/webapp/WEB-INF/views/[Link] New
<html>
<head>
<title>Yahoo!!</title>
</head>
<body>
Welcome ${name}
</body>
</html>
/src/main/webapp/WEB-INF/[Link] New
<web-app xmlns="[Link]
xmlns:xsi="[Link]
xsi:schemaLocation="[Link]
[Link]
version="3.0">
<display-name>To do List</display-name>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
[Link]
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/[Link]</param-
value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/spring-mvc/*</url-pattern>
</servlet-mapping>
</web-app>
#Snippets
package [Link];
import [Link];
import
[Link];
import
[Link];
@Controller
public class LoginController {
@RequestMapping(value = "/login")
@ResponseBody
public String sayHello() {
return "Hello World dummy";
}
}
package [Link];
import [Link];
import
[Link];
import
[Link];
@Controller
public class LoginController {
@RequestMapping(value = "/login", method =
[Link])
public String showLoginPage() {
return "login";
}
}
/src/main/webapp/WEB-INF/[Link] Modified
New Lines
<bean
class="[Link]
eViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Redirect to Login JSP
View Resolver in [Link]
Update LoginController
Remove @ResponseBody
More about View Resolver
Snippets
<bean
class="[Link]
ceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
/src/main/resources/[Link] New
[Link].Appender1=[Link]
[Link]=[Link]
out
[Link]=%-7p %d
[%t] %c %x - %m%n
/src/main/webapp/WEB-INF/views/[Link] Modified
New Lines
Welcome ${name}.
What we want to do:
Understand importance of DispatcherServlet.
Add Logging Framework Log4j to understand the flow much more.
/src/main/java/com/in28minutes/springmvc/login/[Link]
Modified
New Lines
/src/main/java/com/in28minutes/jee/[Link] Deleted
/src/main/java/com/in28minutes/jee/[Link] Deleted
/src/main/java/com/in28minutes/springmvc/login/[Link]
Deleted
/src/main/java/com/in28minutes/login/[Link] New
package [Link];
import [Link];
import [Link];
import
[Link];
import
[Link];
import
[Link];
import [Link];
@Controller
public class LoginController {
if () {
[Link]("errorMessage", "Invalid
Credentials");
return "login";
}
[Link]("name", name);
return "welcome";
}
}
/src/main/java/com/in28minutes/login/[Link] New
package [Link];
public class LoginService {
public boolean validateUser(String user, String
password) {
return [Link]("in28Minutes")
&& [Link]("dummy");
}
}
/src/main/webapp/WEB-INF/views/[Link] Modified
New Lines
<url-pattern>/</url-pattern>
/src/main/java/com/in28minutes/login/[Link] Modified
New Lines
import
[Link];
@Autowired
private LoginService loginService;
/src/main/java/com/in28minutes/login/[Link] Modified
New Lines
import [Link];
@Service
public class LoginService {
Become an expert on Spring Boot, APIs, Microservices and Full
Stack Development