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
中定义实现方法id
查询查询用户信息并且返回对象u1
,判断此时的u1
是否为null
,如果为null
表示当前正在登录的用户已经从数据库删除了,那么此次修改没有意义,抛出用户不存在的异常,如果不为null
,表示此次的用户仍然存在,那么 这个id
是可用的,设置在user
对象中,便于后面执行update(User user)
方法调用u1不为null
,根据用户输入的用户名查询用户信息,返回u2
,如果这个u2不为null
并且其中的用户名和当前正在登录的用户名不相同,那么说明这个用户名已经在数据库中存在了,抛出用户名已经存在的异常,反之说明这个修改过后的用户名是可用的,因此设置在user
对象中,便于后面的修改调用id
查询用户信息,返回user
user=null
,抛出用户不存在的异常user!=null
,比较user中的密码
和用户输入的旧密码oldPassword
是否相同密码不相同
,抛出密码不匹配的异常密码相同
,表示用户输入的旧密码是正确的,那么更新密码即可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
username
,email
,phone
,gender
,id
POST
@ResponseBody
session
中仍然保存着未修改的user
对象信息,因此我们在修改成功后需要重新设置session
中的user
对象。我们只需要在ajax
异步请求处理的controller
方法中重新设置即可/user/updatePassword.do
id
,oldPassword
,newPassword
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-form
是form
标签的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); //输出提示语句
}
}
});
}
}
service
中的方法,如何设置其中的返回值用户名不存在
,当前登录的用户已经被删除
等多种结果,那么这个返回值如何定义呢,只好定义为void
,用抛出异常的方式来提醒Controller
层处理true
,要么是false
,那么就可以返回boolean
,比如验证用户名,两种结果:用户名存在,用户名不存在,只需要返回布尔值即可cn.tedu.store.controller
中新建一个基类BaseController
,这个类中定义的是Controller
中比较通用的方法
,那么如果一个控制器类想用使用其中的方法,只需要继承这个基类即可session
中的user
对象,使其是最新的用户信息session
,这样拦截器就会拦截器操作个人信息的页面并且让其重新登录