├── README.md
├── pom.xml
└── src
├── main
├── java
│ └── net
│ │ └── guides
│ │ └── springboot
│ │ └── todomanagement
│ │ ├── TodoManagementSpringBoot2Application.java
│ │ ├── controller
│ │ ├── ErrorController.java
│ │ ├── LogoutController.java
│ │ ├── TodoController.java
│ │ └── WelcomeController.java
│ │ ├── model
│ │ └── Todo.java
│ │ ├── repository
│ │ └── TodoRepository.java
│ │ ├── security
│ │ └── SecurityConfiguration.java
│ │ └── service
│ │ ├── ITodoService.java
│ │ └── TodoService.java
├── resources
│ └── application.properties
└── webapp
│ └── WEB-INF
│ └── jsp
│ ├── common
│ ├── footer.jspf
│ ├── header.jspf
│ └── navigation.jspf
│ ├── error.jsp
│ ├── list-todos.jsp
│ ├── todo.jsp
│ └── welcome.jsp
└── test
└── java
└── net
└── guides
└── springboot
└── todomanagementspringboot
└── TodoManagementSpringBoot2ApplicationTests.java
/README.md:
--------------------------------------------------------------------------------
1 | # todo-management-spring-boot
2 |
3 |
4 | # Mini Todo Management Project using Spring Boot + Spring MVC + Spring Security + JSP + Hibernate + MySQL
5 |
6 | - http://www.javaguides.net/2018/09/mini-todo-management-project-using-spring-boot-springmvc-springsecurity-jsp-hibernate-mysql.html
7 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | net.guides.springboot
8 | todo-management-spring-boot
9 | 0.0.1-SNAPSHOT
10 | jar
11 |
12 | todo-management-spring-boot
13 | Demo project for Spring Boot
14 |
15 |
16 | org.springframework.boot
17 | spring-boot-starter-parent
18 | 2.0.4.RELEASE
19 |
20 |
21 |
22 |
23 | UTF-8
24 | UTF-8
25 | 1.8
26 |
27 |
28 |
29 |
30 | javax.servlet
31 | jstl
32 |
33 |
34 |
35 | org.webjars
36 | bootstrap
37 | 3.3.6
38 |
39 |
40 |
41 | org.webjars
42 | bootstrap-datepicker
43 | 1.0.1
44 |
45 |
46 |
47 | org.webjars
48 | jquery
49 | 1.9.1
50 |
51 |
52 |
53 | org.apache.tomcat.embed
54 | tomcat-embed-jasper
55 | provided
56 |
57 |
58 |
59 | org.springframework.boot
60 | spring-boot-starter-data-jpa
61 |
62 |
63 | org.springframework.boot
64 | spring-boot-starter-security
65 |
66 |
67 | org.springframework.boot
68 | spring-boot-starter-web
69 |
70 |
71 |
72 | org.springframework.boot
73 | spring-boot-devtools
74 | runtime
75 |
76 |
77 | mysql
78 | mysql-connector-java
79 | runtime
80 |
81 |
82 | org.springframework.boot
83 | spring-boot-starter-test
84 | test
85 |
86 |
87 | org.springframework.security
88 | spring-security-test
89 | test
90 |
91 |
92 |
93 |
94 |
95 |
96 | org.springframework.boot
97 | spring-boot-maven-plugin
98 |
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/TodoManagementSpringBoot2Application.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class TodoManagementSpringBoot2Application {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(TodoManagementSpringBoot2Application.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/controller/ErrorController.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.controller;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 |
5 | import org.springframework.stereotype.Controller;
6 | import org.springframework.web.bind.annotation.ExceptionHandler;
7 | import org.springframework.web.servlet.ModelAndView;
8 |
9 | @Controller("error")
10 | public class ErrorController {
11 |
12 | @ExceptionHandler(Exception.class)
13 | public ModelAndView handleException
14 | (HttpServletRequest request, Exception ex){
15 | ModelAndView mv = new ModelAndView();
16 |
17 | mv.addObject("exception", ex.getLocalizedMessage());
18 | mv.addObject("url", request.getRequestURL());
19 |
20 | mv.setViewName("error");
21 | return mv;
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/controller/LogoutController.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.controller;
2 |
3 | import javax.servlet.http.HttpServletRequest;
4 | import javax.servlet.http.HttpServletResponse;
5 |
6 | import org.springframework.security.core.Authentication;
7 | import org.springframework.security.core.context.SecurityContextHolder;
8 | import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
9 | import org.springframework.stereotype.Controller;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestMethod;
12 |
13 | @Controller
14 | public class LogoutController {
15 |
16 | @RequestMapping(value = "/logout", method = RequestMethod.GET)
17 | public String logout(HttpServletRequest request,
18 | HttpServletResponse response) {
19 |
20 | Authentication authentication = SecurityContextHolder.getContext()
21 | .getAuthentication();
22 |
23 | if (authentication != null) {
24 | new SecurityContextLogoutHandler().logout(request, response,
25 | authentication);
26 | }
27 |
28 | return "redirect:/";
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/controller/TodoController.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.controller;
2 |
3 | import java.text.SimpleDateFormat;
4 | import java.util.Date;
5 |
6 | import javax.validation.Valid;
7 |
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.beans.propertyeditors.CustomDateEditor;
10 | import org.springframework.security.core.context.SecurityContextHolder;
11 | import org.springframework.security.core.userdetails.UserDetails;
12 | import org.springframework.stereotype.Controller;
13 | import org.springframework.ui.ModelMap;
14 | import org.springframework.validation.BindingResult;
15 | import org.springframework.web.bind.WebDataBinder;
16 | import org.springframework.web.bind.annotation.InitBinder;
17 | import org.springframework.web.bind.annotation.RequestMapping;
18 | import org.springframework.web.bind.annotation.RequestMethod;
19 | import org.springframework.web.bind.annotation.RequestParam;
20 |
21 | import net.guides.springboot.todomanagement.model.Todo;
22 | import net.guides.springboot.todomanagement.service.ITodoService;
23 |
24 | @Controller
25 | public class TodoController {
26 |
27 | @Autowired
28 | private ITodoService todoService;
29 |
30 | @InitBinder
31 | public void initBinder(WebDataBinder binder) {
32 | // Date - dd/MM/yyyy
33 | SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
34 | binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
35 | }
36 |
37 | @RequestMapping(value = "/list-todos", method = RequestMethod.GET)
38 | public String showTodos(ModelMap model) {
39 | String name = getLoggedInUserName(model);
40 | model.put("todos", todoService.getTodosByUser(name));
41 | // model.put("todos", service.retrieveTodos(name));
42 | return "list-todos";
43 | }
44 |
45 | private String getLoggedInUserName(ModelMap model) {
46 | Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
47 |
48 | if (principal instanceof UserDetails) {
49 | return ((UserDetails) principal).getUsername();
50 | }
51 |
52 | return principal.toString();
53 | }
54 |
55 | @RequestMapping(value = "/add-todo", method = RequestMethod.GET)
56 | public String showAddTodoPage(ModelMap model) {
57 | model.addAttribute("todo", new Todo());
58 | return "todo";
59 | }
60 |
61 | @RequestMapping(value = "/delete-todo", method = RequestMethod.GET)
62 | public String deleteTodo(@RequestParam long id) {
63 | todoService.deleteTodo(id);
64 | // service.deleteTodo(id);
65 | return "redirect:/list-todos";
66 | }
67 |
68 | @RequestMapping(value = "/update-todo", method = RequestMethod.GET)
69 | public String showUpdateTodoPage(@RequestParam long id, ModelMap model) {
70 | Todo todo = todoService.getTodoById(id).get();
71 | model.put("todo", todo);
72 | return "todo";
73 | }
74 |
75 | @RequestMapping(value = "/update-todo", method = RequestMethod.POST)
76 | public String updateTodo(ModelMap model, @Valid Todo todo, BindingResult result) {
77 |
78 | if (result.hasErrors()) {
79 | return "todo";
80 | }
81 |
82 | todo.setUserName(getLoggedInUserName(model));
83 | todoService.updateTodo(todo);
84 | return "redirect:/list-todos";
85 | }
86 |
87 | @RequestMapping(value = "/add-todo", method = RequestMethod.POST)
88 | public String addTodo(ModelMap model, @Valid Todo todo, BindingResult result) {
89 |
90 | if (result.hasErrors()) {
91 | return "todo";
92 | }
93 |
94 | todo.setUserName(getLoggedInUserName(model));
95 | todoService.saveTodo(todo);
96 | return "redirect:/list-todos";
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/controller/WelcomeController.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.controller;
2 |
3 | import org.springframework.security.core.context.SecurityContextHolder;
4 | import org.springframework.security.core.userdetails.UserDetails;
5 | import org.springframework.stereotype.Controller;
6 | import org.springframework.ui.ModelMap;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestMethod;
9 |
10 | @Controller
11 | public class WelcomeController {
12 |
13 | @RequestMapping(value = "/", method = RequestMethod.GET)
14 | public String showWelcomePage(ModelMap model) {
15 | model.put("name", getLoggedinUserName());
16 | return "welcome";
17 | }
18 |
19 | private String getLoggedinUserName() {
20 | Object principal = SecurityContextHolder.getContext()
21 | .getAuthentication().getPrincipal();
22 |
23 | if (principal instanceof UserDetails) {
24 | return ((UserDetails) principal).getUsername();
25 | }
26 |
27 | return principal.toString();
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/model/Todo.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.model;
2 |
3 | import java.util.Date;
4 |
5 | import javax.persistence.Entity;
6 | import javax.persistence.GeneratedValue;
7 | import javax.persistence.GenerationType;
8 | import javax.persistence.Id;
9 | import javax.persistence.Table;
10 | import javax.validation.constraints.Size;
11 |
12 | @Entity
13 | @Table(name = "todos")
14 | public class Todo {
15 |
16 | @Id
17 | @GeneratedValue(strategy = GenerationType.AUTO)
18 | private long id;
19 |
20 | private String userName;
21 |
22 | @Size(min = 10, message = "Enter at least 10 Characters...")
23 | private String description;
24 |
25 | private Date targetDate;
26 |
27 | public Todo() {
28 | super();
29 | }
30 |
31 | public Todo(String user, String desc, Date targetDate, boolean isDone) {
32 | super();
33 | this.userName = user;
34 | this.description = desc;
35 | this.targetDate = targetDate;
36 | }
37 |
38 | public long getId() {
39 | return id;
40 | }
41 |
42 | public void setId(long id) {
43 | this.id = id;
44 | }
45 |
46 | public String getUserName() {
47 | return userName;
48 | }
49 |
50 | public void setUserName(String userName) {
51 | this.userName = userName;
52 | }
53 |
54 | public String getDescription() {
55 | return description;
56 | }
57 |
58 | public void setDescription(String description) {
59 | this.description = description;
60 | }
61 |
62 | public Date getTargetDate() {
63 | return targetDate;
64 | }
65 |
66 | public void setTargetDate(Date targetDate) {
67 | this.targetDate = targetDate;
68 | }
69 | }
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/repository/TodoRepository.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.repository;
2 |
3 | import java.util.List;
4 |
5 | import org.springframework.data.jpa.repository.JpaRepository;
6 |
7 | import net.guides.springboot.todomanagement.model.Todo;
8 |
9 | public interface TodoRepository extends JpaRepository{
10 | List findByUserName(String user);
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/security/SecurityConfiguration.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.security;
2 |
3 | import org.springframework.beans.factory.annotation.Autowired;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
6 | import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
8 | import org.springframework.security.crypto.password.NoOpPasswordEncoder;
9 |
10 | @Configuration
11 | public class SecurityConfiguration extends WebSecurityConfigurerAdapter{
12 | @Autowired
13 | public void configureGlobalSecurity(AuthenticationManagerBuilder auth)
14 | throws Exception {
15 | auth.inMemoryAuthentication()
16 | .passwordEncoder(NoOpPasswordEncoder.getInstance())
17 | .withUser("admin").password("admin")
18 | .roles("USER", "ADMIN");
19 | }
20 |
21 | @Override
22 | protected void configure(HttpSecurity http) throws Exception {
23 | http.authorizeRequests().antMatchers("/login", "/h2-console/**").permitAll()
24 | .antMatchers("/", "/*todo*/**").access("hasRole('USER')").and()
25 | .formLogin();
26 |
27 | http.csrf().disable();
28 | http.headers().frameOptions().disable();
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/service/ITodoService.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.service;
2 |
3 | import java.util.Date;
4 |
5 | import java.util.List;
6 | import java.util.Optional;
7 |
8 | import net.guides.springboot.todomanagement.model.Todo;
9 |
10 | public interface ITodoService {
11 |
12 | List getTodosByUser(String user);
13 |
14 | Optional getTodoById(long id);
15 |
16 | void updateTodo(Todo todo);
17 |
18 | void addTodo(String name, String desc, Date targetDate, boolean isDone);
19 |
20 | void deleteTodo(long id);
21 |
22 | void saveTodo(Todo todo);
23 |
24 | }
--------------------------------------------------------------------------------
/src/main/java/net/guides/springboot/todomanagement/service/TodoService.java:
--------------------------------------------------------------------------------
1 | package net.guides.springboot.todomanagement.service;
2 |
3 | import java.util.Date;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.stereotype.Service;
9 |
10 | import net.guides.springboot.todomanagement.model.Todo;
11 | import net.guides.springboot.todomanagement.repository.TodoRepository;
12 |
13 | @Service
14 | public class TodoService implements ITodoService {
15 |
16 | @Autowired
17 | private TodoRepository todoRepository;
18 |
19 | @Override
20 | public List getTodosByUser(String user) {
21 | return todoRepository.findByUserName(user);
22 | }
23 |
24 | @Override
25 | public Optional getTodoById(long id) {
26 | return todoRepository.findById(id);
27 | }
28 |
29 | @Override
30 | public void updateTodo(Todo todo) {
31 | todoRepository.save(todo);
32 | }
33 |
34 | @Override
35 | public void addTodo(String name, String desc, Date targetDate, boolean isDone) {
36 | todoRepository.save(new Todo(name, desc, targetDate, isDone));
37 | }
38 |
39 | @Override
40 | public void deleteTodo(long id) {
41 | Optional todo = todoRepository.findById(id);
42 | if (todo.isPresent()) {
43 | todoRepository.delete(todo.get());
44 | }
45 | }
46 |
47 | @Override
48 | public void saveTodo(Todo todo) {
49 | todoRepository.save(todo);
50 | }
51 | }
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | ## Spring view resolver set up
2 | spring.mvc.view.prefix=/WEB-INF/jsp/
3 | spring.mvc.view.suffix=.jsp
4 |
5 | ## Spring DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
6 | spring.datasource.url = jdbc:mysql://localhost:3306/users_database?useSSL=false
7 | spring.datasource.username = root
8 | spring.datasource.password = root
9 |
10 |
11 | ## Hibernate Properties
12 | # The SQL dialect makes Hibernate generate better SQL for the chosen database
13 | spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect
14 |
15 | # Hibernate ddl auto (create, create-drop, validate, update)
16 | spring.jpa.hibernate.ddl-auto = update
17 |
--------------------------------------------------------------------------------
/src/main/webapp/WEB-INF/jsp/common/footer.jspf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
10 |
11 |
12 |
19 |