SpringMVC ファイルのアップロードとダウンロード (SpringMVC の知識を使用してファイルをアップロードおよびダウンロードする方法を説明する非常に詳細なブログ)

目次

序文

1. ファイルのアップロード

1.多機能ビューパーサー(spring-mvc.xml)の設定

2. ファイルアップロードページ(upload.jsp)を追加します。

アップロード.jsp

3. ハードディスクのネットワーク パス マッピングを実行します。

4. ページジャンプを処理するクラスを作成する

ページコントローラー.java

 ClazzController.java

5. ファイルアップロードの事前シミュレーション

6. 設定ディレクトリ内の設定ファイル

リソース.プロパティ

7. 最後にファイルのアップロードと表示を実現します

2. ファイルのダウンロード

メソッドコード

 jspページコード

効果試験

 3. 複数ファイルのアップロード

jspページ表示コード

複数のファイルアップロード方法

 複数のファイルのアップロードをテストする

 4. 拡張機能(jrebelプラグインアプリケーション)

プラグインのインストール

プロキシサーバーを開く

jrebelスタートプロジェクト

 フォローアップメモ


序文

        前回のブログ投稿では、追加、削除、変更、チェックをシミュレートする SpringMVC フレームワークの 4 つの主要な機能の実装について学びましたが、今日は SpringMVC によって実装されたファイルのアップロードおよびダウンロード機能のシミュレーションをお届けします。一緒に見つけてください。

Spring MVC では、ファイルのアップロードとダウンロードは、Web アプリケーションを介してファイルをアップロードおよびダウンロードすること        を指しますSpring MVC は、ファイルのアップロードおよびダウンロードのプロセスを処理するための便利な方法をいくつか提供します。ファイルのアップロードに関しては、MultipartFile オブジェクトを使用して、クライアントによってアップロードされたファイルを受信して​​処理できます。ファイルのダウンロードに関しては、Spring MVC の ResponseEntity クラスと InputStreamResourceクラスを使用してファイルのダウンロード機能を実装できます。

        ファイルをアップロードするには、コントローラー メソッドのパラメーターでMultipartFile 型のパラメーターを宣言してアップロードされたファイルを受け取り、MultipartFile オブジェクトの一部のメソッド (getOriginalFilename() など) を通じて元の名前とファイルの名前を取得します。 、getSize() など)サイズやその他の情報。ファイルを受信したら、指定した場所に保存したり、さらに処理したりできます。

1. ファイルのアップロード

1.多機能ビューパーサー(spring-mvc.xml)の設定

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
      http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--1) 扫描com.zking.zf及子子孙孙包下的控制器(扫描范围过大,耗时)-->
    <context:component-scan base-package="com.yx"/>

    <!--2) 此标签默认注册DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
    <mvc:annotation-driven />

    <!--3) 创建ViewResolver视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!-- viewClass需要在pom中引入两个包:standard.jar and jstl.jar -->
        <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView"></property>
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--4) 单独处理图片、样式、js等资源 -->
     <mvc:resources location="/static/" mapping="/static/**"/>

<!--    处理文件的上传下载的问题-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 文件最大大小(字节) 1024*1024*50=50M-->
        <property name="maxUploadSize" value="52428800"></property>
        <!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
        <property name="resolveLazily" value="true"/>
    </bean>

     <aop:aspectj-autoproxy/>
</beans>

主なことは、次のコードを追加することです

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- 必须和用户JSP 的pageEncoding属性一致,以便正确解析表单的内容 -->
    <property name="defaultEncoding" value="UTF-8"></property>
    <!-- 文件最大大小(字节) 1024*1024*50=50M-->
    <property name="maxUploadSize" value="52428800"></property>
    <!--resolveLazily属性启用是为了推迟文件解析,以便捕获文件大小异常-->
    <property name="resolveLazily" value="true"/>
</bean>

spring-mvc.xml ファイルを追加する前に、関連する依存関係とプラグインも pom.xml にインポートする必要があります。

2. ファイルアップロードページ(upload.jsp)を追加します。

アップロード.jsp

<%--
  Created by IntelliJ IDEA.
  User: 86158
  Date: 2023/9/9
  Time: 16:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>班级logo上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/clz/upload" method="post" enctype="multipart/form-data">
    <label>班级编号:</label><input type="text" name="cid" readonly="readonly" value="${param.cid}"/><br/>
    <label>班级图片:</label><input type="file" name="photo"/><br/>
    <input type="submit" value="上传图片"/>
</form>
</body>
</html>

3. ハードディスクのネットワーク パス マッピングを実行します。

4. ページジャンプを処理するクラスを作成する

