基于springboot框架的电脑商城项目(三)
个人资料
(一)个人资料(持久层)
1.规划sql
update t_user set python=?,email=?,gender=?,modified_user=?,modified_time=? where uid=?
select * from t_user where uid=?
2.接口与抽象方法
//根据id修改
Integer updateInfoByUid(User user);
<update id="updateInfoByUid" >
update t_user set
<!--if是条件判断标签,属性test接受的是一个返回值为boolean类型的条件,
如果test条件的结果为true则执行if标签内部的语句,注意逗号也要在标签内-->
<if test="phone!=null">phone=#{phone},</if>
<if test="email!=null"> email=#{email},</if>
<if test="gender!=null">gender=#{gender},</if>
modified_user=#{modifiedUser},
modified_time=#{modifiedTime}
where
uid=#{uid}
</update>
(二)个人资料(业务层)
1.异常规划
2.设计接口和抽象方法及实现
//修改个人资料 uid通过控制层在session中获取然后传递给业务层,并在业务层封装到User对象中
void changeInfo(Integer uid,String username,User user);
//根据id查询
User getByUid(Integer uid);
@Override
public void changeInfo(Integer uid, String username, User user) {
//查询用户是否存在
User user1=userMapper.findUid(uid);
if (user1==null || user1.getIsDelete()==1){
throw new UsernameNotFoundException("用户不存在");
}
//User对象中的数据只有phone,email,gender,username,因为springboot进行依赖
//注入的时候只注入表单中数据的值,所以需要手动将uid封装到user中
user.setUid(uid);
user.setUsername(username);
user.setModifiedUser(username);
user.setModifiedTime(new Date());
Integer rows= userMapper.updateInfoByUid(user);
if (rows!=1){
throw new UpdateException("修改时出现未知异常");
}
}
@Override
public User getByUid(Integer uid) {
User user1=userMapper.findUid(uid);
if (user1==null || user1.getIsDelete()==1){
throw new UsernameNotFoundException("用户不存在");
}
User user=new User();
user.setUsername(user1.getUsername());
// user.setModifiedUser(user1.getModifiedUser());
// user.setModifiedTime( user1.getModifiedTime());
user.setEmail( user1.getEmail());
user.setPhone(user1.getPhone());
user.setGender(user1.getGender());
return user;
}
(三)个人资料(控制层)
1.设计请求
1.设计一打开页面就发送当前用户数据的查询:
2.点击修改按钮发送用户的数据修改操作
2.处理请求
@GetMapping("/get_by_uid")
public JsonResult<User> getbyUid(HttpSession session){
User user=userService.getByUid(getuidfromsession(session));
return new JsonResult<>(ok,user);
}
@PostMapping("/change_info")
public JsonResult<Void> changeinfo(User user,HttpSession session){
Integer getuidfromsession = getuidfromsession(session);
String getusernamesession = getusernamesession(session);
userService.changeInfo(getuidfromsession,getusernamesession,user);
return new JsonResult<>(ok);
}
(四)个人资料(前端页面)
$(document).ready(function () {
$.ajax({
url:"/users/get_by_uid",
type:"GET",
data:$("#form-change-info").serialize(),
dataType:"JSON",
//2.发送ajax()的异步请求来完成用户的注册功能
success:function (json) {
if (json.state==200){
$("#username").val(json.data.username);
$("#phone").val(json.data.phone);
$("#email").val(json.data.email);
var radio=json.data.gender==0 ?
$("#gender-female") : $("#gender-male");
//prop()表示给某个元素添加属性及属性值
radio.prop("checked","checked");
}else{
alert("用户数据不存在");
}
},
error:function (xhr) {
alert("查询用户信息产生未知异常"+xhr.message);
}
});
});
//1.监听按钮是否被点击
$("#btn-change-info").click(function () {
$.ajax({
url:"/users/change_info",
type:"POST",
data:$("#form-change-info").serialize(),
dataType:"JSON",
//2.发送ajax()的异步请求来完成用户的注册功能
success:function (json) {
if (json.state==200){
alert("修改成功");
//跳转系统主页index。html
//相对路径
location.href="userdata.html";
}else{
alert("修改失败失败");
}
},
error:function (xhr) {
alert("修改产生未知异常"+xhr.message);
}
});
});
上传头像
(一)上传头像(持久层)
1.规划sql
update t_user set avatar=?,modified_user=?,modified_time=? where uid=?
2.接口设计和实现方法
//修改用户头像
Integer updateAvatarByUid(@Param("uid") Integer uid,
@Param("avatar") String avatar,
@Param("modifiedUser") String modifiedUser,
@Param("modifiedTime") Date modifiedTime);
<!-- 上传头像-->
<update id="updateAvatarByUid">
update t_user set
avatar=#{avatar},
modified_user=#{modifiedUser},
modified_time=#{modifiedTime}
where
uid=#{uid}
</update>
(二)上传头像(业务层)
1.规划异常
2.设计接口和抽象方法及实现
//修改头像
void changeAvatar(Integer uid,String avatar,String username);
//修改头像
@Override
public void changeAvatar(Integer uid, String avatar, String username) {
User user1 = userMapper.findUid(uid);
if (user1==null || user1.getIsDelete()==1){
throw new UsernameNotFoundException("用户不存在");
}
Integer rows= userMapper.updateAvatarByUid(user1.getUid(),avatar,username,new Date());
if (rows!=1){
throw new UpdateException("上传时出现未知异常");
}
}
(三)上传头像(控制层)
1.规划异常
FileEmptyException:文件为空的异常(没有选择上传的文件就提交了表单,或选择的文件是0字节的空文件)
FileSizeException:文件大小超出限制
FileTypeException:文件类型异常(上传的文件类型超出了限制)
FileUploadIOException:文件读写异常
FileStateException:文件状态异常(上穿文件时该文件正在打开状态)
2.处理异常
else if (e instanceof FileEmptyException){
result.setState(6000);
}else if (e instanceof FileSizeException) {
result.setState(6001);
} else if (e instanceof FileTypeException) {
result.setState(6002);
} else if (e instanceof FileStateException) {
result.setState(6003);
} else if (e instanceof FileUploadIOException) {
result.setState(6004);
}
3.设计请求
4.处理请求
@RequestMapping("change_avatar")
public JsonResult<String> changeAvatar(HttpSession session,
MultipartFile file) {
/**
* 1.参数名为什么必须用file:在upload.html页面的147行<input type=
* "file" name="file">中的name="file",所以必须有一个方法的参数名
* 为file用于接收前端传递的该文件.如果想要参数名和前端的name不一
* 样:@RequestParam("file")MultipartFile ffff:把表单中name=
* "file"的控件值传递到变量ffff上
* 2.参数类型为什么必须是MultipartFile:这是springmvc中封装的一个
* 包装接口,如果类型是MultipartFile并且参数名和前端上传文件的name
* 相同,则会自动把整体的数据包传递给file
*/
//判断文件是否为null
if (file.isEmpty()) {
throw new FileEmptyException("文件为空");
}
if (file.getSize()>AVATAR_MAX_SIZE) {
throw new FileSizeException("文件超出限制");
}
//判断文件的类型是否是我们规定的后缀类型
String contentType = file.getContentType();
//如果集合包含某个元素则返回值为true
if (!AVATAR_TYPE.contains(contentType)) {
throw new FileTypeException("文件类型不支持");
}
//上传的文件路径:.../upload/文件名.png
/**
* session.getServletContext()获取当前Web应用程序的上下文
* 对象(每次启动tomcat都会创建一个新的上下文对象)
* getRealPath("/upload")的/代表当前web应用程序的根目录,通过该相
* 对路径获取绝对路径,返回一个路径字符串,如果不能进行映射返回null,单
* 斜杠可要可不要
*/
String parent =
session.getServletContext().getRealPath("/upload");
System.out.println(parent);//调试用
//File对象指向这个路径,通过判断File是否存在得到该路径是否存在
File dir = new File(parent);
if (!dir.exists()) {//检测目录是否存在
dir.mkdirs();//创建当前目录
}
//获取这个文件名称(文件名+后缀,如avatar01.png,不包含父目录结构)用UUID
// 工具生成一个新的字符串作为文件名(好处:避免了因文件名重复发生的覆盖)
String originalFilename = file.getOriginalFilename();
System.out.println("OriginalFilename="+originalFilename);
int index = originalFilename.lastIndexOf(".");
String suffix = originalFilename.substring(index);
//filename形如SAFS1-56JHIOHI-HIUGHUI-5565TYRF.png
String filename =
UUID.randomUUID().toString().toUpperCase()+suffix;
//在dir目录下创建filename文件(此时是空文件)
File dest = new File(dir, filename);
//java可以把一个文件的数据直接写到同类型的文件中,这里将参数file中的数据写入到空文件dest中
try {
file.transferTo(dest);//transferTo是一个封装的方法,用来将file文件中的数据写入到dest文件
/**
* 先捕获FileStateException再捕获IOException是
* 因为后者包含前者,如果先捕获IOException那么
* FileStateException就永远不可能会被捕获
*/
} catch (FileStateException e) {
throw new FileStateException("文件状态异常");
} catch (IOException e) {
//这里不用打印e,而是用自己写的FileUploadIOException类并
// 抛出文件读写异常
throw new FileUploadIOException("文件读写异常");
}
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
String avatar = "/upload/"+filename;
userService.changeAvatar(uid,avatar,username);
//返回用户头像的路径给前端页面,将来用于头像展示使用
return new JsonResult<>(OK,avatar);
}
(四)上传头像(前端页面)
1.前端页面代码
2.前端页面优化
方式1:直接在配置文件application.properties中进行配置:
方式2:采用java代码的形式来设置文件的上传大小的限制:
@Bean
public MultipartConfigElement getMultipartConfigElement() {
//1.创建一个配置的工厂类对象
MultipartConfigFactory factory = new MultipartConfigFactory();
//2.设置需要创建的对象的相关信息
factory.setMaxFileSize(DataSize.of(10, DataUnit.MEGABYTES));
factory.setMaxRequestSize(DataSize.of(15,DataUnit.MEGABYTES));
//3.通过工厂类创建MultipartConfigElement对象
return factory.createMultipartConfig();
}
3.头像回显
1.删掉在upload.html的上传头像的表单中加的三个属性:action=“/users/change_avatar”,method=“post”,enctype=“multipart/form-data”.加上id属性:id=“form-change-avatar”
2.把153行的input标签里面的type="submit"改为type=“button”(因为submit按钮不能添加事件,所以要改为普通的按钮)并加上属性id=“btn-change-avatar”
<script>
$("#btn-change-avatar").click(function () {
$.ajax({
url: "/users/change_avatar",
type: "POST",
data: new FormData($("#form-change-avatar")[0]),
processData: false,//处理数据的形式,关闭处理数据
contentType: false,//提交数据的形式,关闭默认提交数据的形式
dataType: "JSON",
success: function (json) {
if (json.state == 200) {
alert("头像修改成功")
//将服务器端返回的头像地址设置到img标签的src属性上
//attr(属性,属性值)用来给某个属性设值
$("#img-avatar").attr("src",json.data);
} else {
alert("头像修改失败")
}
},
error: function (xhr) {
alert("修改头像时产生未知的异常!"+xhr.message);
}
});
});
</script>
4.登录后显示头像
可以在每次用户登录成功后将avatar保存在cookie中,登录的业务层返回给控制层user对象,该对象包含uid,username,avatar.所以要在登录页面login.html中将服务器返回的头像路径设置到cookie中,然后每次检测到用户打开上传头像页面,在这个页面中通过ready()方法来自动读取cookie中头像路径并设到src属性上。
<script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
$.cookie(key,value,time);//time单位:天
success: function (json) {
if (json.state == 200) {
location.href = "index.html";
$.cookie("avatar",json.data.avatar,{expires: 7});
} else {
alert("登录失败")
}
},
<script src="../bootstrap3/js/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
$(document).ready(function(){
var avatar = $.cookie("avatar");
console.log(avatar);//调试用
$("#img-avatar").attr("src",avatar);
})
5.显示最新头像
上传头像后不重新登录而是浏览其他页面,然后再进入个人头像页面时展示的头像是上次上传的,因为此时cookie中的值是上次上传的头像的路径,所以需要上传头像后使用同名覆盖更改cookie中路径
$.cookie("avatar",json.data,{expires: 7});
后记
👉👉💕💕美好的一天,到此结束,下次继续努力!欲知后续,请看下回分解,写作不易,感谢大家的支持!! 🌹🌹🌹