<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.st</groupId> <artifactId>todo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>todo</name> <packaging>war</packaging> <description>To do list </description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.4.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <java.version>13</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> </dependency> </dependencies> <build> <finalName>todos</finalName> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
logging.level.root=ERROR # Derby Database with embedded driver - a directory called database is created when app runs first time spring.datasource.url=jdbc:derby:database;create=true spring.datasource.username=todo spring.datasource.password=todo spring.datasource.driver-class=org.apache.derby.jdbc.EmbeddedDriver #Tomcat related server.port=8888 # Spring MVC View Related spring.mvc.view.prefix=/ spring.mvc.view.suffix=.jsp # JPA spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=update spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.DerbyTenFiveDialect
package todo; import java.util.ArrayList; import java.util.List; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Transient; @Entity @Table(name = "users", schema = "app") public class User { @Id @Column(length=10) private String username; @Column(length=10) private String password; @Transient private String confirmPassword; // This is not mapped to table because of @Transient @Column(length=50) private String email; // One user - many Todos @OneToMany(mappedBy = "username") private List<Todo> todos = new ArrayList<Todo>(); public List<Todo> getTodos() { return todos; } public void setTodos(List<Todo> todos) { this.todos = todos; } public String getUsername() { return username; } public String getConfirmPassword() { return confirmPassword; } public void setConfirmPassword(String confirmPassword) { this.confirmPassword = confirmPassword; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
package todo; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "todos", schema = "app") public class Todo { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; private String text; @Column( length = 10) private String category; @Column( length = 10) private String username; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } public String getCategory() { return category; } public void setCategory(String category) { this.category = category; } }
package todo; import org.springframework.data.repository.CrudRepository; public interface UserRepo extends CrudRepository<User,String> { }
package todo; import java.util.List; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; public interface TodoRepo extends CrudRepository<Todo,Integer> { // Gets all Todos of the given user @Query("SELECT t FROM Todo t WHERE t.username = ?1") List<Todo> getTodosByUser(String username); // Gets Todos related to given user in the desc order of id so that most recent comes first @Query("SELECT t FROM Todo t WHERE t.username = ?1 order by id desc") List<Todo> getRecentTodosByUser(String username); // Performs case insensitive search for the given text @Query("SELECT t FROM Todo t WHERE t.username = ?1 and upper(t.text) like ?2 order by id desc") List<Todo> getTodosByText(String username, String text); }
package todo; import java.util.List; import java.util.Optional; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class UserController { @Autowired private UserRepo userRepo; @Autowired private TodoRepo todoRepo; @RequestMapping(value = "logout") public String logout(HttpSession session) { session.invalidate(); return "redirect:login"; } @RequestMapping(value = "login") public String login(ModelMap model) { User u = new User(); model.addAttribute("user", u); return "login"; } @RequestMapping(value = "login", method = RequestMethod.POST) public String login(ModelMap model, User u, HttpSession session) { // check whether user is present in Users table Optional<User> user = userRepo.findById(u.getUsername()); if (user.isPresent() && user.get().getPassword().equals(u.getPassword())) { session.setAttribute("username", u.getUsername()); return "redirect:home"; } else { model.addAttribute("user", u); model.addAttribute("message", "Login Failed!"); return "login"; } } @RequestMapping(value = "register") public String register(ModelMap model) { User u = new User(); model.addAttribute("user", u); return "register"; } @RequestMapping(value = "register", method = RequestMethod.POST) public String register(ModelMap model, User u) { // Insert user details into table try { userRepo.save(u); return "redirect:login"; } catch (Exception ex) { System.out.println(ex); model.addAttribute("user", u); model.addAttribute("message", "Sorry! Registration Failed. Please try again!"); return "register"; } } @RequestMapping(value = "home") public String home(ModelMap model, HttpSession session) { String username = (String) session.getAttribute("username"); List<Todo> todos = todoRepo.getRecentTodosByUser(username); // Take only first 5 todos from the list model.addAttribute("todos", todos.stream().limit(5).toArray()); return "home"; } }
package todo; import java.util.List; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; @Controller public class TodoController { @Autowired private TodoRepo todoRepo; @Autowired private UserRepo userRepo; @RequestMapping(value = "add") public String add(ModelMap model) { Todo todo = new Todo(); model.addAttribute("todo", todo); return "add"; } @RequestMapping(value = "add", method = RequestMethod.POST) public String add(ModelMap model, Todo todo, HttpSession session) { // Insert Todo details into table try { // Set user to current user String username = (String) session.getAttribute("username"); todo.setUsername(username); todoRepo.save(todo); return "redirect:/home"; } catch (Exception ex) { System.out.println(ex); model.addAttribute("todo", todo); model.addAttribute("message", "Sorry! Could not add todo entry. Please try again!"); return "add"; } } @RequestMapping(value = "list") public String list(ModelMap model, HttpSession session) { // get current user String username = (String) session.getAttribute("username"); User user = userRepo.findById(username).get(); List<Todo> todos = user.getTodos(); model.addAttribute("todos", todos); return "list"; } @RequestMapping(value = "delete/{id}") public String delete(ModelMap model, @PathVariable("id") int id) { Todo todo = todoRepo.findById(id).get(); todoRepo.delete(todo); return "redirect:/home"; } @RequestMapping(value = "edit/{id}") public String edit(ModelMap model, @PathVariable("id") int id) { Todo todo = todoRepo.findById(id).get(); model.addAttribute("todo", todo); return "edit"; } @RequestMapping(value = "edit/{id}", method = RequestMethod.POST) public String edit(ModelMap model, Todo todo, @PathVariable("id") int id) { // Update todo details into table try { Todo dbTodo = todoRepo.findById(id).get(); dbTodo.setText(todo.getText()); dbTodo.setCategory(todo.getCategory()); todoRepo.save(dbTodo); return "redirect:/home"; } catch (Exception ex) { System.out.println(ex); model.addAttribute("todo", todo); model.addAttribute("message", "Sorry! Could not update todo entry. Please try again!"); return "edit"; } } @RequestMapping(value = "searchform") public String search() { return "search"; } @RequestMapping(value = "search") public String search(String text, HttpSession session, ModelMap model) { System.out.println(text); List<Todo> todos = todoRepo.getTodosByText(session.getAttribute("username").toString(), "%" + text.toUpperCase() + "%"); if (todos.size() > 0) model.addAttribute("todos", todos); else model.addAttribute("message", "Sorry! No todos found!"); return "search"; } }
package todo; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Order(1) public class AuthenticationFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { String allowedUrls[] = { "login", "register", "styles.css", "allheaders.jsp" }; HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; // Allow some specific requests without authentication boolean allowed = false; String url = req.getRequestURI(); for (String u : allowedUrls) if (url.endsWith(u)) allowed = true; if (allowed) { chain.doFilter(request, response); }else { // URL is not allowed unless authentication is done HttpSession session = req.getSession(); if (session == null || session.getAttribute("username") == null) // Authentication is not done res.sendRedirect("/login"); else chain.doFilter(request, response); } } }
package todo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; @SpringBootApplication public class TodoApplication extends SpringBootServletInitializer { public static void main(String[] args) { SpringApplication.run(TodoApplication.class, args); } }
.banner { font-family: Arial; font-size: 30pt; background-color: red; color: white; } .menu { font-family: verdana; font-size: 12pt; font-weight: bold; background-color: silver; } .tableheader { font-family: calibri; font-size: 12pt; font-weight: bold; background-color: black; color: white; } body { font-family: calibri; font-size: 12pt; }
<link rel="stylesheet" href="styles.css" /> <div class="banner">ToDo List</div>
<link rel="stylesheet" href="/styles.css" /> <div class="banner">ToDo List</div> <div class="menu"> <a href="/home">Home</a> <a href="/add">Add Todo</a> <a href="/list">List Todos</a> <a href="/searchform">Search Todos</a> <span style="float: right"> User : ${sessionScope.username} <a href="/logout">Logout</a> </span> </div>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@include file="allheader.jsp"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <title>Login</title> </head> <body> <h1>Login</h1> <sf:form modelAttribute="user" method="post"> Username <br> <sf:input required="true" path="username" /> <p /> Password <br /> <sf:password path="password" /> <p /> <button type="submit">Login</button> </sf:form> <h4> <a href="/register">Register as new user!</a> </h4> <h4>${message}</h4> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@include file="allheader.jsp"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <title>Registration</title> </head> <body> <h1>Registration</h1> <sf:form modelAttribute="user" method="post"> Username <br> <sf:input required="true" path="username" /> <p /> Password <br /> <sf:password path="password" /> <p /> Confirm Password <br /> <sf:password path="confirmPassword" /> <p /> Email Address <br> <sf:input required="true" path="email" /> <p /> <button type="submit">Register</button> </sf:form> <p /> <a href="/login">Login</a> <h4>${message}</h4> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@ include file="header.jsp"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <title>Login</title> </head> <body> <h1>Recently Added</h1> <jsp:include page="list_todos.jsp" /> </body> </html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <!-- find out whether we have any items in the list using length() function of JSTL --> <c:if test="${fn:length(todos) gt 0}"> <table style="width: 100%"> <tr class="tableheader"> <td style="text-align: center">Description</td> <td style="text-align: center">Category</td> <td></td> <c:forEach var="todo" items="${todos}"> <tr> <td style="text-align: center">${todo.text}</td> <td style="width: 20%; text-align: center">${todo.category}</td> <td style="text-align: center; width: 10%"><a href="edit/${todo.id}">Edit</a> <a onclick="return confirm('Do you really want to delete?')" href="delete/${todo.id}">Delete</a></td> </tr> </c:forEach> </table> </c:if> <c:if test="${fn:length(todos) == 0}"> <h4>Sorry! No todos found!</h4> </c:if>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@include file="header.jsp"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <title>Add Todo</title> </head> <body> <h1>Add Todo</h1> <sf:form modelAttribute="todo" method="post"> Text <br> <sf:input required="true" path="text" size="50" /> <p /> Category <br /> <sf:select path="category"> <sf:option value="education" label="Education" /> <sf:option value="finance" label="Finance" /> <sf:option value="ent" label="Entertainment" /> <sf:option value="family" label="Family and Friends" /> <sf:option value="maint" label="Maintenance" /> <sf:option value="others" label="Others" /> </sf:select> <p /> <button type="submit">Add Todo</button> </sf:form> <h4>${message}</h4> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <title>Edit Todo</title> </head> <body> <%@include file="header.jsp"%> <h1>Edit Todo</h1> <sf:form modelAttribute="todo" method="post"> Text <br> <sf:input required="true" path="text" size="50" /> <p /> Category <br /> <sf:select path="category"> <sf:option value="education" label="Education" /> <sf:option value="finance" label="Finance" /> <sf:option value="ent" label="Entertainment" /> <sf:option value="family" label="Family and Friends" /> <sf:option value="maint" label="Maintenance" /> <sf:option value="others" label="Others" /> </sf:select> <p /> <button type="submit">Update Todo</button> </sf:form> <h4>${message}</h4> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@include file="header.jsp"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <title>Search Todo</title> </head> <body> <h1>Search Todos</h1> <form action="search"> Text <br> <input required="true" name="text" size="20" /> <p /> <button type="submit">Search</button> </form> <c:if test="${!empty todos}"> <jsp:include page="list_todos.jsp" /> </c:if> <h4>${message}</h4> </body> </html>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <%@ include file="header.jsp"%> <%@ taglib prefix="sf" uri="http://www.springframework.org/tags/form"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <title>Todos</title> </head> <body> <h1>Todos</h1> <jsp:include page="list_todos.jsp" /> </body> </html>