# Spring MVC: Tutorial

This is a step-by-step instruction on how to create a Spring MVC web application. In order to follow it, you only need a Maven and JDK 18+. Starting from simple hello world, you will add more and more modules.
If you want to have more straight-forward experience following this instruction, you can use Powershell to create files and folders. To install Powershell, run winget install --id Microsoft.Powershell --source winget and launch it in your project's folder by typing pwsh in explorers address bar. In this tutorial Powershell is optional and you can ignore provided pwsh commands. You can create files and folders as you wish. If you want to execute Powershell command from CMD, use this: pwsh -c "your_pwsh_command".
Regarding data access there are different concepts: JDBC, ORM, JPA, Spring Data Access and different Spring modules: spring-jdbc, spring-orm, spring-data-jdbc, spring-data-jpa.

## Spring MVC

1. Create pom.xml:
2. Create src\main\webapp\WEB-INF\web.xml:
   * Copy from above and execute Get-Clipboard > ( New-Item src\main\webapp\WEB-INF\web.xml -force )
   * Namespaces can differ if you're using Spring < 6.
3. Create src\main\webapp\WEB-INF\dispatcher-servlet.xml:
   * gcb > src\main\webapp\WEB-INF\dispatcher-servlet.xml
4. Create src\main\java\springtinyweb\controller\Greeting.java:
   * gcb > ( ni src\main\java\springtinyweb\controller\Greeting.java -force )
5. Run your app: mvn clean jetty:run
6. Visit localhost:8080/raw in your browser, you'll see:
Encoding doesn't work, but this problem will go away when you'll choose a template engine for your View layer - proceed to #JSP or #Thymeleaf section.
To stop server, press CTRL + C. Similar steps can be found in defferent sources.

## JSP

1. Add ViewResolver bean to dispatcher-servlet.xml/<beans>:
   * If you'll uncomment viewNames property, this ViewResolver will be called only if view name you are returning from controller method ends with .jsp. If this is what you need, comment out suffix property.
2. Add this method to Greeting.java:
3. Create src\main\webapp\WEB-INF\jsp\greeting.jsp page:
   * gcb > ( ni src\main\webapp\WEB-INF\jsp\greeting.jsp -force )
4. Restart server and visit localhost:8080/jsp, you'll see:
To fix encoding issue you can add <%@page pageEncoding="UTF-8" %> as the first line of your .jsp file or you can change encoding globally by adding following lines to web.xml:

## Thymeleaf

Similar guides can be found in different sources.
1. In your pom.xml add this dependency:
2. Add this beans to your dispatcher-servlet.xml:
   * Comment out cacheable property or set it to true, and you will have to restart server every time you change your templates.
   * Uncomment viewNames property and Spring will use Thymeleaf only if view name you're returning in your controller ends with .html.
3. Create src\main\webapp\WEB-INF\thy\hello.html:
   * gcb > ( ni src\main\webapp\WEB-INF\thy\hello.html -force )
4. Add this method to Greeting.java:
5. mvn clean jetty:run and visit localhost:8080/thy.

## CSS

1. In your dispatcher-servler.xml/<beans> add this element:
2. Create src\main\webapp\resources\css\styles.css:
   * gcb > ( ni src\main\webapp\resources\css\styles.css -force )
3. Thymeleaf: to your hello.html/<html>/<head> add this element:
3. JSP: to your greeting.jsp/<html>/<head> add this element:
4. mvn clean jetty:run and visit your page.

## Spring Security

This section consists of four subsections, but you will need to follow only two of them - one way of configuration and one template engine.
Spring Security can be configured via Java code or XML files. First two steps are common for both flows, but then you should choose only one flow - XML or JAVA - and follow it only. XML flow is almost never used and probably should be ignored, but it's provided here as demonstration.
1. Add this property and dependencies to your pom.xml:
2. Add Spring Security filter chain to your web.xml/<web-app>:

### Java configuration

3. Create a src\main\java\springtinyweb\security\SecurityConfiguration.java:
   * gcb > ( ni src\main\java\springtinyweb\security\SecurityConfiguration.java -force )
   * This is a new API. You can find example of defining both of this security beans from Spring itself:;
   * Different way of java configuration can be found in book Mastering Spring, through overriding methods in WebSecurityConfigurerAdapter, which has been removed from API in Spring 6.

### XML configuration

3. To your web.xml/<web-app> add ContextLoaderListener:
4. Create src\main\webapp\WEB-INF\applicationContext.xml:
Now your application is protected and you can learn how to interact with Spring Security from View layer.

### Spring Security + Thymeleaf

At this point you should already have Spring Security and Thymeleaf both working, this section will show you how to call security layer from Thymeleaf templates.
1. Add this dependency to your pom.xml:
2. In your dispatcher-servlet.xml to the bean with the id="templateEngine" add this property:
3. In your hello.html/<html>/<body> add this line:
4. Visit this page, you will see:

### Spring Security + JSP

At this point you should already have Spring Security and JSP both working, this section will show you how to call security layer from view layer.
1. Add this dependency to your pom.xml:
2. Add this line as the first line in greeting.jsp:
and this line to the <html>/<body>:
   * First line will result in exception being thrown if you will open this page not being logged in, while second line wouldn't.
3. Visit this page, you will see:

## Logging

1. In your pom.xml add this dependency higher than thymeleaf:
2. Create src\main\resources\log4j2.xml:
   * gcb > ( ni src\main\resources\log4j2.xml -force )
