Spring MVC 学习笔记 --- [SpringMVC的文件上传与拦截器,以及更新登录用户头像的简易案例]
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring MVC 学习笔记 --- [SpringMVC的文件上传与拦截器,以及更新登录用户头像的简易案例]相关的知识,希望对你有一定的参考价值。
紧接之前的笔记 --> springmvc学习笔记3(,AJAX交互请求,JSON格式响应;中文乱码配置)
文章目录
1.文件上传
需要借助文件上传的工具包;
在maven引入资源即可
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
还需要在xml配置文件中配置springmvc的相关配置;
文件解析器;这里设置最大上传量为10M;
<!--文件解析器,这里配置最大上传大小为10m-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760"></property>
</bean>
在控制层的方法中使用方法参数类型CommonsMultipartFile
即可接受文件
@RequestParam(“fileName”) CommonsMultipartFile file 接收文件;
file.getOriginalFilename();获得原始文件名
file.getContentType();获得文件类型
file.getInputStream();获得输入流对象
2.拦截器
之前分析过,SpringMVC 定义了拦截器接口 HandlerInterceptor
;
会对配置的路径进行拦截处理;也可以配置不对某些指定的路径进行拦截;
再具体自定义使用时,定义一个类继承这个HandlerInterceptor
接口,比较人性化的是,只需要重写需要的方法即可;而不是像之前那样需要将方法全部重写;
方法1:preHandle
预处理方法;
实现处理器方法的预处理,就是在处理器方法执行之前这个方法会被执行,相当于拦截了处理器方法,框架会传递请求和响应对象给该方法,第三个参数为被拦截的处理器方法。
preHandle 方法返回 true 表示继续流程
(如调用下一个拦截器或处理器方法),
返回 false 表示流程中断
,不会继续调用其他的拦截器或处理器方法,此时需要通过 response 来产生响应;
方法2:postHandle
后处理方法;
实现处理器方法的后处理,就是在处理器方法调用完成,但在渲染视图之前,该方法被调用,
此时可通过 modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理。
目前不进行使用;
方法3:afterCompletion
整个请求处理完毕,视图渲染完毕时该方法被执行。
例如简易拦截器的配置
//简易的登录拦截配置;
public class LoginInter implements HandlerInterceptor
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
HttpSession session = request.getSession();
People people = (People) session.getAttribute("people");
if(people==null)
response.getWriter().print("202");
return false;
else
return true;
另外仅实现接口还是不够的,需要去配置用哪个拦截器进行哪些拦截,
当然,这里不是在web,xml
中进行配置;
在spring-mvc.xml
配置文件中进行配置;
一般使用<mvc:mapping path="/**"/>
拦截所有请求路径;
当然,还要配置不拦截的请求<mvc:exclude-mapping path=""/>
在path中填入即可;
例如对刚才的拦截器进行配置;
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--匹配拦截所有路径-->
<mvc:mapping path="/**"/>
<!--选择不拦截什么路径-->
<mvc:exclude-mapping path="/wantLogin/toLogin"/>
<mvc:exclude-mapping path="/css/**"/>
<mvc:exclude-mapping path="/js/**"/>
<mvc:exclude-mapping path="/img/**"/>
<mvc:exclude-mapping path="/**.html"/>
<!--自定义的拦截器注入-->
<bean id="LoginInter" class="com.xiaozhire0.ssm.utils.LoginInter"/>
</mvc:interceptor>
</mvc:interceptors>
3.更新登录用户头像案例搭建;
将本机文件夹托管给tomcat使用;
由于是web项目,在项目启动后,访问到的图片其实已经不是本机上的文件夹了,而是访问部署的服务器;
所以首先要将使用的文件夹交给tomcat;
其实也可以在tomcat安装下的配置文件中进行设置,或者将文件夹放到tomcat安装下的webapps内;
但是IDEA设置的话比较方便,只需要一个小小的设置,就能将文件夹交给tomcat进行使用管理;
比如我一会就将这个文件夹xiaozhire0userimg
作为用户上传头像的存储仓库;
一会就可使用 IP 端口/xiaozhire0userimg
访问到这个文件夹的内容;
具体的操作很便捷,直接在tomcat的配置处点击external Sources
;配置托管的外部资源;
选择指定文件夹即可
先同意,查看无误后点击OK;
具体的搭建
(1)在上次登录案例的基础上进行初步修改
在上一篇笔记Spring MVC 学习笔记(3) — [SpringMVC的数据响应(Ajax提交请求后,用JSON格式响应数据)]
就做了基础的登录;
这里需要给之前的数据表t_spandmb
中加入新的字段:
old_file_name
旧文件名 new_file_name
新文件名;
为了上传头像的搭建使用;
然后实体类People
也修改一下,
加入新的属性oldFileName
;newFileName
;采用驼峰命名法,因为之前在mybatis的配置文件中已经设置开启了驼峰命名匹配;
/**
* @author by CSDN@小智RE0
* @date 2021-11-21 12:25
* 人类;
*/
//将这个类注入到spring;
@Component
public class People
//这边的话,就保持和数据库的字段名一致吧;
private Integer id;
private String name;
private String password;
private Integer age;
@DateTimeFormat(pattern = "YYYY-MM-dd")
private Date birthday;
//旧文件名,新文件名;
private String oldFileName;
private String newFileName;
public String getOldFileName()
return oldFileName;
public void setOldFileName(String oldFileName)
this.oldFileName = oldFileName;
public String getNewFileName()
return newFileName;
public void setNewFileName(String newFileName)
this.newFileName = newFileName;
public Integer getId()
return id;
public void setId(Integer id)
this.id = id;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getPassword()
return password;
public void setPassword(String password)
this.password = password;
public Integer getAge()
return age;
public void setAge(Integer age)
this.age = age;
public Date getBirthday()
return birthday;
public void setBirthday(Date birthday)
this.birthday = birthday;
(2)分析流程;
-
用户将图片上传过来,后台接收到文件后,需要在服务器的指定位置创建一个位置存放用户的头像;
然后需要将该用户头像的文件名称存入数据库;
当然这个可以自己规定头像名的具体格式, -
还要考虑到用户后来需要更新头像,数据库的文件名可能与仓库的头像文件名不一致,所以这个存入的数据需要跟随存入仓库的头像文件名一致;并且这个执行的SQL语句实际上是更新语句;根据用户的ID修改用户的信息;
-
还有用户在访问服务器上的图片时,需要根据自己的信息找到属于自己的文件夹,找到其中的对应文件名;所以在之前创建用户的文件夹时不能将路径写死,要动态拼入用户的专属标记作为创建的文件夹名称;
-
我这个是用户的头像更新案例,所以说要考虑到用户登陆进来的默认头像显示;
最后还考虑到新用户登录进入时可能没有头像,我这里默认一个头像;就放在xiaozhire0userimg
文件夹下的default
文件夹内;默认让新用户的头像图片链接指向此处;
(3)在登录成功处进行上传头像,
这里弹出的模态框使用了bootstrap
提供的组件;
还是比较方便的;
这里上传文件时还需要使用一个js库
;ajaxfileupload.js
还有,由于要在用户成功登录处访问头像,
这里就在登录时将用户的新头像名称放入session中;
//这里再存入用户的新头像名称;
window.sessionStorage.setItem("userNewFileName",res.data.newFileName);
在显示用户的头像时,会根据这个session取到的用户新文件的名称是否为空来决定是否显示头像;
若newFileName
为空,则显示默认路径的图片,否则,就显示用户的头像;
数据库初始化;这边没有新文件名
启动先看看效果;默认显示的头像出现了;
用户没有头像就显示默认的一个头像;
点击更新头像;即可弹出模态框;可选择文件;
mysuccess.html
页面代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>模拟登录成功页面</title>
<link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="js/jquery.1.8.3.min.js"></script>
<script type="text/javascript" src="js/ajaxfileupload.js"></script>
<script type="text/javascript">
//页面加载即触发事件;
$(function ()
//获取到session中的信息;
var peopleN = window.sessionStorage.getItem("people");
if (peopleN == null)
//简易验证,无登录则跳回首页;
location.replace("loginin.html");
//取到在登录时放入的用户新文件名
var newFileName = window.sessionStorage.getItem("userNewFileName");
//定义的头像位置链接变量 imgLinkSuccess
var imgLinkSuccess = "";
if (newFileName != "null")
//显示用户的专属文件;
imgLinkSuccess = "http://localhost:8080/xiaozhire0userimg/" + peopleN + "/" + newFileName;
else
//若用户没有头像;走默认路径;
imgLinkSuccess = "http://localhost:8080/xiaozhire0userimg/default/admin.png";
//将用户的头像存入;
$("#imgIds").html("<img src='" + imgLinkSuccess + "' width=30 height=30 />");
//用户姓名放入页面
$("#spanId").html(peopleN);
);
//上传头像时触发;
function toUpImg()
$.ajaxFileUpload(
url: 'person/uploadAvatar', //用于文件上传的服务器端请求地址
fileElementId: 'fileId', //文件上传域的ID
dataType: 'json', //返回值类型 一般设置为json
success: function (res)
//测试响应的数据信息;
console.log(res)
//这里更新后就更改原来位置的头像;
var people = window.sessionStorage.getItem("people");
//这里取到用户的数据后,将地址拼接放到父窗口; 注意,响应时用了一个类进行封装,所以一这里要取返回结果中的data中的数据;
var imgLinkUpdate = "http://localhost:8080/xiaozhire0userimg/"+people+"/"+res.data.newFileName;
//测试拼接的链接;
console.log(imgLinkUpdate);
//将图片链接替换;
$("#imgIds").html("<img src='" + imgLinkUpdate + "' width=30 height=30 />");
)
</script>
</head>
<body>
欢迎用户(✪ω✪)<span id="spanId"></span>嘿嘿
您的靓照卡在了奇怪的地方─━ _ ─━✧
<!--放置头像处-->
<span id="imgIds">
</span>
<hr/>
<!--下面的按钮处理更新头像-->
<button class="btn btn-primary btn-lg" data-toggle="modal" data-target="#myModal">
更新头像
</button>
<!-- 模态框(Modal) -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">
×
</button>
<h4 class="modal-title" id="myModalLabel">
请选择要上传的头像
</h4>
</div>
<div class="modal-body">
<form enctype="multipart/form-data">
<!--这里限制上传文件的类型-->
<input type="file" name="fileName" id="fileId" accept=".png,.gif,.jpg">
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">关闭
</button>
<button type="button" class="btn btn-primary" onclick="toUpImg()">
点击上传
</button>
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
</div>
</body>
</html>
(4)具体的配置和处理
spring-mvc.xml
中配置文件解析器
<!--文件解析器,这里配置最大上传大小为10m-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760"></property>
</bean>
需要使用的自定义工具类StringUtil
;
用来将上传的头像文件名截取更新为新的规则文件名
/**
* 自定义的String工具类
*/
public class StringUtil
/**
* 截取文件扩展名
* @param fileName 文件名
* @return
*/
public static String subFileType(String fileName)
if(fileName!=null)
return fileName.substring(fileName.lastIndexOf(".")+1);
return null;
/**
* 生成新的文件名;
* @param oldFileName 旧的文件名
* @return 新的文件名
*/
public static String getNewFileName(String oldFileName)
Spring MVC学习笔记——WebContentGenerator
Spring MVC学习—ViewSolvsolver视图解析器的详细介绍与使用案例