SpringMVC文件上传、下载、国际化配置

news/2024/9/19 12:02:19/

Java知识点总结:想看的可以从这里进入

目录

      • 3.6、文件上传、下载
        • 3.6.1、文件上传
        • 3.6.2、文件下载
      • 3.7、国际化配置

3.6、文件上传、下载

3.6.1、文件上传

form 表单想要具有文件上传功能,其必须满足以下 3 个条件。

  • form 表单的 method 属性必须设置为 post。
  • form 表单的 enctype 属性设置为 multipart/form-data。
  • 至少提供一个 type 属性为 file 的 input 输入框。

在SpringMVC 中为我们提供了文件解析器,来实现上传文件的功能,MultipartResolver 本身是一个接口,我们需要通过它的实现类来完成对它的实例化工作。

实现类说明依赖支持的 Servlet 版本
StandardServletMultipartResolverServlet 内置的上传功能。不需要第三方 JAR 包的支持。仅支持 Servlet 3.0 及以上版本
CommonsMultipartResolver借助 Apache 的 commons-fileupload 来完成具体的上传操作。需要 Apache 的 commons-fileupload 等 JAR 包的支持。不仅支持 Servlet 3.0 及以上版本,还可以在比较旧的 Servlet 版本中使用。
<!-- CommonsMultipartResolver依赖 支持文件上传(注意此组件在Spring6被移除了)-->
<dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.1</version>
</dependency>
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.8.0</version>
</dependency>

CommonsMultipartResolver我们在学习Servlet组件的时候使用过,它在springMVC中使用时需要配置文件解析器,其中multipartResolver这个名字是固定的一旦更改,就无法完成文件的解析和上传工作。

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--编码格式 --><property name="defaultEncoding" value="UTF-8"/><!--上传文件大小--><property name="maxUploadSize" value="103424"/><!-- <property name="maxUploadSizePerFile" value="102400"/>--><property name="resolveLazily" value="true"/>
</bean>

在使用时直接向Controller的方法中传入参数即可 MultipartFile file即可使用:

@RequestMapping("")
public void multipartFileTest(MultipartFile file){}
内部方法作用
byte[] getBytes()以字节数组的形式返回文件的内容。
String getContentType()返回文件的内容类型。
InputStream getInputStream()返回一个 input 流,从中读取文件的内容。
String getName()返回请求参数的名称。
String getOriginalFillename()返回客户端提交的原始文件名称。
long getSize()返回文件的大小,单位为字节。
boolean isEmpty()判断被上传文件是否为空。
void transferTo(File destination)将上传文件保存到目标目录下。
<form th:action="@{/student}" method="post" enctype="multipart/form-data"><table style="margin: auto"><tr><td>照片:</td><td><input type="file" id="chooseImage" name="photos" multiple="multiple" required><br><span id="img-div"></span></td></tr><tr><td colspan="2" align="center"><input type="submit" value="提交"><input type="reset" value="重置"></td></tr></table><!-- 保存用户自定义的背景图片 --><img id="preview_photo" src="" width="200px" height="200px">
</form>

使用Controller上传图片

