├── README.md ├── src └── main │ ├── webapp │ ├── res │ │ ├── icons.png │ │ ├── tlotr.png │ │ ├── favicon.png │ │ └── style.css │ └── WEB-INF │ │ ├── pages-simple │ │ ├── films.jsp │ │ └── editPage.jsp │ │ └── pages │ │ ├── editPage.jsp │ │ └── films.jsp │ ├── resources │ └── db.properties │ └── java │ └── testgroup │ └── filmography │ ├── dao │ ├── FilmDAO.java │ └── FilmDAOImpl.java │ ├── service │ ├── FilmService.java │ └── FilmServiceImpl.java │ ├── config │ ├── AppInitializer.java │ ├── WebConfig.java │ └── HibernateConfig.java │ ├── model │ └── Film.java │ └── controller │ └── FilmController.java ├── pom.xml └── db.sql /README.md: -------------------------------------------------------------------------------- 1 | ### Filmography 2 | Simple CRUD example using Maven, Spring MVC, Hibernate, MySQL 3 | -------------------------------------------------------------------------------- /src/main/webapp/res/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxsouldrake/Filmography/HEAD/src/main/webapp/res/icons.png -------------------------------------------------------------------------------- /src/main/webapp/res/tlotr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxsouldrake/Filmography/HEAD/src/main/webapp/res/tlotr.png -------------------------------------------------------------------------------- /src/main/webapp/res/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/maxsouldrake/Filmography/HEAD/src/main/webapp/res/favicon.png -------------------------------------------------------------------------------- /src/main/resources/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driverClassName=com.mysql.cj.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=Europe/Minsk&useSSL=false 3 | jdbc.username=root 4 | jdbc.password=root 5 | 6 | hibernate.dialect=org.hibernate.dialect.MySQL8Dialect 7 | hibernate.show_sql=true -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/dao/FilmDAO.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.dao; 2 | 3 | import testgroup.filmography.model.Film; 4 | 5 | import java.util.List; 6 | 7 | public interface FilmDAO { 8 | List allFilms(int page); 9 | void add(Film film); 10 | void delete(Film film); 11 | void edit(Film film); 12 | Film getById(int id); 13 | 14 | int filmsCount(); 15 | 16 | boolean checkTitle(String title); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/service/FilmService.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.service; 2 | 3 | import testgroup.filmography.model.Film; 4 | 5 | import java.util.List; 6 | 7 | public interface FilmService { 8 | List allFilms(int page); 9 | void add(Film film); 10 | void delete(Film film); 11 | void edit(Film film); 12 | Film getById(int id); 13 | 14 | int filmsCount(); 15 | 16 | boolean checkTitle(String title); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/config/AppInitializer.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.config; 2 | 3 | import org.springframework.web.filter.CharacterEncodingFilter; 4 | import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; 5 | 6 | import javax.servlet.Filter; 7 | 8 | public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 9 | @Override 10 | protected Class[] getRootConfigClasses() { 11 | return new Class[]{HibernateConfig.class}; 12 | } 13 | 14 | @Override 15 | protected Class[] getServletConfigClasses() { 16 | return new Class[]{WebConfig.class}; 17 | } 18 | 19 | @Override 20 | protected String[] getServletMappings() { 21 | return new String[]{"/"}; 22 | } 23 | 24 | @Override 25 | protected Filter[] getServletFilters() { 26 | CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter(); 27 | characterEncodingFilter.setEncoding("UTF-8"); 28 | characterEncodingFilter.setForceEncoding(true); 29 | return new Filter[] {characterEncodingFilter}; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.ViewResolver; 7 | import org.springframework.web.servlet.config.annotation.EnableWebMvc; 8 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 9 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 10 | import org.springframework.web.servlet.view.InternalResourceViewResolver; 11 | 12 | @Configuration 13 | @EnableWebMvc 14 | @ComponentScan(basePackages = "testgroup.filmography") 15 | public class WebConfig implements WebMvcConfigurer { 16 | 17 | @Override 18 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 19 | registry.addResourceHandler("/res/**").addResourceLocations("/res/"); 20 | } 21 | 22 | @Bean 23 | ViewResolver viewResolver() { 24 | InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 25 | viewResolver.setPrefix("/WEB-INF/pages/"); 26 | viewResolver.setSuffix(".jsp"); 27 | return viewResolver; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/pages-simple/films.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | 4 | 5 | FILMS 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 39 | 40 |
Films
titleyeargenrewatchedaction
${i.index + 1 + (page - 1) * 10}${film.title}${film.year}${film.genre}${film.watched}">edit">delete
31 | ">Add new film 32 | 33 | 34 | 35 | 36 | ${i.index} 37 | 38 |
41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/model/Film.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.model; 2 | 3 | import javax.persistence.*; 4 | 5 | @Entity 6 | @Table(name = "films") 7 | public class Film { 8 | 9 | @Id 10 | @Column(name = "id") 11 | @GeneratedValue(strategy = GenerationType.IDENTITY) 12 | private int id; 13 | 14 | @Column(name = "title") 15 | private String title; 16 | 17 | @Column(name = "year") 18 | private int year; 19 | 20 | @Column(name = "genre") 21 | private String genre; 22 | 23 | @Column(name = "watched") 24 | private boolean watched; 25 | 26 | 27 | public int getId() { 28 | return id; 29 | } 30 | 31 | public void setId(int id) { 32 | this.id = id; 33 | } 34 | 35 | public String getTitle() { 36 | return title; 37 | } 38 | 39 | public void setTitle(String title) { 40 | this.title = title; 41 | } 42 | 43 | public int getYear() { 44 | return year; 45 | } 46 | 47 | public void setYear(int year) { 48 | this.year = year; 49 | } 50 | 51 | public String getGenre() { 52 | return genre; 53 | } 54 | 55 | public void setGenre(String genre) { 56 | this.genre = genre; 57 | } 58 | 59 | public boolean isWatched() { 60 | return watched; 61 | } 62 | 63 | public void setWatched(boolean watched) { 64 | this.watched = watched; 65 | } 66 | 67 | @Override 68 | public String toString() { 69 | return id + " " + title + " " + year + " " + genre + " " + watched; 70 | } 71 | } 72 | 73 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/service/FilmServiceImpl.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.service; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Service; 5 | import org.springframework.transaction.annotation.Transactional; 6 | import testgroup.filmography.dao.FilmDAO; 7 | import testgroup.filmography.model.Film; 8 | 9 | import java.util.List; 10 | 11 | @Service 12 | public class FilmServiceImpl implements FilmService { 13 | 14 | private FilmDAO filmDAO; 15 | 16 | @Autowired 17 | public void setFilmDAO(FilmDAO filmDAO) { 18 | this.filmDAO = filmDAO; 19 | } 20 | 21 | @Override 22 | @Transactional 23 | public List allFilms(int page) { 24 | return filmDAO.allFilms(page); 25 | } 26 | 27 | @Override 28 | @Transactional 29 | public void add(Film film) { 30 | filmDAO.add(film); 31 | } 32 | 33 | @Override 34 | @Transactional 35 | public void delete(Film film) { 36 | filmDAO.delete(film); 37 | } 38 | 39 | @Override 40 | @Transactional 41 | public void edit(Film film) { 42 | filmDAO.edit(film); 43 | } 44 | 45 | @Override 46 | @Transactional 47 | public Film getById(int id) { 48 | return filmDAO.getById(id); 49 | } 50 | 51 | @Override 52 | @Transactional 53 | public int filmsCount() { 54 | return filmDAO.filmsCount(); 55 | } 56 | 57 | @Override 58 | @Transactional 59 | public boolean checkTitle(String title) { 60 | return filmDAO.checkTitle(title); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/pages-simple/editPage.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | 4 | 5 | 6 | 7 | Add 8 | 9 | 10 | Edit 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 |

Edit film

21 | 22 |
23 | 24 |

Add new film

25 |
26 |
27 |

28 |

29 |

30 |

31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |

39 |

40 | 41 | 42 | 43 |

44 |

${message}

45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/dao/FilmDAOImpl.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.dao; 2 | 3 | import org.hibernate.Session; 4 | import org.hibernate.SessionFactory; 5 | import org.hibernate.query.Query; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Repository; 8 | import testgroup.filmography.model.Film; 9 | 10 | import java.util.List; 11 | 12 | @Repository 13 | public class FilmDAOImpl implements FilmDAO { 14 | private SessionFactory sessionFactory; 15 | 16 | @Autowired 17 | public void setSessionFactory(SessionFactory sessionFactory) { 18 | this.sessionFactory = sessionFactory; 19 | } 20 | 21 | @Override 22 | @SuppressWarnings("unchecked") 23 | public List allFilms(int page) { 24 | Session session = sessionFactory.getCurrentSession(); 25 | return session.createQuery("from Film").setFirstResult(10 * (page - 1)).setMaxResults(10).list(); 26 | } 27 | 28 | @Override 29 | public void add(Film film) { 30 | Session session = sessionFactory.getCurrentSession(); 31 | session.persist(film); 32 | } 33 | 34 | @Override 35 | public void delete(Film film) { 36 | Session session = sessionFactory.getCurrentSession(); 37 | session.delete(film); 38 | } 39 | 40 | @Override 41 | public void edit(Film film) { 42 | Session session = sessionFactory.getCurrentSession(); 43 | session.update(film); 44 | } 45 | 46 | @Override 47 | public Film getById(int id) { 48 | Session session = sessionFactory.getCurrentSession(); 49 | return session.get(Film.class, id); 50 | } 51 | 52 | @Override 53 | public int filmsCount() { 54 | Session session = sessionFactory.getCurrentSession(); 55 | return session.createQuery("select count(*) from Film", Number.class).getSingleResult().intValue(); 56 | } 57 | 58 | @Override 59 | public boolean checkTitle(String title) { 60 | Session session = sessionFactory.getCurrentSession(); 61 | Query query; 62 | query = session.createQuery("from Film where title = :title"); 63 | query.setParameter("title", title); 64 | return query.list().isEmpty(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/pages/editPage.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | 4 | 5 | " rel="stylesheet" type="text/css"/> 6 | "/> 7 | 8 | 9 | Add 10 | 11 | 12 | Edit 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 |

Edit film

23 | 24 |
25 | 26 |

Add new film

27 |
28 |
29 |

31 |

33 |

34 |

35 | 45 |

46 |

47 | 48 | 49 | 50 |

51 |

${message}

52 |
53 | 54 | 55 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 4.0.0 7 | 8 | testgroup 9 | filmography 10 | 1.0-SNAPSHOT 11 | war 12 | 13 | 14 | 15 | org.springframework 16 | spring-webmvc 17 | 5.1.1.RELEASE 18 | 19 | 20 | 21 | org.springframework 22 | spring-orm 23 | 5.1.1.RELEASE 24 | 25 | 26 | 27 | javax.servlet 28 | javax.servlet-api 29 | 4.0.1 30 | provided 31 | 32 | 33 | 34 | org.hibernate 35 | hibernate-core 36 | 5.3.7.Final 37 | 38 | 39 | 40 | jstl 41 | jstl 42 | 1.2 43 | 44 | 45 | 46 | mysql 47 | mysql-connector-java 48 | 8.0.11 49 | 50 | 51 | 52 | org.apache.tomcat 53 | tomcat-dbcp 54 | 9.0.10 55 | 56 | 57 | 58 | 59 | 60 | 61 | org.apache.maven.plugins 62 | maven-compiler-plugin 63 | 3.8.0 64 | 65 | 1.8 66 | 1.8 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/config/HibernateConfig.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.config; 2 | 3 | import org.apache.tomcat.dbcp.dbcp2.BasicDataSource; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.context.annotation.PropertySource; 9 | import org.springframework.core.env.Environment; 10 | import org.springframework.orm.hibernate5.HibernateTransactionManager; 11 | import org.springframework.orm.hibernate5.LocalSessionFactoryBean; 12 | import org.springframework.transaction.annotation.EnableTransactionManagement; 13 | 14 | import javax.sql.DataSource; 15 | import java.util.Properties; 16 | 17 | @Configuration 18 | @ComponentScan(basePackages = "testgroup.filmography") 19 | @EnableTransactionManagement 20 | @PropertySource(value = "classpath:db.properties") 21 | public class HibernateConfig { 22 | private Environment environment; 23 | 24 | @Autowired 25 | public void setEnvironment(Environment environment) { 26 | this.environment = environment; 27 | } 28 | 29 | private Properties hibernateProperties() { 30 | Properties properties = new Properties(); 31 | properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect")); 32 | properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")); 33 | return properties; 34 | } 35 | 36 | @Bean 37 | public DataSource dataSource() { 38 | BasicDataSource dataSource = new BasicDataSource(); 39 | dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName")); 40 | dataSource.setUrl(environment.getRequiredProperty("jdbc.url")); 41 | dataSource.setUsername(environment.getRequiredProperty("jdbc.username")); 42 | dataSource.setPassword(environment.getRequiredProperty("jdbc.password")); 43 | return dataSource; 44 | } 45 | 46 | @Bean 47 | public LocalSessionFactoryBean sessionFactory() { 48 | LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean(); 49 | sessionFactory.setDataSource(dataSource()); 50 | sessionFactory.setPackagesToScan("testgroup.filmography.model"); 51 | sessionFactory.setHibernateProperties(hibernateProperties()); 52 | return sessionFactory; 53 | } 54 | 55 | @Bean 56 | public HibernateTransactionManager transactionManager() { 57 | HibernateTransactionManager transactionManager = new HibernateTransactionManager(); 58 | transactionManager.setSessionFactory(sessionFactory().getObject()); 59 | return transactionManager; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /db.sql: -------------------------------------------------------------------------------- 1 | USE test; 2 | 3 | DROP TABLE IF EXISTS films; 4 | CREATE TABLE films 5 | ( 6 | id int(10) PRIMARY KEY AUTO_INCREMENT, 7 | title VARCHAR(100) NOT NULL, 8 | year int(4), 9 | genre VARCHAR(20), 10 | watched BIT DEFAULT false NOT NULL 11 | ) 12 | COLLATE='utf8_general_ci'; 13 | CREATE UNIQUE INDEX films_title_uindex ON films (title); 14 | 15 | INSERT INTO `films` (`title`,`year`,`genre`, watched) 16 | VALUES 17 | ("Inception", 2010, "sci-fi", 1), 18 | ("The Lord of the Rings: The Fellowship of the Ring", 2001, "fantasy", 1), 19 | ("Tag", 2018, "comedy", 0), 20 | ("Gunfight at the O.K. Corral", 1957, "western", 0), 21 | ("Die Hard", 1988, "action", 1), 22 | ("6", 1988, "action", 1), 23 | ("7", 1988, "action", 1), 24 | ("8", 1988, "action", 1), 25 | ("9", 1988, "action", 1), 26 | ("10", 1988, "action", 1), 27 | ("11", 1988, "action", 1), 28 | ("12", 1988, "action", 1), 29 | ("13", 1988, "action", 1), 30 | ("14", 1988, "action", 1), 31 | ("15", 1988, "action", 1), 32 | ("16", 1988, "action", 1), 33 | ("17", 1988, "action", 1), 34 | ("18", 1988, "action", 1), 35 | ("19", 1988, "action", 1), 36 | ("20", 1988, "action", 1), 37 | ("21", 1988, "action", 1), 38 | ("22", 1988, "action", 1), 39 | ("23", 1988, "action", 1), 40 | ("24", 1988, "action", 1), 41 | ("25", 1988, "action", 1), 42 | ("26", 1988, "action", 1), 43 | ("27", 1988, "action", 1), 44 | ("28", 1988, "action", 1), 45 | ("29", 1988, "action", 1), 46 | ("30", 1988, "action", 1), 47 | ("31", 1988, "action", 1), 48 | ("32", 1988, "action", 1), 49 | ("33", 1988, "action", 1), 50 | ("34", 1988, "action", 1), 51 | ("35", 1988, "action", 1), 52 | ("36", 1988, "action", 1), 53 | ("37", 1988, "action", 1), 54 | ("38", 1988, "action", 1), 55 | ("39", 1988, "action", 1), 56 | ("40", 1988, "action", 1), 57 | ("41", 1988, "action", 1), 58 | ("42", 1988, "action", 1), 59 | ("43", 1988, "action", 1), 60 | ("44", 1988, "action", 1), 61 | ("45", 1988, "action", 1), 62 | ("46", 1988, "action", 1), 63 | ("47", 1988, "action", 1), 64 | ("48", 1988, "action", 1), 65 | ("49", 1988, "action", 1), 66 | ("50", 1988, "action", 1), 67 | ("51", 1988, "action", 1), 68 | ("52", 1988, "action", 1), 69 | ("53", 1988, "action", 1), 70 | ("54", 1988, "action", 1), 71 | ("55", 1988, "action", 1), 72 | ("56", 1988, "action", 1), 73 | ("57", 1988, "action", 1), 74 | ("58", 1988, "action", 1), 75 | ("59", 1988, "action", 1), 76 | ("60", 1988, "action", 1), 77 | ("61", 1988, "action", 1), 78 | ("62", 1988, "action", 1), 79 | ("63", 1988, "action", 1), 80 | ("64", 1988, "action", 1), 81 | ("65", 1988, "action", 1), 82 | ("66", 1988, "action", 1), 83 | ("67", 1988, "action", 1), 84 | ("68", 1988, "action", 1), 85 | ("69", 1988, "action", 1), 86 | ("70", 1988, "action", 1); -------------------------------------------------------------------------------- /src/main/java/testgroup/filmography/controller/FilmController.java: -------------------------------------------------------------------------------- 1 | package testgroup.filmography.controller; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.*; 6 | import org.springframework.web.servlet.ModelAndView; 7 | import testgroup.filmography.model.Film; 8 | import testgroup.filmography.service.FilmService; 9 | 10 | import java.util.List; 11 | 12 | @Controller 13 | public class FilmController { 14 | private int page; 15 | 16 | private FilmService filmService; 17 | 18 | @Autowired 19 | public void setFilmService(FilmService filmService) { 20 | this.filmService = filmService; 21 | } 22 | 23 | @RequestMapping(value = "/", method = RequestMethod.GET) 24 | public ModelAndView allFilms(@RequestParam(defaultValue = "1") int page) { 25 | List films = filmService.allFilms(page); 26 | int filmsCount = filmService.filmsCount(); 27 | int pagesCount = (filmsCount + 9)/10; 28 | ModelAndView modelAndView = new ModelAndView(); 29 | modelAndView.setViewName("films"); 30 | modelAndView.addObject("page", page); 31 | modelAndView.addObject("filmsList", films); 32 | modelAndView.addObject("filmsCount", filmsCount); 33 | modelAndView.addObject("pagesCount", pagesCount); 34 | this.page = page; 35 | return modelAndView; 36 | } 37 | 38 | @RequestMapping(value = "/add", method = RequestMethod.GET) 39 | public ModelAndView addPage(@ModelAttribute("message") String message) { 40 | ModelAndView modelAndView = new ModelAndView(); 41 | modelAndView.setViewName("editPage"); 42 | return modelAndView; 43 | } 44 | 45 | @RequestMapping(value = "/add", method = RequestMethod.POST) 46 | public ModelAndView addFilm(@ModelAttribute("film") Film film) { 47 | ModelAndView modelAndView = new ModelAndView(); 48 | if (filmService.checkTitle(film.getTitle())) { 49 | modelAndView.setViewName("redirect:/"); 50 | modelAndView.addObject("page", page); 51 | filmService.add(film); 52 | } else { 53 | modelAndView.addObject("message","part with title \"" + film.getTitle() + "\" already exists"); 54 | modelAndView.setViewName("redirect:/add"); 55 | } 56 | return modelAndView; 57 | } 58 | 59 | @RequestMapping(value = "/edit/{id}", method = RequestMethod.GET) 60 | public ModelAndView editPage(@PathVariable("id") int id, 61 | @ModelAttribute("message") String message) { 62 | Film film = filmService.getById(id); 63 | ModelAndView modelAndView = new ModelAndView(); 64 | modelAndView.setViewName("editPage"); 65 | modelAndView.addObject("film", film); 66 | return modelAndView; 67 | } 68 | 69 | @RequestMapping(value = "/edit", method = RequestMethod.POST) 70 | public ModelAndView editFilm(@ModelAttribute("film") Film film) { 71 | ModelAndView modelAndView = new ModelAndView(); 72 | if (filmService.checkTitle(film.getTitle()) || filmService.getById(film.getId()).getTitle().equals(film.getTitle())) { 73 | modelAndView.setViewName("redirect:/"); 74 | modelAndView.addObject("page", page); 75 | filmService.edit(film); 76 | } else { 77 | modelAndView.addObject("message","part with title \"" + film.getTitle() + "\" already exists"); 78 | modelAndView.setViewName("redirect:/edit/" + + film.getId()); 79 | } 80 | return modelAndView; 81 | } 82 | 83 | @RequestMapping(value="/delete/{id}", method = RequestMethod.GET) 84 | public ModelAndView deleteFilm(@PathVariable("id") int id) { 85 | ModelAndView modelAndView = new ModelAndView(); 86 | int filmsCount = filmService.filmsCount(); 87 | int page = ((filmsCount - 1) % 10 == 0 && filmsCount > 10 && this.page == (filmsCount + 9)/10) ? 88 | this.page - 1 : this.page; 89 | modelAndView.setViewName("redirect:/"); 90 | modelAndView.addObject("page", page); 91 | Film film = filmService.getById(id); 92 | filmService.delete(film); 93 | return modelAndView; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/main/webapp/WEB-INF/pages/films.jsp: -------------------------------------------------------------------------------- 1 | <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8"%> 2 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 3 | 4 | 5 | FILMS 6 | " rel="stylesheet" type="text/css"/> 7 | "/> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 32 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 50 | 51 | 52 | 53 | 118 | 119 |
Films
titleyeargenrewatchedaction
${i.index + 1 + (page - 1) * 10}${film.title}${film.year}${film.genre} 28 | 29 | 30 | 31 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 41 |
48 | the list is empty but you can add a new film 49 |
120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /src/main/webapp/res/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url("tlotr.png") no-repeat 50% 50% fixed; 3 | } 4 | 5 | a { 6 | display: inline-block; 7 | text-decoration: none; 8 | text-transform: uppercase; 9 | font-size: 120%; 10 | padding: 5px 0; 11 | transition: 0.2s ease-in-out; 12 | border-radius: 5px; 13 | color: #000000; 14 | box-shadow: 2px 2px 5px rgba(0,0,0,0.3); 15 | } 16 | 17 | input:invalid:not(:placeholder-shown) { 18 | border: 2px solid red; 19 | } 20 | 21 | a.disabled { 22 | pointer-events: none; 23 | cursor: default; 24 | box-shadow: 0 0 3px rgba(0,0,0,0.3); 25 | opacity: 0.5; 26 | } 27 | 28 | a.selected { 29 | box-shadow: 0 0 25px rgb(255,255,255); 30 | background: linear-gradient(1deg, rgb(190, 200, 255), rgba(235, 245, 255, 0.9)); 31 | } 32 | 33 | a.current-page { 34 | pointer-events: none; 35 | cursor: default; 36 | font-size: 150%; 37 | box-shadow: 0 0; 38 | } 39 | 40 | a:hover { 41 | transition: 0.3s; 42 | box-shadow: 0 0 25px rgb(255,255,255); 43 | } 44 | 45 | a:active { 46 | background: linear-gradient(1deg, rgb(255, 255, 255), rgba(210, 210, 210, 0.9)); 47 | } 48 | 49 | .link a { 50 | padding-right: 10px; 51 | padding-left: 10px; 52 | } 53 | 54 | .icon { 55 | display: inline-block; 56 | width: 20px; 57 | height: 20px; 58 | margin-right: 10px; 59 | margin-left: 10px; 60 | vertical-align: bottom; 61 | background: url("icons.png") no-repeat; 62 | } 63 | 64 | .icon-add { 65 | background-position: 0 0; 66 | margin-right: 5px; 67 | margin-left: 0; 68 | } 69 | 70 | .icon-delete { 71 | background-position: -24px 0; 72 | } 73 | 74 | .icon-edit { 75 | background-position: -49px 0; 76 | } 77 | 78 | .icon-watched { 79 | background-position: -74px 0; 80 | } 81 | 82 | .icon-first { 83 | background-position: -125px 0; 84 | margin: 0; 85 | } 86 | 87 | .icon-prev { 88 | background-position: -147px 0; 89 | margin: 0; 90 | } 91 | 92 | .icon-next { 93 | background-position: -166px 0; 94 | margin: 0; 95 | } 96 | 97 | .icon-last { 98 | background-position: -188px 0; 99 | margin: 0; 100 | } 101 | 102 | .heading { 103 | text-shadow: 2px 2px 5px #7F7F7F; 104 | color: #e7f6ff; 105 | font-size: 30px; 106 | } 107 | 108 | .style { 109 | border-spacing: 0 12px; 110 | font: bold 100% Georgia, serif; 111 | margin: 40px auto; 112 | text-shadow: 1px 1px 1px #7F7F7F; 113 | background: #0000; 114 | text-align: center; 115 | vertical-align: middle; 116 | width: 60%; 117 | } 118 | 119 | .style th { 120 | color: white; 121 | background: rgba(0, 5, 25, 0.75); 122 | padding: 10px; 123 | font-size: 130%; 124 | border-top: 1px solid #efeaea; 125 | border-bottom: 1px solid #efeaea; 126 | width: 1%; 127 | } 128 | 129 | .style td { 130 | width: 1%; 131 | padding: 5px; 132 | } 133 | 134 | .style tr { 135 | height: 50px; 136 | box-shadow: 0 0 5px rgb(15,15,45); 137 | } 138 | 139 | .style tr:nth-child(even) { 140 | background: linear-gradient(1deg, rgb(180, 210, 255), rgba(255, 255, 255, 0.9)); 141 | } 142 | 143 | .style tr:nth-child(odd) { 144 | background: linear-gradient(1deg, rgb(205, 230, 255), rgba(255, 255, 255, 0.9)); 145 | } 146 | 147 | .style input { 148 | border: 1px solid #cccccc; 149 | border-radius: 3px; 150 | background: linear-gradient(1deg, rgb(205, 230, 255), rgba(255, 255, 255, 0.9)); 151 | outline: none; 152 | height: 30px; 153 | width: 300px; 154 | font: bold 20px Georgia, serif; 155 | text-align: center; 156 | text-shadow: 1px 1px 1px #7F7F7F; 157 | box-shadow: 3px 3px 25px rgb(15,15,45); 158 | } 159 | 160 | .checkbox label { 161 | display: block; 162 | border-radius: 3px; 163 | background: linear-gradient(1deg, rgb(180, 200, 220), rgba(255, 255, 255, 0.9)); 164 | padding-top: 5px; 165 | height: 25px; 166 | width: 300px; 167 | font-size: 20px; 168 | box-shadow: 3px 3px 25px rgb(15,15,45); 169 | margin: auto; 170 | color: rgba(0,0,0,0.2); 171 | text-shadow: 0 0; 172 | cursor: pointer; 173 | } 174 | 175 | .checkbox label::selection, .checkbox span::selection { 176 | background: transparent; 177 | } 178 | 179 | .checkbox label:hover { 180 | box-shadow: 0 0 25px rgb(155,155,155); 181 | } 182 | 183 | .checkbox label:active { 184 | box-shadow: 0 0 25px rgb(255,255,255); 185 | } 186 | 187 | .checkbox input[type=checkbox] { 188 | display: none; 189 | } 190 | 191 | .checkbox-common { 192 | display: block; 193 | height: 30px; 194 | width: 40px; 195 | position:relative; 196 | margin: auto; 197 | font-size: 25px; 198 | text-align: center; 199 | color: black; 200 | text-shadow: 1px 1px 1px #7F7F7F; 201 | } 202 | 203 | .checkbox-yes { 204 | bottom: 57px; 205 | left: 100px; 206 | opacity:0; 207 | } 208 | 209 | .checkbox-no { 210 | bottom: 27px; 211 | right: 100px; 212 | } 213 | 214 | #watched:checked ~ .checkbox-yes { 215 | opacity:1; 216 | } 217 | 218 | #watched:checked ~ .checkbox-no { 219 | opacity:0; 220 | } 221 | 222 | input[type=submit] { 223 | width: 100px; 224 | height: 35px; 225 | font-size: 24px; 226 | cursor: pointer; 227 | } 228 | 229 | input[type=submit]:active { 230 | transition: 0s; 231 | background: linear-gradient(1deg, rgb(255, 255, 255), rgba(210, 210, 210, 0.9)); 232 | } 233 | 234 | input[type=number]::-webkit-inner-spin-button { 235 | display: none; 236 | } 237 | 238 | input:hover { 239 | box-shadow: 0 0 25px rgb(155,155,155); 240 | } 241 | 242 | input:focus { 243 | box-shadow: 0 0 25px rgb(255,255,255); 244 | } 245 | 246 | ::-webkit-input-placeholder { 247 | font: bold 100% Georgia, serif; 248 | color: rgba(0,0,0,0.2); 249 | text-shadow: 0 0; 250 | } 251 | 252 | .left-side { 253 | border-top-left-radius: 3px; 254 | border-bottom-left-radius: 3px; 255 | } 256 | 257 | .right-side { 258 | border-top-right-radius: 3px; 259 | border-bottom-right-radius: 3px; 260 | } 261 | 262 | .title { 263 | text-align: left; 264 | font-size: 130%; 265 | } --------------------------------------------------------------------------------