SpringMVC下的图片存取方法

本人初学SSM架构,走了不少弯路,刚开始做注册登录功能,想加入上传头像的功能,摸索了好久尝试了各种方法后终于成功了,此处记录一些要点。
SSM架构搭建我就不再赘述了,网上有很多例子,搭环境,整合框架真的是特别麻烦,出错几率特别高,很多新人入门就死在这一步。。。按照某位大神教我的,配置好以后就把文件打包传到云上,下次再需要的时候下载导入,改一下名字就好了。
基本思路是将图片上传到服务器上,同时将文件路径保存在数据库中,等需要显示图片时从数据库获取图片路径,根据相对路径在jsp中显示。因为直接上传图片到数据库容易实现,但是效率较低,而且jsp读取图片时也有诸多不便,所以还是使用存储图片路径的方法,因此数据操作的框架使用Mybatis还是Hibernate并没有什么影响。

1. 数据库

我用到的用户表结构如下,读者可以直接复制,也可以根据自己需要删改。
这里写图片描述

2. 列表内容

注册页面的jsp代码如下;
其中的关键代码是form中必须要加入的enctype属性,以便使用multipartFile在Controller中接收文件。

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--之前被坑了很久的,isELIgnored属性如果不加就接收不到参数,可能是版本原因--%>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>注册</title>
</head>
<body>
<form action="/signup" method="post" enctype="multipart/form-data" id="signup-form">
    昵称<input type="text" id="nickname" name="nickname"><br/>
    密码<input type="password" id="password" name="password"><br/><input type="text" id="firstName" name="firstName"><br/><input type="text" id="lastName" name="lastName"><br/>
    头像<input type="file" id="picFile" name="picFile"><br/>
    <button type="submit">注册</button>
</form>
</body>
</html>

同时想要使用multipartFile,必须在配置文件中添加以下的multipartResolver配置信息

    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="104857600"/>
        <property name="maxInMemorySize" value="4096"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

其中maxUploadSize是控制文件上传大小的参数,可以根据自己需要设置。

3. 控制层

控制层的代码如下

@Controller
public class UserController {
    @Resource
    private UserService userService;

    @RequestMapping(value="/signup", method = RequestMethod.POST)
    public String signup(@RequestParam(value = "picFile",required = false) MultipartFile file,
                         HttpServletRequest request, @ModelAttribute User u , ModelMap model){

//      获取Servlet的运行路径下的imgs文件夹作为上传图片的存储路径
        String uploadRootPath = request.getServletContext().getRealPath("imgs/");
        System.out.println("uploadRootPath="+uploadRootPath);

//      检查图片存储路径是否存在,如果不存在,创建路径
        File uploadRootDir = new File(uploadRootPath);
        if(!uploadRootDir.exists())
            uploadRootDir.mkdirs();

//      获取源文件的文件名
        String fileName = file.getOriginalFilename();

//      创建目标文件,制定文件存储路径和文件名
        File targetFile = new File(uploadRootPath+ fileName);

        if(fileName!=null&&fileName.length()>0){
            try {
//              将源文件转移到目标文件,使用transferTo方法
                file.transferTo(targetFile);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

//      由于获取到的User对象没有userPic属性,这里补全
        u.setUserPic(fileName);
        System.out.println("fileDir="+uploadRootPath+fileName);

//      实现signUp方法,将用户信息持久化到数据库
        if(userService.signUp(u)){
//          直接将图片路径(这里是文件名)传递给login-success页面
            model.addAttribute("picpath",u.getUserPic());
            return "signup-success";
        }
        return "index";
    }

}

这里为什么传递的图片路径只有文件名呢?下面会解释。

4. signup-success.jsp

注册成功后的返回页面如下

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>注册成功!</h1>
<img src="../../imgs/${picpath}"/>
</body>
</html>

这里我为什么取 ../../imgs/${picpath} 这样一个相对路径,而不是直接放绝对路径呢?
读者可以试一下,其实这里放绝对路径是取不到文件的,这是处于安全考虑的,具体的原因我水平有限也不是太懂啦难过有大神有钻研精神的求赐教
所以我试了一下相对路径,发现果然是可以的,那这个相对路径是怎么来的呢?
读者是否还记得我在Controller中输出了图片的存储路径?我检查了这个路径后发现这是Tomcat服务器的发布路径下的一个子路径,结构如下
这里写图片描述
ROOT是项目的发布路径,imgs是我们的图片存储路径,而WEB-INF/views就是我们的jsp页面的位置,说明了什么?这说明了
request.getServletContext().getRealPath(“imgs/”) 获取的路径其实就是我们的项目在服务器上运行路径的根目录下的一个文件,了解一些前端知识的朋友们一定已经懂了。
这里就是随便举了个例子,实际应用中还是要根据用户id从数据库中获取头像的路径。。。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值