用户管理模块之个人信息修改

用户管理模块之个人信息修改

功能

  1. 修改用户名
  2. 修改性别
  3. 修改邮箱
  4. 修改密码
  5. 修改头像

UserMapper中定义方法和UserMapper.xml中定义

定义接口方法

  • 定义接口方法
/**
 * 更新用户信息
 * @param user  User对象
 */
void update(User user);

定义update节点

  • 使用动态sql定义一个通用的修改方法
	<!-- 
  	void update(User user);
  	修改用户信息
   -->
  <update id="update" parameterType="cn.tedu.store.bean.User">
  	update t_user set
  	<if test="username!=null">
  		username=#{username},
  	</if>
  	
  	<if test="password!=null">
  		password=#{password},
  	</if>
  		
  	<if test="email!=null">
  		email=#{email},
  	</if>
  	
  	<if test="phone!=null">
  		phone=#{phone},
  	</if>
  	
  	<if test="image!=null">
  		image=#{image},
  	</if>
  	
  	<if test="gender!=null">
  		gender=#{gender},
  	</if>
  	
  	modified_user=#{modifiedUser},
  	modified_time=#{modifiedTime}
where id=#{id}

  </update>

测试

@Test
public void testupdate() {
	// 加载Spring的配置文件
	AbstractApplicationContext ac = new ClassPathXmlApplicationContext("spring-dao.xml");

	// 获取UserMapper的bean,这个是spring通过扫描mapper.xml文件自动为mybatis自动创建的,首字母小写
	UserMapper userMapper = ac.getBean("userMapper", UserMapper.class);

	User user=new User();
	user.setId(5);;
	user.setUsername("chenjiabing666");
	user.setPassword("chenjiabing");
	user.setGender(0);
	user.setModifiedUser("陈加兵");
	user.setModifiedTime(new Date());
	userMapper.update(user);
	
}

IUserService接口中定义方法,在UserServiceImpl中定义实现方法

分析步骤

修改用户名,邮箱,电话,性别

  1. 根据当前登录的用户id查询查询用户信息并且返回对象u1,判断此时的u1是否为null,如果为null表示当前正在登录的用户已经从数据库删除了,那么此次修改没有意义,抛出用户不存在的异常,如果不为null,表示此次的用户仍然存在,那么 这个id是可用的,设置在user对象中,便于后面执行update(User user)方法调用
  2. 如果u1不为null,根据用户输入的用户名查询用户信息,返回u2,如果这个u2不为null并且其中的用户名和当前正在登录的用户名不相同,那么说明这个用户名已经在数据库中存在了,抛出用户名已经存在的异常,反之说明这个修改过后的用户名是可用的,因此设置在user对象中,便于后面的修改调用
  3. 如果前面的内容都能正常进行,那么此时就可以更新了

修改密码

  1. 根据id查询用户信息,返回user
  2. 如果user=null,抛出用户不存在的异常
  3. 如果user!=null,比较user中的密码用户输入的旧密码oldPassword是否相同
  4. 如果密码不相同,抛出密码不匹配的异常
  5. 如果密码相同,表示用户输入的旧密码是正确的,那么更新密码即可

定义接口方法

  • IUserService中定义
	/**
	 * 修改用户信息,不包括修改密码
	 * @param id  当前正在登录的用户id
	 * @param username 用户修改的用户名
	 * @param gender  用户修改的性别
	 * @param email   用户修改的邮箱
	 * @param phone  用户修改的电话
	 * @throws UserNotFoundException   用户名不存在的异常
	 * @throws UserNameAlreadyExistException  用户名已经存在的异常
	 */
void updateUser(Integer id,String username,Integer gender,String email,String phone) throws UserNotFoundException, UserNameAlreadyExistException;


	/**
	 * 修改密码 
	 * @param id  正在登录的用户id
	 * @param oldPassword  旧密码
	 * @param newPassword  新密码
	 * @throws UserNotFoundException 当前登录的用户不存在
	 * @throws PassWordNotMatchException   //密码不匹配
	 */
	void updatePassword(Integer id,String oldPassword,String newPassword) throws UserNotFoundException, PassWordNotMatchException;