@RequestMapping(value = "/uploadPhoto", method = RequestMethod.POST)
public String uploadPhoto(MultipartFile photo, HttpServletRequest request,Model model) {String realPath = request.getSession().getServletContext().getRealPath("/upload/");System.out.println(realPath);File fileDir = new File(realPath);if (!fileDir.exists()) {fileDir.mkdir();}String filename = photo.getOriginalFilename();System.err.println("正在上传的图片为:" + filename);String newFileName = UUID.randomUUID() + filename;try {//将文件保存指定目录photo.transferTo(new File(realPath + newFileName));model.addAttribute("message","上传成功");model.addAttribute("filename",newFileName);} catch (Exception e) {model.addAttribute("message","上传失败");e.printStackTrace();}return "page/success";
}
<h1 th:text="${message}"></h1>
<table><tr><td>照片:</td><td th:if="${message}eq'上传成功'"><img th:src="@{'http://localhost:8080/upload/'+${filename}}" width='200px' height='200px'/><br></td></tr>
</table>

image-20220917171145599

image-20220917171154976

这里有一点要注意,如果使用的eclipse,那么使用request.getSession().getServletContext().getRealPath(“/upload/”),获取的就是部署到Tomcat的路径,可以直接获取,但是如果你使用的是Idea的话,它是把图片上传到了target这样一个文件夹内image-20220917171433341

如果想获取这个路径的图片可以通过tomcat设置一个虚拟的路径:

image-20220917171514074

image-20220917171541490

image-20220917171614081

设置完成后,通过 http://localhost:8080/虚拟路径文件夹/文件名,即可获取上传的图片

3.6.2、文件下载

使用ResponseEntity实现下载文件的功能。

将上面上传的文件下载:

<tr><td>照片:</td><td th:if="${message}eq'上传成功'"><img th:src="@{'http://localhost:8080/upload/'+${filename}}" width='200px' height='200px'/><br><a th:href="@{/downLoadFile(fileName=${filename})}">点击下载</a></td>
</tr>
@RequestMapping("/downLoadFile")
public ResponseEntity<byte[]> downLoadFile(HttpServletRequest request, String fileName) throws IOException {//得到图片的实际路径String realPath = request.getSession().getServletContext().getRealPath("/upload/");realPath = realPath+fileName;//创建该图片的对象File file = new File(realPath);//将图片数据读取到字节数组中byte[] bytes = FileUtils.readFileToByteArray(file);//创建 HttpHeaders 对象设置响应头信息HttpHeaders httpHeaders = new HttpHeaders();//设置图片下载的方式和文件名称httpHeaders.setContentDispositionFormData("attachment", toUTF8String(fileName));httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);return new ResponseEntity<>(bytes, httpHeaders, HttpStatus.OK);
}public String toUTF8String(String str) {StringBuffer sb = new StringBuffer();int len = str.length();for (int i = 0; i < len; i++) {// 取出字符中的每个字符char c = str.charAt(i);// Unicode码值为0~255时,不做处理if (c <= 255) {sb.append(c);} else { // 转换 UTF-8 编码byte b[];try {b = Character.toString(c).getBytes("UTF-8");} catch (UnsupportedEncodingException e) {e.printStackTrace();b = null;}// 转换为%HH的字符串形式for (int value : b) {int k = value;if (k < 0) {k &= 255;}sb.append("%" + Integer.toHexString(k).toUpperCase());}}}return sb.toString();
}
image-20220917174738732

image-20220917174752383

3.7、国际化配置

国际化(i18n)(internationalization的首末字符i和n,18为中间的字符数)是指软件开发时应该具备支持多种语言和地区的功能。也就是根据不同国家显示不同的语言(中国人阅读为汉语,美国人为英语,韩国人为韩语等等)。

在 Spring 项目中实现国际化,通常需要以下 4 步:

  1. 编写国际化资源文件:文件名格式为:基本名-语言代码-国家或地区代码,例如 messages_zh_CN.properties。

    userName=用户名
    password=密码
    welcome=欢迎您
    submit=提交
    reset=重置userName=userName
    password=password
    welcome=Welcome
    submit=submit
    reset=reset
    

    写完之后IDEA会自动归类这种文件

    image-20220917175831691

  2. 在Spring MVC xml配置文件进行配置

    <!-- 国际化配置:对资源文件进行绑定 -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"><property name="basename" value="messages"/><property name="defaultEncoding" value="UTF-8"/><property name="cacheSeconds" value="0"/>
    </bean>
    <!-- 在界面上进行切换,Session -->
    <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver"><property name="defaultLocale" value="en_US"/>
    </bean>
    <!--用于获取请求中的国际化信息并将其转换为 Locale 对象,获取 LocaleResolver 对象对国际化资源文件进行解析。-->
    <mvc:interceptors><bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"><property name="paramName" value="lang"/></bean>
    </mvc:interceptors>
    
  3. 在页面中获取国际化内容;

    <body><h1 th:text="主页+#{welcome}"></h1><tr><td th:text="#{userName}"></td><td><input type="text" name="userName" required><br></td></tr><tr><td th:text="#{password}"></td><td><input type="password" name="password" required><br></td></tr><tr><td colspan="2" align="center"><input type="submit" th:value="#{submit}"><input type="reset" th:value="#{reset}"></td></tr><a th:href="@{/localeChange(lang=en_US)}">英文</a><a th:href="@{/localeChange(lang=zh_CN)}">中文</a><br/>
    </body>
    
  4. 编写控制器方法手动切换语言。

    @Controller
    public class I18nController  {@Autowiredprivate ResourceBundleMessageSource messageSource;@RequestMapping("/localeChange")public String localeChange(Locale locale) {String userName = messageSource.getMessage("userName", null, locale);String password = messageSource.getMessage("password", null, locale);String submit = messageSource.getMessage("submit", null, locale);String reset = messageSource.getMessage("reset", null, locale);return "index";}
    }
    
image-20220917182151799 image-20220917182206344

http://www.ppmy.cn/news/30002.html

相关文章

最近一年我都干了什么——反思!!

过去一年不管是学习方式还是心态上都和以往有了许多不同的地方&#xff0c;比较昏昏沉沉。最近慢慢找到状态了&#xff0c;就想赶紧记录下来。 学习 在学习新技术的过程中开始飘了&#xff0c;总感觉有了一些开发经验后就觉得什么都不用记&#xff0c;知道思路就行遇到了现场百…

Java高效率复习-SpringMVC[SpringMVC-2]

SpringMVC获取请求参数 SpringMVC获取请求参数的两种方式↓ 通过ServletAPI获取请求参数 将HttpServletRequest作为控制器方法的形参&#xff0c;此时HttpServletRequest类型的参数表示封装了当前请求的请求报文的对象 通过request的API——getParameter(String s)方法来获取…

2023王道考研数据结构笔记第四章串

第四章 串 4.1 串的定义 4.1.1 串的相关概念 串&#xff1a;即字符串&#xff08;String&#xff09;是由零个或多个字符组成的有限序列。一般记为S‘a1a2…an’ (n>0) 其中S是串名&#xff0c;单引号&#xff08;注&#xff1a;有的地方用双引号&#xff0c;如Java、C&am…

用Python Flask为女朋友做一个简单的网站(附可运行的源码)

&#x1f31f;所属专栏&#xff1a;献给榕榕&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该专栏系为女友准备的&#xff0c;里面会不定时发一些讨好她的技术作品&#xff0c;感兴趣的小伙伴可以关注一下~&#x1f449;文章简介…

【数据结构初阶】详解“树”

目录 前言 1.树概念及结构 &#xff08;1&#xff09;树的概念 &#xff08;2&#xff09;树的名词介绍 &#xff08;3&#xff09;树的表示 ​编辑 2.二叉树概念及结构 &#xff08;1&#xff09;概念 &#xff08;2&#xff09;特殊的二叉树 &#xff08;3&#xff0…

[深入理解SSD系列综述 1.5] SSD固态硬盘参数图文解析_选购固态硬盘就像买衣服?

版权声明&#xff1a;付费作品&#xff0c;未经许可&#xff0c;不可转载前言SSD &#xff08;Solid State Drive&#xff09;&#xff0c;即固态硬盘&#xff0c;通常是一种以半导体闪存&#xff08;NAND Flash&#xff09;作为介质的存储设备。SSD 以半导体作为介质存储数据&…

UNIX编程--Makefile入门

Makefile 文件命名和规则 文件命名 makefile 或者 Makefile Makefile 规则 一个 Makefile 文件中可以有一个或者多个规则目标 ... &#xff1a; 依赖 ...命令 (shell 命令)...目标&#xff1a;最终要生成的文件&#xff0c;伪目标除外依赖&#xff1a;生成目标所需的文件或是目…

【剧前爆米花--爪哇岛寻宝】MySQL中索引和事务

作者&#xff1a;困了电视剧 专栏&#xff1a;《MySQL数据库》 文章分布&#xff1a;这是一篇关于Java中异常类的文章&#xff0c;在本篇文章中详细讲解了异常的使用逻辑和底层的执行过程&#xff0c;如有疏漏&#xff0c;欢迎大佬指正&#xff01; 目录 索引 用法 底层逻辑…

HCIP第一个实验

实验要求与实验拓扑子网划分分析将骨干链路看成一个整体&#xff0c;路由器后的2个环回地址先看成一个&#xff0c;最后再进行拆分。计算得出&#xff0c;一共需要划分为6个子网段&#xff0c;取三位。再将每一条网段&#xff0c;按照题目要求进行划分最后完成子网划分。子网划…

synchronized和lock的区别

区别&#xff1a; 1.synchronized是关键字,Lock是接口; 2.synchronized是隐式的加锁,lock是显式的加锁; 3.synchronized可以作用于方法上,lock只能作用于方法块; 4.synchronized底层采用的是objectMonitor,lock采用的AQS; 5.synchronized是阻塞式加锁,lock是非阻塞式加锁支…

【0177】Linux中POSIX信号量实现机制

文章目录 1. 信号量概念1.1 信号量类比1.2 重要的观察1.3 信号量分类2. POSIX与System V信号量3. 信号量API4. 代码演示5. 信号量内核实现1. 信号量概念 在计算机科学中,信号量(semaphores )是一种变量或抽象数据类型,用于控制多个进程对公共资源的访问,并避免并发系统(如…

gazebo仿真轨迹规划+跟踪(不在move_base框架下)

以Tianbot为例子&#xff0c;开源代码如下&#xff1a; https://github.com/tianbot/tianbot_mini GitHub - tianbot/abc_swarm: Ant Bee Cooperative Swarm, indicating air-ground cooperation. This repository is for Tianbot Mini and RoboMaster TT swarm kit. 1.在…

借助CatGPT让turtlesim小乌龟画曲线

注意这里是CatGPT&#xff0c;不等同OpenAI的ChatGPT&#xff0c;但是用起来十分方便&#xff0c;效果也还行。详细说明ROS机器人turtlesim绘制曲线需要注意哪些ROS机器人turtlesim绘制曲线需要注意以下几点&#xff1a;绘制曲线前需要设置好turtlesim的初始位置和方向&#xf…

机器学习、数据挖掘和统计模式识别学习(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 机器学习是让计算机在没有明确编程的情况下采取行动的科学。在过去的十年中&#xff0c;机器学习为我们提供了自动驾驶汽车&…

蓝桥杯第十四届校内赛(第三期) C/C++ B组

一、填空题 &#xff08;一&#xff09;最小的十六进制 问题描述   请找到一个大于 2022 的最小数&#xff0c;这个数转换成十六进制之后&#xff0c;所有的数位&#xff08;不含前导 0&#xff09;都为字母&#xff08;A 到 F&#xff09;。   请将这个数的十进制形式作…

【数据结构初阶】二叉树顺序结构:堆的实现

前言 前边077带着大家学习了树与二叉树的相关概念&#xff0c;这篇文章我们来实现一个二叉树的顺序结构。 二叉树的顺序结构 普通的二叉树是不适合用数组来存储的&#xff0c;因为可能会存在大量的空间浪费。而完全二叉树更适合使用顺序结构存储。现实中我们通常把堆(一种二叉…

库函数qsort 的模拟实现

在之前了解了库函数qsort的使用之后 我们来模拟实现一下上篇有介绍 qsort的底层实现是快速排序 由于害怕没有人了解过快速排序 我就用大家熟知的冒泡排序进行模拟实现 先来展示完整代码 以下代码为升序排序 如果降序将冒泡排序中的大于号改为小于号就可以了#define _CRT_SECURE…

【设计模式之美 设计原则与思想:设计原则】19 | 理论五:控制反转、依赖反转、依赖注入,这三者有何区别和联系?

关于 SOLID 原则&#xff0c;我们已经学过单一职责、开闭、里式替换、接口隔离这四个原则。今天&#xff0c;我们再来学习最后一个原则&#xff1a;依赖反转原则。在前面几节课中&#xff0c;我们讲到&#xff0c;单一职责原则和开闭原则的原理比较简单&#xff0c;但是&#x…

「媒体分流直播」媒体直播和传统直播的区别,以及媒体直播的特点

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好直播毋庸置疑已经融入到了我们生活的方方面面&#xff0c;小到才艺&#xff0c;游戏&#xff0c;大到政策的发布&#xff0c;许多企业和机构也越来越重视直播&#xff0c;那么一场活动怎么最大化的进行传播&#xff0c;一是…

【基础算法】单链表的OJ练习(3) # 移除链表元素 # 相交链表 #

文章目录前言移除链表元素相交链表写在最后前言 本章的OJ练习也是相对简单的&#xff0c;只要能够理解解题的思路&#xff0c;并且依照这个思路能够快速的写出代码&#xff0c;我相信&#xff0c;你的链表水平已经足够了。 对于OJ练习&#xff08;2&#xff09; : ->传送门…