ページコントローラー.java

package com.yx.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-10 17:03
 * 处理页面跳转的
 */
@Controller
@RequestMapping("/page")
public class PageController {

    @RequestMapping("/page/{page}")
public String toPage(@PathVariable("page") String page){
    return page;
}


    @RequestMapping("/page/{dir}{page}")
    public String toDirPage(@PathVariable("dir") String dir,
                            @PathVariable("page") String page){
        return dir+"/"+page;
    }
}

 ClazzController.java

package com.yx.web;

import com.yx.biz.ClazzBiz;
import com.yx.model.Clazz;
import com.yx.utils.PageBean;
import com.yx.utils.PropertiesUtil;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author 君易--鑨
 * @site www.yangxin.com
 * @company 木易
 * @create  2023-09-09 15:25
 */
@Controller
@RequestMapping("/clz")
public class ClazzController {
    @Autowired
    private ClazzBiz clazzBiz;

    //    增
    @RequestMapping("/add")
    public String add(Clazz Clazz){
        int i = clazzBiz.insertSelective(Clazz);
        return "redirect:list";
    }

    //    删
    @RequestMapping("/del/{mid}")
    public String del(@PathVariable("mid") Integer mid){
        int i = clazzBiz.deleteByPrimaryKey(mid);
        return "redirect:list";
    }
    //    改
    @RequestMapping("/edit")
    public String del(Clazz Clazz){
        int i = clazzBiz.updateByPrimaryKeySelective(Clazz);
        return "redirect:list";
    }

//    文件上传
    @RequestMapping("/upload")
    public String upload(Clazz clazz,MultipartFile photo){

        try {
//上传的图片真实存放地址
            String dir= PropertiesUtil.getValue("dir");
//网络服务器访问地址
            String server=PropertiesUtil.getValue("server");

            String filename = photo.getOriginalFilename();
            System.out.println("文件名称:"+filename);
            System.out.println("文件类型:"+photo.getContentType());
            FileUtils.copyInputStreamToFile(photo.getInputStream(),new File(dir+filename));

            clazz.setPic(server+filename);//保存到数据库中
            clazzBiz.updateByPrimaryKeySelective(clazz);//调用方法修改

        } catch (IOException e) {
            e.printStackTrace();
        }
        return "redirect:list";
    }

    //    查
    @RequestMapping("/list")
    public String list(Clazz Clazz, HttpServletRequest request){
//    Clazz接口参数
        PageBean pageBean=new PageBean();
        pageBean.setRequest(request);
        List<Clazz> Clazzs = clazzBiz.ListPager(Clazz, pageBean);
        request.setAttribute("lst",Clazzs);
        request.setAttribute("pageBean",pageBean);
//最终跳转到WEB-IEF/Clazz/list.jsp页面
        return "clz/list";
    }

    //    数据回显
    @RequestMapping("/preSave")
    public String preSave(Clazz Clazz, Model model){
        if (Clazz !=null && Clazz.getCid() !=null && Clazz.getCid() != 0){
            Clazz c = clazzBiz.selectByPrimaryKey(Clazz.getCid());
            model.addAttribute("c",c);
        }
        return "clz/edit";
    }


}

5. ファイルアップロードの事前シミュレーション

これにより、選択したファイルが指定されたフォルダーにダウンロードされるだけで、データベース内のデータは変更されません。

6. 設定ディレクトリ内の設定ファイル

リソース.プロパティ

dir=D:/photo/upload/
server=/upload/

7. 最後にファイルのアップロードと表示を実現します

2. ファイルのダウンロード

メソッドコード

