我们把与数据库有关的,与增删改查有关的,都放到DAO层里,与业务逻辑有关的都放到Service层里,最终controller调用service,service调用dao。
新建一个查询:
在com.zhenzhigu.mvc.dao下的UserDao中添加代码:
User findOne(String hql,Object... objs) throws Exception;
在com.zhenzhigu.mvc.dao.impl包下的UserDaoImpl中添加代码:
@Override
public User findOne(String hql, Object... objs) throws Exception {
Query query = factory.getCurrentSession().createQuery(hql);
for(int i = 0;objs != null && i < objs.length;i++)
{
query.setParameter(i, objs[i]);
}
return query.uniqueResult();
}
//...代表0个或多个
在com.zhenzhigu.mvc.service包下的UserService中添加代码:
User findByUsername(String username) throws Exception;
在com.zhenzhigu.mvc.service.impl包下的UserServiceImpl中添加代码:
@Override
public User findByUsername(String username) throws Exception {
User user = null;
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
user = userDao.findOne("from User where username = ?",username);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw e; //service层不要吃掉异常,扔到上层去处理
}finally {
session.close();
}
return user;
}
在com.zhenzhigu.mvc.controller包下的UserController中添加代码:
@RequestMapping("/login.do")
public String login_do(
@RequestParam String username,
@RequestParam String password
)throws Exception{
User user = userService.findByUsername(username);
if(user==null) { //用户名不存在
}else {
String value=MD5Util.md5(MD5Util.md5(password)+user.getSalt());
if(value.equals(user.getPassword())) {
//登录成功
return "redirect:/user/home";
}else {
//密码错误
}
}
return "redirect:/user/login";
}
------------------------------------------------------------------------------------------------------------------------------
登录功能
在src/main/webapp下新建一个upload目录。
在upload下新建一个avatar(头像)目录,用户设置了头像之后,就把头像放到avatar目录下。
给用户添加一项头像路径的属性,在com.zhenzhigu.mvc.entity包下的User中添加代码:
private String avatar; //头像路径
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
在com.zhenzhigu.mvc.controller包下的UserController中添加代码:
package com.zhenzhigu.mvc.controller;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.zhenzhigu.mvc.entity.User;
import com.zhenzhigu.mvc.service.UserService;
import com.zhenzhigu.mvc.util.MD5Util;
/**
* 浏览器访问Java中的Method
* @author Master.Xia
*/
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired UserService userService; //从Spring中取出
@RequestMapping("/register")
public String register()throws Exception{
return "register";
}
@RequestMapping("/login")
public String login()throws Exception{
return "login";
}
@RequestMapping("/home")
public String home()throws Exception{
return "home";
}
@RequestMapping("/save")
public String save(
@RequestParam String username,
@RequestParam String password,
@RequestParam String realname,
@RequestParam int age
)throws Exception{
User user = new User(username, password, realname, age);
userService.register(user);
return "redirect:/user/register";
}
@RequestMapping("/login.do")
public String login_do(
@RequestParam String username,
@RequestParam String password,
HttpServletRequest request,
HttpServletResponse response
)throws Exception{
User user = userService.findByUsername(username);
if(user==null) { //用户名不存在
}else {
String value=MD5Util.md5(MD5Util.md5(password)+user.getSalt());
if(value.equals(user.getPassword())) {
//登录成功
request.getSession().setAttribute("LoginUser", user);
return "redirect:/user/home";
}else {
//密码错误
}
}
return "redirect:/user/login";
}
private HttpServletRequest getRequest() {
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
}
private HttpServletResponse getResponse() {
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
}
}
在src/main/webapp/WEB-INF/pages下创建home.jsp文件。
添加代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
个人中心
个人中心
账号:${sessionScope.LoginUser.username}
姓名:${sessionScope.LoginUser.realname}
头像:
在src/main/webapp/upload/avatar下添加一张图片:picture.jpg
修改com.zhenzhigu.mvc.entity包下的User中的代码:
private String avatar="picture.jpg"; //头像路径
在src/main/webapp/WEB-INF/pages下创建register.jsp文件。
添加代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
用户注册
用户注册
点击这里登录
在src/main/webapp/WEB-INF/pages下创建login.jsp文件。
添加代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
用户登录
用户登录
------------------------------------------------------------------------------------------------------------------------------
注销功能
在home.jsp文件中添加代码:
注销(退出登录)
在com.zhenzhigu.mvc.controller包下的UserController中添加代码:
@RequestMapping("/logout")
public String login_do(
HttpServletRequest request,
HttpServletResponse response
)throws Exception{
request.getSession().removeAttribute("LoginUser");
return "redirect:/user/login";
}
------------------------------------------------------------------------------------------------------------------------------
直接来到home页应该是不允许的
在home.jsp中添加代码:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
------------------------------------------------------------------------------------------------------------------------------
更换头像功能
在home.jsp文件中添加代码:
更换头像
在com.zhenzhigu.mvc.controller包下创建一个SettingsController。
添加代码:
package com.zhenzhigu.mvc.controller;
import java.io.File;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.zhenzhigu.mvc.entity.User;
import com.zhenzhigu.mvc.service.UserService;
import com.zhenzhigu.mvc.util.MD5Util;
@Controller
@RequestMapping("/settings")
public class SettingsController {
@Autowired UserService userService; //从Spring中取出
@RequestMapping(value = "/avatar",method = RequestMethod.GET)
public String avatarGet() throws Exception //展示
{
return "settings/avatar";
}
@RequestMapping(value = "/avatar",method = RequestMethod.POST)
public String avatarPost(
@RequestParam MultipartFile file,
HttpServletRequest request
)throws Exception //上传头像
{
userService.changeAvatar(request, file);
return "redirect:/settings/avatar";
}
private HttpServletRequest getRequest() {
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
}
private HttpServletResponse getResponse() {
return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getResponse();
}
}
在com.zhenzhigu.mvc.service包下的UserServiceImpl中添加代码:
@Override
public void changeAvatar(HttpServletRequest request, MultipartFile file) throws Exception {
Session session = factory.getCurrentSession();
try {
session.beginTransaction();
//1.当前登陆用户
User loginUser = (User) request.getSession().getAttribute("LoginUser");
User user = userDao.findById(loginUser.getId());
//2.创建本地文件
String real = request.getSession().getServletContext().getRealPath("/upload/avatar");
File local = new File(real,UUID.randomUUID().toString()+".jpg");
//3.文件复制
file.transferTo(local);
//4.更新数据库信息
user.setAvatar(local.getName());
userDao.update(user);
//5.更新登录信息
request.getSession().setAttribute("LoginUser",user);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
throw e; //service层不要吃掉异常,扔到上层去处理
}finally {
session.close();
}
}
在src/main/webapp/WEB-INF/pages下创建一个settings目录。
在settings目录下创建一个avatar.jsp文件。
添加代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
更改头像
更改头像
当前头像:
上传新头像:
------------------------------------------------------------------------------------------------------------------------------
声明式事务处理
上述的service里面的每一个功能都一样,启动事务,提交事务,回滚事务,关闭session。
随着功能越来越多,try,catch,finally总是要写的,非常麻烦。
所以为了解决这一问题,Spring提供了一种解决方案,叫做声明式事务处理(service层所有方法都应该有事务)。
1.在spring.xml配置文件中添加代码:
事务交给spring管理之后,current也要由spring决定
2.修改hibernate.cfg.xml配置文件中的代码:
org.springframework.orm.hibernate5.SpringSessionContext
3.执行过程中如果出现RuntimeException事务会回滚
4.Spring配置文件的命名空间要引全
修改spring.xml配置文件中的代码:
5.导入相关依赖jar包
在pom.xml配置文件中添加代码:
org.aspectj
aspectjweaver
1.8.11
6.Spring主容器不加载Controller,SpringMVC容器不加载Service:
Spring主容器:
SpringMVC容器:
经过以上六步,就可以使用事务了。
修改com.zhenzhigu.mvc.service.impl包下的UserServiceImpl中的代码:
package com.zhenzhigu.mvc.service.impl;
import java.io.File;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zhenzhigu.mvc.dao.UserDao;
import com.zhenzhigu.mvc.entity.User;
import com.zhenzhigu.mvc.service.UserService;
import com.zhenzhigu.mvc.util.MD5Util;
/**
* 业务逻辑层
*/
@Service
public class UserServiceImpl implements UserService {
@Autowired SessionFactory factory;
@Autowired UserDao userDao;
@Override
public void register(User user) throws Exception {
//保存用户之前对密码进行加密
String password = user.getPassword();
password = MD5Util.md5(password); //1.对明文密码进行MD5加密
user.setSalt(UUID.randomUUID().toString());//2.给用户随机生成一个盐值
password=MD5Util.md5(password+user.getSalt());//3.密文密码连接salt再次MD5
user.setPassword(password);
userDao.save(user);
}
@Override
public User findByUsername(String username) throws Exception {
return userDao.findOne("from User where username = ?",username);
}
@Override
public void changeAvatar(HttpServletRequest request, MultipartFile file) throws Exception {
//1.当前登陆用户
User loginUser = (User) request.getSession().getAttribute("LoginUser");
User user = userDao.findById(loginUser.getId());
//2.创建本地文件
String real = request.getSession().getServletContext().getRealPath("/upload/avatar");
File local = new File(real,UUID.randomUUID().toString()+".jpg");
//3.文件复制
file.transferTo(local);
//4.更新数据库信息
user.setAvatar(local.getName());
userDao.update(user);
//5.更新登录信息
request.getSession().setAttribute("LoginUser",user);
//throw new RuntimeException();//会触发hibernate回滚
}
}
------------------------------------------------------------------------------------------------------------------------------
功能拓展
OpenSessionInView:支持延迟加载
在web.xml配置文件中添加代码:
SpringOpenSessionInViewFilter
org.springframework.orm.hibernate5.support.OpenSessionInViewFilter
SpringOpenSessionInViewFilter
/*
Service实现类加上注解:@Transactional,代表这个类中有事务(声明式事务可以不用这个注解)
------------------------------------------------------------------------------------------------------------------------------
修改密码功能
在home.jsp文件中添加代码:
修改密码
SettingsController文件中添加代码:
@RequestMapping(value = "/password",method = RequestMethod.GET)
public String PasswordGet() {
return "settings/password";
}
@RequestMapping(value = "/password",method = RequestMethod.POST)
public void PasswordPost( //AJAX无需跳转
@RequestParam String pw1,
@RequestParam String pw2,
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
User loginUser = (User) request.getSession().getAttribute("LoginUser");
try {
userService.changePassword(loginUser.getId(),pw1, pw2);
} catch (Exception e) {
if("OldPwdErr".equals(e.getMessage()))
{
response.getWriter().print("OldPwdErr");
}
return;
}
response.getWriter().print("success");
}
在src/main/webapp/WEB-INF/pages/settings目录下创建一个password.jsp文件。
添加代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
修改密码(AJAX)
修改密码
当前密码:
新的密码:
在UserService中添加代码:
void changePassword(String oldPwd,String newPwd) throws Exception;
在UserServiceImpl中添加代码:
@Override
public void changePassword(String loginUserId,String oldPwd, String newPwd) throws Exception {
User user = userDao.findById(loginUserId);
//旧密码是否正确
if(MD5Util.md5(MD5Util.md5(oldPwd)+user.getSalt()).equals(user.getPassword()))
{
user.setSalt(UUID.randomUUID().toString());
user.setPassword(MD5Util.md5(MD5Util.md5(newPwd)+user.getSalt()));
userDao.update(user);
}
else
{
throw new RuntimeException("OldPwdErr");
}
}