前端ajax已经发送请求了,发送到后端的是二进制的数据,现在后端就要获取二进制的数据
后端代码的实现
注意:
需要在项目导入上传相关的jar包
1. 在在单元方法中获取上传请求的请求数据分析
传统的请求中,上传的数据是键值对数据,我们可以直接使用request对象中
的getParameter(“键名”)来获取请求数据,或者在单元方法上声明形参来
接收DispatcherServlect传递的请求数据。
而在上传请求中,请求数据是二进制流数据,tomcat服务器在接收到请求后,仍然将请求数据封装到request对中,调用DispatcherServlet处理请求,并将存储了上传请求数据的request对象作为实参传递给DispatcherServlet,而DispatcherServlet会根据请求调用对 应的单元方法来处理请求,而这个时候因为request中存储的是二进制请求数据
我们就无法再使用req.getParameter来获取请求数据了。我们希望 DispatcherServlet将request对象中的二进制数据进行解析,然后将解析后的结 果传递给单元方法处理。也就是说DispatcherServlet会调用一个工具类来完成
二进制数据的解析,所以需要我们在springmvc.xml文件中配置上传解析的bean
对象给DispatcherServlet使用。其实说白了就是需要在springmvc.xml文件中
配置SpringMVC官方提供的上传解析bean即可,我们正常的在单元方法上,声
明形参直接接收解析后的结果完成请求处理即可。
- 将上传的资源存储到服务器的硬盘中
① 确定资源要写入到硬盘中的存储路径
② 确定文件存储的文件名,每次存储的文件名都是唯一的。
③ 使用IO流将文件输出到服务器硬盘中存储起来
- 将上传的结果响应给浏览器
① 设置单元方法的返回值类型为void
② 使用response对象完成直接响应
③ 响应一个json字符串给浏览器
{
state:true,
msg:“服务器繁忙”,
url:”上传成功的资源的请求地址”
}
2 在需要在springmvc.xml文件中配置SpringMVC官方提供的上传解析bean即可
也就是在springmvc.xml里面配置一个东西解析二进制,之后在controller层直接使用解析后的结果就可以了。如何解析就是我们配置的东西进行的,我们不需要关心,我们只需要配置就可以了
<!--配置上传解析bean:给DispatcherServlet使用,调用该bean对象完成request对象中的上传数据的解析-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>
3controller层的代码
在这个controller层直接获取二进制的信息就可以了。这个里面就是io流的写操作,将资源写到本地的硬盘里面。
2. 将上传的资源存储到服务器的硬盘中
① 确定资源要写入到硬盘中的存储路径
② 确定文件存储的文件名,每次存储的文件名都是唯一的。
③ 使用IO流将文件输出到服务器硬盘中存储起来
3. 将上传的结果响应给浏览器
① 设置单元方法的返回值类型为void
② 使用response对象完成直接响应
③ 响应一个json字符串给浏览器
{
state:true,
msg:“服务器繁忙”,
url:”上传成功的资源的请求地址”
}
@Controller
public class RegController {
//声明单元方法:处理文件上传请求
/*** * 形参MultipartFile * 该形参是用来接收DispatcherServlet解析request对象后存储了文件二进制数据的对象。 * 形参的名字必须是上传请求中的文件的键名 * @param photo * @param response */
@RequestMapping("regUpload")
public void regUpload(MultipartFile photo, HttpServletResponse response, HttpServletRequest request) throws IOException {
//1.确定文件存储路径
//使用ServletContext对象动态获取项目根目录下的upload文件夹的路径,作为资源存储路径
String path=request.getServletContext().getRealPath("/upload");
System.out.println(path);
//2.确定文件存储的名字
//获取文件的原始名 ab.c.jpg
String oldName=photo.getOriginalFilename();
//获取文件存储的后缀名
String suffix=oldName.substring(oldName.lastIndexOf("."));//.jpg
//创建文件新的名字 名+后缀 比如 a.jpg
String newName= UUID.randomUUID()+""+suffix;
//3.完成存储
//创建file对象存储资源路径
File f=new File(path);
if(!f.exists()){
f.mkdirs();//创建存储路径
}
//输出存储
photo.transferTo(new File(f,newName));
//4.响应结果
//创建UploadResult对象存储响应数据
UploadResult uploadResult=new UploadResult(true,"",newName);
//将uploadResult对象转换为json对象
String jsonStr=new Gson().toJson(uploadResult);
//直接响应
response.getWriter().write(jsonStr);
}
}
返回的是一个json格式
4 上传成功的图片的回显
后端已经将图片保存到对应的路径下了
这个是返回的实体类,里面的url是图片的新名字
//创建UploadResult对象存储响应数据
UploadResult uploadResult=new UploadResult(true,"",newName);
前端要回显,就是要获取后端传到前段的数据
<td>
<input type="file" id="file" value=> <a id="btnUpload" href="javascript:void(0)">点击上传</a>
<input type="hidden" name="img" id="img" value="" >
<img src="" alt="" id="myImg" width="100px" style="display: none">
</td>
success:function (data) {
//回调函数
//将响应数据转换为json对象
eval("var obj="+data);
//判断
if(obj.status==true){
alert("上传成功");
$('#img').val(obj.url);
$('#myImg').attr("src","upload/"+obj.url).css("display","");
}else{
alert(obj.msg);
}
}
以下的这个就是回显代码
$('#myImg').attr("src","upload/"+obj.url).css("display","");
放行upload文件夹
以上图片就可以实现上传了