3. To any of your classes, add following imports and a class variable, and you can write logs:

## Internationalization

1. To src\main\webapp\WEB-INF\dispatcher-servlet.xml/<beans> add this elements:
2. Create src\main\resources\messages_en.properties:
3. Create src\main\resources\messages_ru.properties:
4. In your Thymeleaf template *.html/<html>/<body> add this line:
4. In your JSP add this lines:
5. Visit this page and change language of message by appending ?lang=ru or ?lang=en parameters to URL.

## Aspect Oriented Programming

Consult book Spring Start Here, Chapter 6.
1. Add this dependency to your pom.xml:
2. Add these namespace and element to your dispatcher-servlet.xml:
3. Create .\src\main\java\springtinyweb\aop\LoggingAspect.java:

## JDBC Template
### H2 DataSource with spring-jdbc

1. To your pom.xml add this dependencies:
2. To your dispatcher-servlet.xml add this namespace and a bean:
3. Create src\main\resources\schema.sql:
4. If you will start your application you will see a log:
Now you have a working dataSource bean.

### JdbcTemplate Usage

At this point you should have a working dataSource bean.
1. Create src\main\java\springtinyweb\model\Message.java:
2. Create src\main\java\springtinyweb\service\MessageService.java:
3. Create src\main\java\springtinyweb\repository\MessageJdbcDaoImpl.java:
   * You can find an example of how to use JdbcTemplate in an external source: Using JdbcTemplate to work with persisted data.
4. In your controller\Greeting.java add this import, class variable and a method:
5. Visit https://localhost:8080/all, you will see contents of your Message table.

## Spring Data Repository

Spring Data Repositories require a working dataSource bean, if you don't have it - follow this subsection: #H2 DataSource with spring-jdbc.
1. To your pom.xml add this property and dependency:
   * If you have spring-jdbc dependency you can remove it (you've added it at #H2 DataSource with spring-jdbc step).
2. Create src\main\java\springtinyweb\config\AdditionalConfig.java:
   * This is where you enable discovering of Spring Repositories. You don't need this class if you've already configured Hibernate as in #Hibernate Configuration section.
3. Create src\main\java\springtinyweb\model\Message.java:
   * Some lines are commented out, because they are used in different flow: #Hibernate.
4. Create src\main\java\springtinyweb\repository\MessageRepository.java:
5. Create src\main\java\springtinyweb\service\MessageService.java:
5. In your controller\Greeting.java add these imports, class variable and methods:
6. Create new messages: localhost:8080/save?msg=ilovetomato, or get message with id=1 by following localhost:8080/find?id=1.

## Hibernate
### H2 DataSource

Follow this section to obtain a dataSource bean.
1. To your pom.xml add this dependencies:
2. To your dispatcher-servlet.xml add this bean:
   * As you can see, there is a one long ugly commented-out connectionInitSqls property. You don't need it with Hibernate, but if you will wonder how you can provide initializing SQL script to XML-defined dataSource bean - that's how you can do it. If you'll want something more readable and concise, uncomment jdbc:initialize-database element and add spring-jdbc dependency and xmlns:jdbc namespace as in this section: #H2 DataSource with spring-jdbc.
Now you have a working dataSource bean, which you can use to interact with database.

### Hibernate Configuration

At this point you should have a working dataSource bean.
1. To your pom.xml add this property and dependency:
2. To your dispatcher-servlet.xml add this namespace and elements:
   * Note <jpa:repositories ...> element- this is where you enable Spring Data Repository lookup, this is why you wouldn't need AdditionalConfig.java class in #Spring_Data_Repository section. If you are not going to use Spring Repositories you can remove this element and jpa: namespace.
   * Both Spring 5 and Spring 6 use Hibernate through org.springframework.orm.hibernate5 package, even if it's Hibernate 6.
   * If you're using Hibernate 6, you can remove hibernate.dialect line - Hibernate 6 will automatically resolve dialect from the JDBC DatabaseMetaData.
Now your Hibernate is configured, but it's not being used by your application. You can proceed to #Spring Data Repository section in which you should skip the optional step with creation of AdditionalConfig.java class. When you will create src\main\java\springtinyweb\model\Message.java comment out all org.springframework imports and @Table annotation. Also uncomment all javax.persistence imports, @Entity and @GeneratedValue line.

## Spring Security JDBC

At this point you should have a working DataSource bean. This is how you can use your database in Spring Security:
In src\main\java\springtinyweb\security\SecurityConfiguration.java remove userDetailsService method and instead add this two methods:

## REST

1. Add this dependency to pom.xml:
2. Add this element to your dispatcher-servlet.xml:
3. Create .\src\main\java\springtinyweb\rest\MainRest.java:
   * These are two ways which you can use to marshall an object to json, they produce different output for chars which are not in Basic Multilingual Plane, this is an issue of Jackson library.
4. Invoke these endpoints with curl or Powershell:

## Spring 5

You can switch all of the above to Spring 5 and Hibernate 5.
1. In pom.xml use second group of dependency versions:
   * First group provided here for convenience, you will get it by following tutorial.
2. In pom.xml replace digit in thymeleaf-spring6 and thymeleaf-extras-springsecurity6 artifacts.
3. In dispatcher-servlet.xml replace digit in org.thymeleaf.spring6 and org.thymeleaf.extras.springsecurity6.
4. In all your entity classes (only Message.java in this tutorial) change your imports from jakarta.persistence to javax.persistence.
5. If you have
replace it with