@RequestMapping(value="/download")
    public ResponseEntity<byte[]> download(Clazz clazz,HttpServletRequest req){

        try {
            //先根据文件id查询对应图片信息
            Clazz clz = this.clazzBiz.selectByPrimaryKey(clazz.getCid());
            String diskPath = PropertiesUtil.getValue("dir");
            String reqPath = PropertiesUtil.getValue("server");
            String realPath = clz.getPic().replace(reqPath,diskPath);
            String fileName = realPath.substring(realPath.lastIndexOf("/")+1);
            //下载关键代码
            File file=new File(realPath);
            HttpHeaders headers = new HttpHeaders();//http头信息
            String downloadFileName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");//设置编码
            headers.setContentDispositionFormData("attachment", downloadFileName);
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            //MediaType:互联网媒介类型  contentType:具体请求中的媒体类型信息
            return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

ファイルのダウンロード コードを指定したコントローラー クラスに追加します。

 jspページコード

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<%@ taglib uri="http://jsp.veryedu.cn" prefix="z"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <link
            href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.css"
            rel="stylesheet">
    <script
            src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.js"></script>
    <title>班级列表</title>
    <style type="text/css">
        .page-item input {
            padding: 0;
            width: 40px;
            height: 100%;
            text-align: center;
            margin: 0 6px;
        }


        .page-item input, .page-item b {
            line-height: 38px;
            float: left;
            font-weight: 400;
        }

        .page-item.go-input {
            margin: 0 10px;
        }
    </style>
</head>
<body>
<form class="form-inline"
      action="${pageContext.request.contextPath }/clz/list" method="post">
    <div class="form-group mb-2">
        <input type="text" class="form-control-plaintext" name="cname"
               placeholder="请输入班级名称">
        <!-- 			<input name="rows" value="20" type="hidden"> -->
        <!-- 不想分页 -->
<%--        <input name="pagination" value="false" type="hidden">--%>
    </div>
    <button type="submit" class="btn btn-primary mb-2">查询</button>
    <a class="btn btn-primary mb-2" href="${pageContext.request.contextPath }/clz/preSave">新增</a>
</form>

<table class="table table-striped ">
    <thead>
    <tr>
        <th scope="col">班级ID</th>
        <th scope="col">班级名称</th>
        <th scope="col">教员</th>
        <th scope="col">图片</th>
        <th scope="col">操作</th>
    </tr>
    </thead>
    <tbody>
    <c:forEach  var="b" items="${lst }">
        <tr>
            <td>${b.cid }</td>
            <td>${b.cname }</td>
            <td>${b.cteacher }</td>
            <td>
             <img src="${b.pic}" style="height:100px;width: 60px; ">
            </td>
            <td>
                <a href="${pageContext.request.contextPath }/clz/preSave?cid=${b.cid}">修改</a>
                <a href="${pageContext.request.contextPath }/clz/del/${b.cid}">删除</a>
                <a href="${pageContext.request.contextPath }/page/clz/upload?cid=${b.cid}">图片上传</a>
                <a href="${pageContext.request.contextPath }/clz/download?cid=${b.cid}">图片下载</a>
            </td>
        </tr>
    </c:forEach>
    </tbody>
</table>
<!-- 这一行代码就相当于前面分页需求前端的几十行了 -->
<z:page pageBean="${pageBean }"></z:page>

</body>
</html>

効果試験

 3. 複数ファイルのアップロード

jspページ表示コード

<%--
  Created by IntelliJ IDEA.
  User: 86158
  Date: 2023/9/9
  Time: 16:08
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>班级logo上传</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/clz/upload" method="post" enctype="multipart/form-data">
    <label>班级编号:</label><input type="text" name="cid" readonly="readonly" value="${param.cid}"/><br/>
    <label>班级图片:</label><input type="file" name="photo"/><br/>
    <input type="submit" value="上传图片"/>
</form>


<p>多文件上传</p>
<form method="post" action="${pageContext.request.contextPath }/clz/uploads" enctype="multipart/form-data">
    <input type="file" name="files" multiple>
    <button type="submit">上传</button>
</form>

</body>
</html>

複数のファイルアップロード方法

@RequestMapping("/uploads")
    public String uploads(HttpServletRequest req, Clazz clazz, MultipartFile[] files){
        try {
            StringBuffer sb = new StringBuffer();
            for (MultipartFile cfile : files) {
                //思路:
                //1) 将上传图片保存到服务器中的指定位置
                String dir = PropertiesUtil.getValue("dir");
                String server = PropertiesUtil.getValue("server");
                String filename = cfile.getOriginalFilename();
                FileUtils.copyInputStreamToFile(cfile.getInputStream(),new File(dir+filename));
                sb.append(filename).append(",");
            }
            System.out.println(sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "redirect:list";
    }

 複数のファイルのアップロードをテストする

 これは複数のファイルをローカル パスにアップロードすることをシミュレートするもので、画像はローカル パスのフォルダーに表示されます。(データベース操作は行われません)、製品の複数の写真、医薬品の一括保存など、独自のプロジェクトのニーズに応じて変更して適用できます。

 4. 拡張機能(jrebelプラグインアプリケーション)

プラグインのインストール

プロキシサーバーを開く

プロキシ サーバーは、アップロードされたリソースに配置されます。最初にプロキシ サーバーを起動し、次に jrebel を使用してプロジェクトを実行することに注意してください。

jrebelスタートプロジェクト

 フォローアップメモ

 このブログはここで共有されています。Lao Tie が今後も共有できることを願っています。

おすすめ

転載: blog.csdn.net/weixin_74352229/article/details/132776866