定义实现方法

  • UserServiceImpl中定义
/**
 * 1. 根据id查询用户,返回user对象,确认当前登录的用户是否存在
 * 2. 如果user=null,抛出用户不存在的异常
 * 3. 如果user!=null,表示用户存在
 * 4. 判断用户修改的用户名是否已经存在
 * 5. 如果修改的用户名已经存在并且不是当前用户名的前提下,那么抛出用户名已经存在的异常,
 */
public void updateUser(Integer id, String username, Integer gender,
		String email, String phone) throws UserNotFoundException, UserNameAlreadyExistException {
	User user=new User();  //封装修改的内容
	
	User u1=userMapper.seletUserById(id);  //根据id查询用户信息,返回user对象
	
	//如果此时登录的用户不存在,说明当前已经登录的用户被人删除了
	if (u1==null) {
		throw new UserNotFoundException("你当前登录的用户名已经被删除");  //抛出用户不存在的异常,已经从数据库中删除了
	}else {  //如果当前登录的用户仍然存在数据库中
		user.setId(id);  //此时的用户id是可用的,因此存入user对象
		User u2=userMapper.selectUserByUserName(username);  //根据用户修改的用户名查询数据库返回user对象
		//如果此时的用户名已经在数据库中存在了,并且不是当前登录的用户名
		if (u2!=null&&!u2.getUsername().equals(u1.getUsername())) {
			throw new UserNameAlreadyExistException("你输入的用户名已经存在");  //抛出用户名已经存在的异常
		}else {   //如果修改过后的用户名在数据库中不存在
			user.setUsername(username);  //说明此时的用户名可用,因此存入user对象中,便于后面的更新
			user.setEmail(email);   //设置邮箱
			user.setPhone(phone);   //设置电话号码
			user.setGender(gender);  //设置性别
			user.setModifiedUser(u1.getUsername());  //设置修改人的姓名
			user.setModifiedTime(new Date());  //设置修改的时间
			userMapper.update(user);   //此时用户信息
		}
	}
}


/**
 * 修改密码
 * 1. 根据id查询用户信息,返回user
 * 2. 如果user=null,抛出用户不存在的异常
 * 3. 如果user!=null,比较user中的密码和用户输入的旧密码oldPassword是否相同
 * 4. 如果密码不相同,抛出密码不匹配的异常
 * 5. 如果密码相同,表示用户输入的旧密码是正确的,那么更新密码即可 
 */
public void updatePassword(Integer id, String oldPassword,
		String newPassword) throws UserNotFoundException, PassWordNotMatchException {
	User user=userMapper.seletUserById(id);  //根据id查询,返回user对象
	if (user==null) {  //如果用户不存在
		throw new UserNotFoundException("当前登录的用户不存在");  //抛出用户不存在的异常
	}else {  //如果当前登录的用户存在
		if (!user.getPassword().equals(oldPassword)) { //如果返回的user对象中的密码和用户输入的旧密码不匹配
			throw new PassWordNotMatchException("输入的旧密码不匹配");
		}else {  //如果输出的旧密码正确
			User u1=new User();   //创建User对象,封装修改所需的参数
			u1.setPassword(newPassword);  //封装新密码
			u1.setId(id);  //封装id
			userMapper.update(u1);  //调用修改的方法
		}
	}	
}

测试

@Test
public void testUpdateUserService() {
	// 加载Spring的配置文件,测试的业务层,因此需要spring-dao.xml和spring-service.xml配置文件
	AbstractApplicationContext ac = new ClassPathXmlApplicationContext(
			"spring-dao.xml", "spring-service.xml");

	IUserService userService = ac.getBean("userServiceImpl",
			IUserService.class);
	
	Integer id=5;
	String username="zhengyuanmei";
	Integer gender=0;
	String email="chenjiabing@tedu.com";
	String phone="1381815155";
	
	try {
           //调用方法
		userService.updateUser(id, username, gender, email, phone);
		System.out.println("更新成功");
	} catch (UserNotFoundException e) {
		System.out.println(e.getMessage());
	} catch (UserNameAlreadyExistException e) {
		System.out.println(e.getMessage());
	}
}


