说明
本篇开始学习springmvc的知识
win10,idea社区版本,java1.8
SpringMVC
Spring MVC 本身就是 Spring 框架的一部分,可以说和 Spring 框架是无缝集成。性能方面具有先天的优越性,是当今业界最主流的 Web 开发框架
MVC
控制层(Controller):负责接收并转发请求,对请求进行处理后,指定视图并将响应结果发送给客户端。
视图层(View):负责格式化数据并把它们呈现给用户,包括数据展示、用户交互、数据验证、界面设计等功能。
数据模型层(Model):模型对象拥有最多的处理任务,是应用程序的主体部分,它负责数据逻辑(业务规则)的处理和实现数据操作(即在数据库中存取数据)
执行流程
实例
1 2 3 4 5 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 <packaging>war</packaging> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>5.2.16.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.13</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.20</version> </dependency> <!-- Spring Test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency> <!-- servlet api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> </project>
将pom.xml中的package改为war,加入springMVC,就是web工程
war 这里默认是pom,我改成了war,经过测试没有区别
1 2 3 4 5 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" version="4.0"> <!--编码过滤器,解决post乱码问题--> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <!--中央控制器,用于处理请求--> <servlet-name>DispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:spring-mvc.xml</param-value> </init-param> <!--启动级别 1 表示服务器启动,这个项目也跟着启动--> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>DispatcherServlet</servlet-name> <!--,所有的请求都需要通过DispatcherServlet --> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 启用Spring的Session --> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> </web-app>
发现报错:URI is not registered (Settings | Languages & Frameworks | Schemas and DTDs)
在idea中按照报错的步骤把http://xmlns.jcp.org/xml/ns/javaee
加入进去即可
上方的配置文件,需要加载spring的配置文件,在resources下新建spring-mvc.xml文件
1 2 3 4 5 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--扫包,spring可以识别此包以及子包下的类中的spring相关注解,比如Service,Controller,Component等--> <context:component-scan base-package="xyz.shi" /> <!-- 配置@controller扫描包 --> <!--<context:component-scan base-package="cn.book.controller" />--> <context:annotation-config/> <!-- 配置注解驱动,相当于同时使用最新处理器映射跟处理器适配器,对json数据响应提供支持 --> <mvc:annotation-driven enable-matrix-variables="true"/> <!--对webapp下的静态文件放行,不去走中央控制器--> <mvc:default-servlet-handler /> <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8&allowMultiQueries=true&serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean> <!-- 配置jdbc --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置事务管理器 --> <!-- <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">--> <!-- <property name="dataSource" ref="dataSource"/>--> <!-- </bean>--> <!-- 配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> <!-- 配置拦截器--> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/users/**"/> <bean class="xyz.shi.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors> </beans>
1 2 3 4 5 6 7 8 9 public interface UserDao { boolean login(User user); void save(User user); void delete(int id); void update(User user); User findById(int id); List<User> findAll(); }
1 2 3 4 5 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 @Repository public class UserDaoImpl implements UserDao { @Autowired private JdbcTemplate jdbcTemplate; @Override public boolean login(User user) { String sql = "SELECT * FROM users WHERE name = ? AND password = ?"; List<User> users = jdbcTemplate.query(sql, new Object[]{user.getName(), user.getPassword()}, BeanPropertyRowMapper.newInstance(User.class)); if (!users.isEmpty()) { return true; } else { return false; } } @Override public void save(User user) { String sql = "INSERT INTO users (name, password) VALUES (?, ?)"; jdbcTemplate.update(sql, user.getName(), user.getPassword()); } @Override public void delete(int id) { String sql = "DELETE FROM users WHERE id = ?"; jdbcTemplate.update(sql, id); } @Override public void update(User user) { String sql ="update `users` set name = ?,password = ? where id = ? "; jdbcTemplate.update(sql, user.getName(), user.getPassword(), user.getId()); } @Override public User findById(int id) { String sql = "SELECT * FROM users WHERE id = ?"; return jdbcTemplate.queryForObject(sql, new Object[]{id}, BeanPropertyRowMapper.newInstance(User.class)); } @Override public List<User> findAll() { String sql = "SELECT * FROM users"; // 查询数据 List<User> userList = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(User.class)); return userList; } }
1 2 3 4 5 6 7 8 public interface UserService { boolean login(User user); void save(User user); void delete(int id); void update(User user); User findById(int id); List<User> findAll(); }
实现service,这里主要作用实现service层的接口,具体数据逻辑是调用的userdao层,而userdao自动关联到了他的实现层也就是UserDaoImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 @Service public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public boolean login(User user) { return userDao.login(user); } @Override public void save(User user) { userDao.save(user); } @Override public void delete(int id) { userDao.delete(id); } @Override public void update(User user) { userDao.update(user); } @Override public User findById(int id) { return userDao.findById(id); } @Override public List<User> findAll() { return userDao.findAll(); } }
Controller层的登录 主要用来处理登录和注销
1 2 3 4 5 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 31 32 33 34 35 36 37 38 39 40 41 42 43 @Controller @SessionAttributes("username") @RequestMapping("/home") public class LoginController { @Autowired private UserDao userDao; @GetMapping("/userlogin") public String userlogin() { return "userlogin"; } @PostMapping("/login") public String login(@RequestParam String username, @RequestParam String password,Model model,HttpServletRequest request) { User user1 = new User(); user1.setName(username); user1.setPassword(password); boolean flag = userDao.login(user1); if (!flag) { model.addAttribute("error", "用户名或密码错误"); System.out.println("用户名或密码错误"); // 页面路径 // return "/WEB-INF/view/user/add.jsp"; return "userlogin"; } // model.addAttribute("username", username); //将用户信息放入 session 中 request.getSession(true).setAttribute("username",username); System.out.println("登录成功"+ username); return "redirect:/users/list"; } @GetMapping("/logout") public String logout(HttpSession session,SessionStatus sessionStatus) { session.removeAttribute("username"); sessionStatus.setComplete(); System.out.println("注销成功"); System.out.println(session.getAttribute("username")); return "redirect:userlogin"; } }
Controller层的UserController 主要用来处理登录后对用户进行增删改查
1 2 3 4 5 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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 @Controller @RequestMapping("/users") public class UserController { @Autowired private UserDao userDao; @GetMapping("/list") public String list(Model model) { List<User> users = userDao.findAll(); model.addAttribute("users", users); return "userList"; } @GetMapping("/addPage") public String addPage(Model model) { return "useradd"; } @PostMapping("/add") public String add(@RequestParam String username, @RequestParam String password, Model model) { User user = new User(); user.setName(username); user.setPassword(password); userDao.save(user); System.out.println("添加用户信息成功"); return "redirect:/users/list"; } @GetMapping("/findPage") public String findPage(@RequestParam Integer id ,Model model) { User user = userDao.findById(id); if (user!=null) { model.addAttribute("user", user); } else { System.out.println("用户信息不存在"); } return "useredit"; } @PostMapping("/update") public String update(@RequestParam Integer id ,@RequestParam String username, @RequestParam String password) { User user = new User(); user.setId(id); user.setPassword(password); user.setName(username); userDao.update(user); System.out.println("更新成功"); return "redirect:/users/list"; } @GetMapping("/del") public String del(@RequestParam Integer id) { userDao.delete(id); System.out.println("删除成功"); return "redirect:/users/list"; }
LoginInterceptor 主要是对没有登录的进行拦截,自动跳转到登录界面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package xyz.shi.interceptor; import org.springframework.web.servlet.HandlerInterceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HttpSession session = request.getSession(); // 检查用户是否已登录,如果未登录则跳转到登录页 if (session.getAttribute("username") == null) { response.sendRedirect(request.getContextPath() + "/home/userlogin"); return false; } else { return true; } } }
jsp界面,路径在/WEB-INF/jsp/目录下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <h1>登录</h1> <form action="${pageContext.request.contextPath}/home/login" method="post"> <label for="username">用户名:</label> <input type="text" id="username" name="username" required><br><br> <label for="password">密码:</label> <input type="password" id="password" name="password" required><br><br> <input type="submit" value="登录"> </form> </body> </html>