上传头像,更换头像等功能开发(含声明式事务处理)

我们把与数据库有关的,与增删改查有关的,都放到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");		
		}
	}

你可能感兴趣的:(Java,Web)