@Test
public void testUpdatePasswordService() {
	// 加载Spring的配置文件,测试的业务层,因此需要spring-dao.xml和spring-service.xml配置文件
	AbstractApplicationContext ac = new ClassPathXmlApplicationContext(
			"spring-dao.xml", "spring-service.xml");

	IUserService userService = ac.getBean("userServiceImpl",
			IUserService.class);
	
	Integer id=5;
	String oldPassword="chenjiabing";
	String newPassword="5268266";
	try {
		userService.updatePassword(id, oldPassword, newPassword);
		System.out.println("密码修改成功");
	} catch (UserNotFoundException e) {
		System.out.println(e.getMessage());
	} catch (PassWordNotMatchException e) {
		System.out.println(e.getMessage());
	}
}

控制器出层UserController

功能和分析

修改个人信息(不包括修改密码和头像)

  • 修改个人信息(不包括修改密码和头像)
    • /user/updateUser.do
    • 请求参数:usernameemailphonegenderid
    • 请求方式:POST
    • 响应方式:@ResponseBody
  • 修改成功后,我们的session中仍然保存着未修改的user对象信息,因此我们在修改成功后需要重新设置session中的user对象。我们只需要在ajax异步请求处理的controller方法中重新设置即可

修改密码

  • 修改密码
    • /user/updatePassword.do
    • 请求参数:idoldPasswordnewPassword
    • 请求方式: POST
    • 响应方式:@ResponseBody
    • 密码修改成功后,我们需要让用户重新登录,因此我们需要清除session,因为我们设置了登录验证拦截器,只要访问有关个人信息的页面,我们都会先拦截验证是否登录

    ​ ​

实现

cn.tedu.store.controller中定义基类BaseController

  • 我们的id是根据session中存储的user对象获取的,但是如果此时的登录超时,那么session会被自动清除,此时的user将获取不到,因此我们需要判断获取的User对象时候为空,我们可以设计一个BaseController的类,其中定义这个方法,这个方法获取在后续的其他控制器的处理都需要这个方法,因此我们可以在基类中定义这个通用的方法,如下
/**
 * 所有Controller类中父类,如果想用用到里面的方法,可以继承这个类即可
 * @author chenjiabing
 */
public class BaseController {
	/**
	 * 获取session中的user对象,返回其中的id值
	 * @param session  HttpSession对象
	 * @return  返回id
	 * @throws Exception  登录超时的异常,说明此时的session已经不存在了
	 */
	public Integer getId(HttpSession session) throws Exception{
		User user=(User) session.getAttribute("user");
		if (user!=null) {
			return user.getId();
		}else {
			throw new Exception("登录超时间,请重新登录...");
		}
	}    
    
}

UserController中定义方法

  • UserController,其中需要用到BaseController中的方法,因此需要继承这个类
