24.Spring练习(spring、springMVC)
目录
一、Spring练习环境搭建。
(1)设置服务器启动的展示页面。
(2)创建工程步骤。
(3)applicationContext.xml配置文件。
(4)spring-mvc.xml配置文件。
(5)web.xml配置文件。
(6)jdbc.properties配置文件。
(7)log4j.properties配置文件。
二、SSM项目结构。
(1)conctroller层。
(1.1)RoleController类。
(1.2)UserController类。
(1.3)jsp文件的部分截取参考。
(2)service层。
(2.1)RoleService接口与RoleServiceImpl类。
(2.2)UserService接口与UserService类。
(3)dao层。
(3.1)RoleDao接口与RoleDaoImpl类。
(3.2)UserDao接口与UserDaoImpl类。
(4)domain:存放POJO类。
(4.1)Role类。
(4.2) User类。
(5)utils:存放工具类。
(6)interceptor:拦截器。
四、业务功能实现步骤。
一、Spring练习环境搭建。
(1)设置服务器启动的展示页面。
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>主页</title>
</head>
<body><%response.sendRedirect(request.getContextPath()+"/pages/main.jsp");%>
</body>
</html>
(2)创建工程步骤。
IDEA项目右键->新建->新模块 ->选择Maven->选择骨架或不选->next->命名->把项目缺少的文件添加上去。
(3)applicationContext.xml配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--1、加载jdbc.properties文件--><context:property-placeholder location="classpath:jdbc.properties"/><!--2、配置数据源对象--><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="${jdbc.Driver}"/><property name="jdbcUrl" value="${jdbc.url}"/><property name="user" value="${jdbc.user}"/><property name="password" value="${jdbc.password}"/></bean><!--3、配置JdbcTemplate对象--><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"/></bean><!--配置RoleService--><bean id="roleService" class="service.impl.RoleServiceImpl"><property name="roleDao" ref="roleDao"/></bean><!--配置RoleDao--><bean id="roleDao" class="dao.impl.RoleDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!--配置UserService--><bean id="userService" class="service.impl.UserServiceImpl"><property name="userDao" ref="userDao"/><property name="roleDao" ref="roleDao"/></bean><!--配置UserDao--><bean id="userDao" class="dao.impl.UserDaoImpl"><property name="jdbcTemplate" ref="jdbcTemplate"/></bean></beans>
(4)spring-mvc.xml配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"><!--1、mvc的注解驱动--><mvc:annotation-driven/><!--2、配置视图解析器--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/pages/"/><property name="suffix" value=".jsp"/></bean><!--3、静态资源权限开放--><mvc:default-servlet-handler/><!--4、组件扫描--><context:component-scan base-package="controller"/><!--5、拦截器配置--><mvc:interceptors><mvc:interceptor><!--配置对哪些资源执行操作--><mvc:mapping path="/"/><!--配置哪些资源排除拦截操作--><mvc:exclude-mapping path="/user/login"/><bean class="interceptor.PrivilegeInterceptor"/></mvc:interceptor></mvc:interceptors>
</beans>
(5)web.xml配置文件。
<?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"><!--Spring监听器--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!--Spring监听器的全局的初始化参数--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></context-param><!--SpringMVC的前端控制器--><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><load-on-startup>1</load-on-startup><!--表示服务器启动就创建--></servlet><servlet-mapping><servlet-name>DispatcherServlet</servlet-name><url-pattern>/</url-pattern></servlet-mapping><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>
</web-app>
(6)jdbc.properties配置文件。
jdbc.Driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8
jdbc.user=root
jdbc.password=root
注意:url中的 ?后面是防止乱码的方法之一。
(7)log4j.properties配置文件。
direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n direct messages to file mylog.log
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n set log levels - for more verbose logging change 'info' to 'debug' log4j.rootLogger=info, stdout
二、SSM项目结构。
(1)conctroller层。
(1.1)RoleController类。
package controller;
@Controller
@RequestMapping("/role")
public class RoleController {@Resource(name = "roleService")private RoleService roleService;@RequestMapping("/list")public ModelAndView list(){ModelAndView modelAndView = new ModelAndView();List<Role> roleList = roleService.list();//设置模型modelAndView.addObject("roleList",roleList);//设置视图modelAndView.setViewName("role-list");return modelAndView;}@RequestMapping("/save")//参数是用来接收表单数据public String save(Role role){roleService.save(role);return "redirect:/role/list";}
}
(1.2)UserController类。
package controller;
@Controller
@RequestMapping("/user")
public class UserController {@Resource(name = "userService")private UserService userService;@Autowiredprivate RoleService roleService;@RequestMapping("/list")public ModelAndView list(){ModelAndView modelAndView = new ModelAndView();List<User> userList = userService.list();modelAndView.addObject("userList",userList);modelAndView.setViewName("user-list");return modelAndView;}@RequestMapping("/saveUI")public ModelAndView saveUI(){ModelAndView modelAndView = new ModelAndView();List<Role> roleList = roleService.list();modelAndView.addObject("roleService",roleList);modelAndView.setViewName("user-add");return modelAndView;}@RequestMapping("/save")public String save(User user,Long[] roleIds){userService.save(user,roleIds);return "redirect:/user/list";}@RequestMapping("/del/{userId}")//Restful风格public String del(@PathVariable(name = "userId") Long userId){userService.del(userId);return "redirect:/user/list";}@RequestMapping("/login")public String login(String username, String password, HttpSession session){User user = userService.login(username,password);if (user != null){//登录成功,将user存储到sessionsession.setAttribute("user",user);return "redirect:/index.jsp";}return "redirect:/login.jsp";}
}
(1.3)jsp文件的部分截取参考。
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<tbody><c:forEach items="${roleList}" var="role"><tr><td><input name="ids" type="checkbox"></td><td>${role.id}</td><td>${role.roleName}</td><td>${role.roleDesc}</td><td class="text-center"><a href="#" class="btn bg-olive btn-xs">删除</a></td></tr></c:forEach>
</tbody>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<div class="col-md-10 data"><c:forEach items="${roleService}" var="role"><input type="checkbox" name="roleIds" value="${role.id}">${role.roleName}</c:forEach>
</div>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<script>function delUser(userId) {if (confirm("您确认要删除吗?")){location.href="${pageContext.request.contextPath}/user/del/"+userId;}}
</script>
<tbody><c:forEach items="${userList}" var="user"><tr><td><input name="ids" type="checkbox"></td><td>${user.id}</td><td>${user.username}</td><td>${user.email}</td><td>${user.phoneNum}</td><td class="text-center"><c:forEach items="${user.roles}" var="role"> ${role.roleDesc}</c:forEach></td><td class="text-center"><a href="javascript:void(0);" onclick="delUser('${user.id}')" class="btn bg-olive btn-xs">删除</a></td></tr></c:forEach>
</tbody>
(2)service层。
(2.1)RoleService接口与RoleServiceImpl类。
package service;
import domain.Role;
import java.util.List;
public interface RoleService {public void save(Role role);public List<Role> list();
}
package service.impl;
public class RoleServiceImpl implements RoleService {private RoleDao roleDao;public void setRoleDao(RoleDao roleDao) {this.roleDao = roleDao;}@Overridepublic List<Role> list() {List<Role> roleList = roleDao.findAll();return roleList;}@Overridepublic void save(Role role) {roleDao.save(role);}
}
(2.2)UserService接口与UserService类。
package service;
public interface UserService {public List<User> list();void save(User user, Long[] roleIds);void del(Long userId);User login(String username, String password);
}
package service.impl;
public class UserServiceImpl implements UserService {private UserDao userDao;public void setUserDao(UserDao userDao) {this.userDao = userDao;}private RoleDao roleDao;public void setRoleDao(RoleDao roleDao) {this.roleDao = roleDao;}@Overridepublic List<User> list() {List<User> userList = userDao.findAll();//封装userList中的每一个User的roles数据for (User user : userList) {//获得user的idLong id = user.getId();//将id作为参数,查询当前userId对应的Role集合数据List<Role> roles = roleDao.findRoleById(id);user.setRoles(roles);}return userList;}@Overridepublic void save(User user, Long[] roleIds) {//第一步:向sys_user表中存储数据Long userId = userDao.save(user);//第二步:向sys_user_role关系表中存储数据userDao.saveUserRoleRel(userId,roleIds);}@Overridepublic void del(Long userId) {//1、删除sys_user_role关系表(userId数据)userDao.delUserRoleRel(userId);//2、删除sys_user表(userId数据)userDao.del(userId);}@Overridepublic User login(String username, String password) {try {User user = userDao.findByUsernameAndPassword(username,password);return user;}catch (EmptyResultDataAccessException e){//如果有这个异常,说明搜索后的结果为空return null;}}
}
(3)dao层。
(3.1)RoleDao接口与RoleDaoImpl类。
package dao;
public interface RoleDao {public void save(Role role);public List<Role> findAll();List<Role> findRoleById(Long id);
}
package dao.impl;
public class RoleDaoImpl implements RoleDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic List<Role> findAll() {List<Role> roleList = jdbcTemplate.query("select * from sys_role", new BeanPropertyRowMapper<Role>(Role.class));return roleList;}@Overridepublic void save(Role role) {jdbcTemplate.update("insert into sys_role values(?,?,?)",null,role.getRoleName(),role.getRoleDesc());}@Overridepublic List<Role> findRoleById(Long id) {//其实就是ur表的每一个roleId把r表全部查找一遍,把ur.roleId = r.id并且ur.userId = ?的结果就是满足条件的List<Role> roles = jdbcTemplate.query("select * from sys_user_role ur,sys_role r where ur.roleId = r.id and ur.userId = ?", new BeanPropertyRowMapper<>(Role.class), id);return roles;}
}
(3.2)UserDao接口与UserDaoImpl类。
package dao;
public interface UserDao {List<User> findAll();Long save(User user);void saveUserRoleRel(Long id, Long[] roleIds);void delUserRoleRel(Long userId);void del(Long userId);User findByUsernameAndPassword(String username, String password);
}
package dao.impl;
public class UserDaoImpl implements UserDao {private JdbcTemplate jdbcTemplate;public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Overridepublic List<User> findAll() {List<User> userList = jdbcTemplate.query("select * from sys_user",new BeanPropertyRowMapper<>(User.class));return userList;}@Override//里面有,获取数据表的主键id的方式public Long save(User user) {//创建PreparedStatementCreatorPreparedStatementCreator creator = new PreparedStatementCreator() {@Overridepublic PreparedStatement createPreparedStatement(Connection connection) throws SQLException {//使用原始jdbc完成有个PreparedStatement的组件PreparedStatement preparedStatement = connection.prepareStatement("insert into sys_user values(?,?,?,?,?)", PreparedStatement.RETURN_GENERATED_KEYS);//PreparedStatement.RETURN_GENERATED_KEYS,就是1的意思,也可以写1preparedStatement.setObject(1,null);preparedStatement.setString(2,user.getUsername());preparedStatement.setString(3,user.getEmail());preparedStatement.setString(4,user.getPassword());preparedStatement.setString(5,user.getPhoneNum());return preparedStatement;}};//创建keyHolder,获取自增主键idGeneratedKeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(creator, keyHolder);//获取生成的主键long userId = keyHolder.getKey().longValue();//不能获取主键的方式//jdbcTemplate.update("insert into sys_user values(?,?,?,?,?)",null,user.getUsername(),user.getEmail(),user.getPassword(),user.getPhoneNum());return userId; //返回当前保存用户的id,该id是数据库自动生成的}@Overridepublic void saveUserRoleRel(Long userId, Long[] roleIds) {for (Long roleId : roleIds) {jdbcTemplate.update("insert into sys_user_role values(?,?)",userId,roleId);}}@Overridepublic void delUserRoleRel(Long userId) {jdbcTemplate.update("delete from sys_user_role where userId = ?",userId);}@Overridepublic void del(Long userId) {jdbcTemplate.update("delete from sys_user where id = ?",userId);}@Overridepublic User findByUsernameAndPassword(String username, String password) throws EmptyResultDataAccessException {User user = jdbcTemplate.queryForObject("select * from sys_user where username = ? and password = ?", new BeanPropertyRowMapper<>(User.class), username, password);return user;}
}
(4)domain:存放POJO类。
(4.1)Role类。
package domain;
public class Role {private Long id;private String roleName;private String roleDesc;public Long getId() {return id; }public void setId(Long id) {this.id = id; }public String getRoleName() { return roleName;}public void setRoleName(String roleName) { this.roleName = roleName;}public String getRoleDesc() { return roleDesc;}public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc;}@Overridepublic String toString() {return "Role{" +"id=" + id +", roleName='" + roleName + '\\'' +", roleDesc='" + roleDesc + '\\'' +'}';}
}
(4.2) User类。
package domain;
import java.util.List;
public class User {private Long id;private String username;private String email;private String password;private String phoneNum;//当前用户具备哪些角色private List<Role> roles;public List<Role> getRoles() { return roles; }public void setRoles(List<Role> roles) {this.roles = roles; }public Long getId() { return id; }public void setId(Long id) { this.id = id; }public String getUsername() { return username; }public void setUsername(String username) { this.username = username; }public String getEmail() { return email; }public void setEmail(String email) { this.email = email; }public String getPassword() { return password; }public void setPassword(String password) { this.password = password; }public String getPhoneNum() { return phoneNum; }public void setPhoneNum(String phoneNum) { this.phoneNum = phoneNum; }@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\\'' +", email='" + email + '\\'' +", password='" + password + '\\'' +", phoneNum='" + phoneNum + '\\'' +'}';}}
(5)utils:存放工具类。
(6)interceptor:拦截器。
package interceptor;
public class PrivilegeInterceptor implements HandlerInterceptor {//这里不需要重写三个,因为只需要用到一个,不用到(不写操作的方法)的就不重写@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//逻辑:判断用户是否登录,本质:判断session中有没有userHttpSession session = request.getSession();User user = (User) session.getAttribute("user");if (user == null){//没有登录,重定向和转发都可以//request.getRequestDispatcher("/login.jsp").forward(request,response);//可以返回trueresponse.sendRedirect(request.getContextPath()+"/login.jsp");//重定向后不能返回truereturn false;}return true;//放行,访问目标资源}
}
三、SpringMVC的视图解析器的前缀后缀添加规则:
@RequestMapping("/quick")public String quick(){* 总结:forward: 或 redirect:* 如果加了上面中的一个,那么视图解析器配置的 前缀后缀将不在添加//1. 文.件[/pages/quick.html.jsp] 未找到return "quick.html";//2. 文.件[/pages/quick.html.jsp] 未找到return "/quick.html";//3.文.件[/pages/aside.jsp.jsp] 未找到return "aside.jsp";//4.访问失败,服务器崩溃!!!,因为少加了“/"return "forward:quick.html";//5.成功访问/quick.html,不会添加前缀与后缀return "forward:/quick.html";//6.访问失败,缺少“/”,服务器收不到请求(估计定向到其他地方了(不存在的路径))return "redirect:quick.html";//7.成功访问,/quick.html,不会添加前缀与后缀return "redirect:/quick.html";//8./quick.html,return "redirect:/quick.jsp";//9.成功访问https://www.baidu.com,不会添加前缀与后缀return "redirect:https://www.baidu.com";}
总结:字符串的最前面有forward: 或 redirect:,那么就不会添加前缀和后缀。