【技术】SSM文件上传下载

SSM上传下载

上传

上传文件的基本要求:

1、form表单提交必须是post请求:method="post"
2、添加enctype属性:enctype="multipart/form-data"

好了,接下来开始进入正题


1、首先创建一个JSP用于提交文件
regist.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <form action="${pageContext.request.contextPath}/regist" 
          method="post" enctype="multipart/form-data">
        账号:<input type="text" name="name"/><br/>
        密码:<input type="password" name="pass"/><br/>
        性别:<input type="radio" name="sex" value="1"/>男
              <input type="radio" name="sex" value="0"/>女<br/>
        年龄:<input type="number" name="age"/><br/>
        邮箱:<input type="email" name="email"/><br/>
        生日:<input type="date" name="birthday"/><br/>
        头像:<input type="file" name="file"/><br/>
        <input type="submit" value="提交"/>
    </form>
</body>
</html>

2、在SpringMVC的配置文件中添加文件上传的解析器
spring-mvc.xml

<!-- 文件上传的解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 编码格式 -->
    <property name="defaultEncoding" value="UTF-8"/>
    <!-- 配置上传文件的大小,以字节为单位;-1代表没有限制 -->
    <property name="maxUploadSize" value="-1"/>
</bean>

3、编写Controller代码
文件上传的目的地可以是数据库,也可以是磁盘。但是一般不建议放到数据库中,数据量大时会增加数据库的负担。有条件的以单独使用一台服务器来存储流媒体。
这里上传成功之后直接返回一个JSON类型的数据,告知上传成功。

@RequestMapping(value="/regist", method= {RequestMethod.GET, RequestMethod.POST})
public @ResponseBody String regist(@RequestParam MultipartFile file,Student student) {
    try {
        // 上传到本地
        // 获取文件名
        String fileName = file.getOriginalFilename();
        String headPath = "D://" + fileName;
        File dest = new File(headPath);

        // 获取文件的二进制数组
        byte[] bytes = file.getBytes();
        // 上传到数据库
        student.setHead(bytes);

        // 把数据封装到对象中
        student.setHeadPath(headPath);
        studentService.regist(student);

        // 把文件写到磁盘
        file.transferTo(dest);
        return "文件:" + fileName + "上传成功!";
    } catch (Exception e) {
        e.printStackTrace();
        return "文件上传失败!";
    }
}

4、实体类

public class Student{
    private Integer id;
    private String name;
    private String pass;
    private String sex;
    private Integer age;
    private String email;
    private String birthday;
    private byte[] head; // 头像的二进制数据
    private String headPath;// 头像的路径
    
    // 省略set/get方法
}

5、service

// 接口
public int regist(Student student);

// 实现类
public int regist(Student student) {
	return studentMapper.regist(student);
}

6、dao

// 接口
public int regist(Student student);

7、dao映射文件
mybatis默认可以省略入参的类型,所以这里没有写parameterType;
insert默认的返回值就是int类型,所以这里也没有写resultType;

<insert id="regist">
    insert into student
    (id, name, pass, age, sex, email,birthday, head) 
    values
    (seq_stu.nextval, #{name, jdbcType=VARCHAR}, #{pass, jdbcType=VARCHAR}, #{age, jdbcType=VARCHAR}, 
    #{sex, jdbcType=VARCHAR}, #{email, jdbcType=VARCHAR}, to_date(#{birthday, jdbcType=DATE},'yyyy-mm-dd'),
    #{head, jdbcType=VARBINARY})
</insert>

下载

下载的原理:通过ServletOutputStream将byte类型的数据响应到浏览器的过程。
下载的基本要求:

设置头信息:
		content-disposition
		attachement;filename=name

1、编写Controllerd代码
这里提供两种解决方案:
(1)使用ResponseEntity<byte[]>
因为在上传的时候写了直接把图片存储到数据库的操作,所以这边写了两种获取方式:
1)直接从数据库读取图片信息。
2)从数据库读取图片的路径,根据图片路径构造File对象。下面dao接口中会提到查询图片路径的方法。

@RequestMapping(value="/download" , method= {RequestMethod.GET, RequestMethod.POST})
public ResponseEntity<byte[]> download(Student student) throws Exception {
    // 通过数据库查询文件的byte[]
    // byte[] head = studentService.getHead(student);

    // 查询数据库获取文件路径
    String headPath = studentService.getHeadPath(student);
    // 构建文件对象
    File file = new File(headPath);
    // 读取文件
    FileInputStream fis = new FileInputStream(file);
    byte[] bytes = new byte[fis.available()];
    fis.read(bytes);

    // 设置头信息
    HttpHeaders hh = new HttpHeaders();
    hh.setContentDispositionFormData("attachement", "a.jpg");
    // 返回ResponseEntity对象
    // 第一个参数:要下载的文件的byte数组
    // 第二个参数:头信息,因为HttpHeaders实现了MultiValueMap<String, String>这个接口
    // 第三个参数:http状态,一般请求成200,所以要写HttpStatus.OK
    return new ResponseEntity<byte[]>(bytes, hh, HttpStatus.OK);
}

(2)使用ServletOutputStream

@RequestMapping(value="/download1" , method= {RequestMethod.GET, RequestMethod.POST})
public void download1(Student student, HttpServletResponse resp) throws Exception {
    // 查询数据库获取文件路径
    String headPath = studentService.getHeadPath(student);
    // 构建文件对象
    File file = new File(headPath);
    // 输入流读取文件
    FileInputStream fis = new FileInputStream(file);
    byte[] bytes = new byte[fis.available()];
    fis.read(bytes);
    // 设置头信息
    resp.setContentType("multipart/form-data");
    resp.setHeader("content-disposition", "attachement;filename=b.jpg");

    // 相应到浏览器
    ServletOutputStream outputStream = resp.getOutputStream();
    // 将二进制数组写到输出流中
    outputStream.write(bytes);
    outputStream.flush();
    // 关闭流
    outputStream.close();
}

2、service

// 接口
public byte[] getHead(Student student);
public String getHeadPath(Student student);

// 实现类
public byte[] getHead(Student student) {
	return (byte[]) studentMapper.getHead(student);
}

public String getHeadPath(Student student) {
	return studentMapper.getHeadPath(student);
}

3、dao
需要注意的是,service的接口中返回值类型是byte[],dao中接口的返回值类型必须是Object,否则会报错。

// 查询图片
public Object getHead(Student student);
// 查询图片路径
public String getHeadPath(Student student);

4、映射文件
注意byte[]类型的写法是:[B,写成byte[]会报类型转换错误。报错信息里也让写成[B

<select id="getHead" resultType="[B">
	select head from student where id = #{id, jdbcType=INTEGER}
</select>

<select id="getHeadPath" resultType="String">
	select headPath from student where id = #{id, jdbcType=INTEGER}
</select>
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值