@Controller
@RequestMapping("/user")
public class UserController extends BaseController {
    /**
	 * 修改个人信息
	 * @param username  用户名
	 * @param email  邮箱
	 * @param phone  电话号码
	 * @param gender  性别
	 * @param session HttpSession对象,用户获取存储在其中的user对象
	 * @return  返回结果集
	 */
	@RequestMapping("/updateUser.do")
	@ResponseBody
	public ResponseResult<Void> updateUser(String username,String email,String phone,Integer gender,HttpSession session){
		ResponseResult<Void> result=new ResponseResult<Void>();  //创建结果集对象
		try {
			Integer id=this.getId(session);  //调用父类的方法获取id
			userservice.updateUser(id, username, gender, email, phone);  //调用业务层的方法
			//修改成功设置响应结果集
			result.setState(1);  //设置响应码
			result.setMessage("修改成功");  //设置响应内容
            session.setAttribute("user", userservice.getUserById(id));  //修改成功之后,刷新session中的user对象
		} catch (UserNotFoundException e) {   //用户不存在的异常
			result.setState(0);  //设置响应码
			result.setMessage(e.getMessage());  //设置响应内容
		} catch (UserNameAlreadyExistException e) {  //用户名已经存在的异常
			result.setState(0);  //设置响应码
			result.setMessage(e.getMessage());  //设置响应内容
		} catch (Exception e) {   //登录超时的异常
			result.setState(0);  //设置响应码
			result.setMessage(e.getMessage());  //设置响应内容
		}
		return result;
	}
    
    
    /**
	 * 修改密码的控制器方法
	 * @param session  HttpSession对象,用户获取对象id
	 * @param oldPassword   旧密码
	 * @param newPassword   新密码
	 * @return  返回结果集
	 */
	@RequestMapping("/updatePassword.do")
	@ResponseBody
	public ResponseResult<Void> updatePassword(HttpSession session,String oldPassword,String newPassword){
		ResponseResult<Void> result=new ResponseResult<Void>();  //创建结果集对象
		try {
			Integer id=this.getId(session);  //获取id
			userservice.updatePassword(id, oldPassword, newPassword);  //调用修改方法
			result.setState(1);  //设置状态码
			result.setMessage("密码修改成功");
			//清除session,用户需要重新登录
			session.invalidate();  
			
		} catch (UserNotFoundException e) {   //用户不存在异常
			result.setState(0);  //设置状态码
			result.setMessage(e.getMessage());
		} catch (PassWordNotMatchException e) {   //密码不匹配异常
			result.setState(0);  //设置状态码
			result.setMessage(e.getMessage());
		} catch (Exception e) {   //  登录超时的异常
			result.setState(0);  //设置状态码
			result.setMessage(e.getMessage());
		}
		return result;  //返回结果
	}
    
}

页面

修改个人信息的页面(不包括修改密码)

  • 获取表单数据使用的$("#personInfo-form").serialize()方法
    • personInfo-formform标签的id
    • form表单中的name要和controller方法中的参数字段一样,否则不能对应接收
    • 这个方法是获取表单中的input节点,并且将表单参数封装成请求参数
//异步请求
	$.ajax({
		url:"<%=request.getContextPath()%>/user/updateUser.do",
		type:"POST",
		dataType:"json",
		data:$("#personInfo-form").serialize(),   //封装请求参数
		success:function(obj){
			alert(obj.message);
			//如果成功修改
			if(obj.state==1){
				//重定向到个人信息页面,相当于刷新页面了,那么此时修改的信息会更新在页面中
				window.location.href="<%=request.getContextPath()%>/user/showPersonInfo.do";
			}
		}
	})

安全验证的页面(修改密码)

  • 密码修改完成之后,使用window.location重定向到登录界面
//验证密码长度在6-9位之间,参数为密码
function checkPasswordLength(pwd){
	return pwd.length>=6&&pwd.length<=9;   
}

//验证新密码和确认新密码是否相同
function checkPasswordEquals(){
	var newPassword=$("#newPassword").val(); //新密码
	var confirmPassword=$("#confirmPassword").val();  //确认新密码
	return newPassword==confirmPassword;   
}

//旧密码失去焦点验证密码长度
$("#oldPassword").blur(function(){
	if(!checkPasswordLength($(this).val())){
		$("#oldPasswordSpan").text("密码长度在6-9位之间");
		$("#oldPasswordSpan").css("color","red"); 
	}else{
		$("#oldPasswordSpan").text("密码格式正确");
		$("#oldPasswordSpan").css("color","green"); 
	}
});

//新密码失去焦点验证密码长度
$("#newPassword").blur(function(){
	if(!checkPasswordLength($(this).val())){
		$("#newPasswordSpan").text("密码长度在6-9位之间");
		$("#newPasswordSpan").css("color","red"); 
	}else{
		$("#newPasswordSpan").text("密码格式正确");
		$("#newPasswordSpan").css("color","green"); 
	}
});


//确认密码失去焦点验证与新密码是否一致
$("#confirmPassword").blur(function(){
	//如果密码不一致
	if(!checkPasswordEquals()){
		$("#confirmPasswordSpan").text("密码与新密码不一致");
		$("#confirmPasswordSpan").css("color","red");
	}else{
		$("#confirmPasswordSpan").text("");
	}
});


//修改密码的方法
function updatePassword(){
	var newPassword=$("#newPassword").val(); // 新密码
	var oldPassword=$("#oldPassword").val();   // 旧密码
	var d={"newPassword":newPassword,"oldPassword":oldPassword };  // 封装请求数据
	var url="<%=request.getContextPath()%>/user/updatePassword.do";  // 请求的url
	
	//如果验证的条件都完成了,那么可以发出请求
	if(checkPasswordLength(newPassword)&&checkPasswordLength(oldPassword)&&checkPasswordEquals()){
		$.post(url,d,function(data,status,xhr){
			//响应成功
			if(status=="success"){
				//如果修改成功
				if(data.state==1){
					alert(data.message);   //输出提示语句
					//重定向到登录界面
					window.location="<%=request.getContextPath()%>/user/showLogin.do";
				}else{  //如果修改失败
					alert(data.message);  //输出提示语句
				}
			}
		});
	}
}

总结

  1. 对于service中的方法,如何设置其中的返回值
    1. 如果这个返回值不好定义,比如更新用户信息,可能出现用户名不存在当前登录的用户已经被删除等多种结果,那么这个返回值如何定义呢,只好定义为void,用抛出异常的方式来提醒Controller层处理
    2. 如果返回值要么是true,要么是false,那么就可以返回boolean,比如验证用户名,两种结果:用户名存在,用户名不存在,只需要返回布尔值即可
  2. 我们可以在cn.tedu.store.controller中新建一个基类BaseController,这个类中定义的是Controller中比较通用的方法,那么如果一个控制器类想用使用其中的方法,只需要继承这个基类即可
  3. 在修改用户信息之后,不要忘记更新存储在session中的user对象,使其是最新的用户信息
  4. 修改密码完成之后,我们需要清空session,这样拦截器就会拦截器操作个人信息的页面并且让其重新登录

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏你不就像风一样

MongoDB非关系型数据库开发手册

NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。

1502
来自专栏java技术学习之道

Java线程面试题合集(含答案)

1964
来自专栏PhpZendo

MVC 框架中的路由器(Router)是如何跑起来的

MVC 路由器(Router)或分发器(Dispatcher)会检测 HTTP 请求的 URL,并尝试将单个 URL 组件与控制器和控制器中定义的方法匹配,同时...

991
来自专栏前端侠2.0

asp。net5的依赖注入 原

昨天读asp.net5的doc,看到了configure的配置时,提到在controller中访问配置就是通过依赖注入的。asp.net5的很多功能都通过依赖注...

971
来自专栏JAVA烂猪皮

JAVA多线程与并发学习总结

使用高速缓存来作为内存与处理器之间的缓冲,将运算需要用到的数据复制到缓存中,让计算能快速进行;当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存...

731
来自专栏Java 源码分析

MyBatis笔记二:配置

可以看到我们使用 <properties resource="db.properties"/> 引入了我们的数据据库的配置文件,然后这个标签有两个属性 : r...

1782
来自专栏Kevin-ZhangCG

[ Java面试题 ]并发篇

1282
来自专栏大闲人柴毛毛

程序员必知的并发编程注意事项

获取单例对象需要保证线程安全,其中的方法也要保证线程安全。 单例对象会被多线程共享,因此要保证它是线程安全的,它其中的方法都要保证是线程安全的。 工具类、资源...

4035
来自专栏智能大石头

新生命开发团队Orm框架XCode v3.5.2009.0714源码发布(圣诞随心大礼包)

忙忙碌碌有一年!做了很多东西,到头来,似乎又什么都没有做。人继续变老,程序继续改进。     这段时间从我们各个系统抽取了基础的常用的部分,整理后形成了一个...

2097
来自专栏醒者呆

Debug EOS:nodeos + mongo_db_plugin

nodeos开始运行前,要先使用项目的总CmakeList.txt配置,这里我配置了boost库的位置,如果你配置了boost的环境变量可以跳过这里。

3991

扫码关注云+社区

领取腾讯云代金券