说明:
(1)为什么写本篇博客?:【我们知道,在新增商品的时候,是需要上传图片的】→【对应到接口上的表现就是:在开发【增加商品】接口的时候,我们需要传递一个image参数】→【这个image参数,就是图片在服务器上的地址啦】→【So,这个image地址是什么、从哪儿来?】→【由此,就涉及到【上传图片】接口了】→【我们在调用【增加商品】接口的时候,其会先调用【上传图片】接口,把图片先上传到服务器上,,,然后服务器会返回一个(经过安全处理的)该图片在服务器的地址】→【然后,这个返回的image地址,就会作为【增加图片】接口的image参数】;
所以,在开发【增加商品】接口的时候,必须要开发图片上传的功能,也就是必须要开发【上传图片】功能;
(2)本篇博客介绍的上传文件技术,其实具有很强的通用性;;;;对于以后遇到其他需要上传文件的开发场景时候,完全可以参考本篇博客的内容;
(3)关于文件上传:
● 以前在【后台系统四:【新增】功能;(FileUpload组件)】中,介绍过使用FileUpload组件实现上传文件;(PS:当时的那个项目是个,纯纯的Servlet和JSP项目);● 但本篇博客,没有使用FileUpload组件;而是使用Spring提供的【@RequestParam("file") MultipartFile file】的方式,来实现文件的接收;
(4)服务器在保存静态资源的时候,出于安全的考虑;返回给前端的图片地址,并不是图片在服务器上的真实地址;关于这一点,在【Spring Boot电商项目36:商品模块二:【增加商品】接口之图片上传:资源映射开发;】作了详细介绍;
(5)声明:一个尚未仔细研究的点:MultipartFile与File的具体内容;
● 似乎可以参考【MultipartFile与File的一些事】;这篇博客自己还没看;
● 以后遇到了个性化的文件上传需求;或者遇到断点续传等特殊需求时;或者等到有精力的时候;可以再来仔细研究一下相关内容;
目录
二:开发【上传图片】接口:在ProductAdminController中,创建上传图片的方法:upload()方法;
(2)方法参数,为什么要引入HttpServletRequest?
(3)使用MultipartFile来实现文件的上传;(PS:这儿介绍的很浅)
(4)代码逻辑说明:使用【MultipartFile.getOriginalFilename();】去获取原始文件名;使用【UUID.randomUUID();】创建文件名;
(5)创建目录File对象,创建文件夹File对象;把文件按照指定的文件名,写入到服务器的指定目录中去;
(6)【配置文件中,配置自定义属性】并【使用@Value注解去获取属性,以赋值给变量】;
(7)【配置文件中,配置自定义属性】并【使用@Value注解去获取属性,以赋值给变量】:两个坑;
(8)上传文件时,如果出了问题:我们使用try-catch的方法把异常给捕获,而不是throw抛出;(PS:对这一点的理解,还不是太深……)
(9)至此,文件就上传到服务器了;;;下面就是(也可以说是根据接口要求,其实接口只能这么要求),返回(经过安全处理的)图片路径;
一:【上传图片】接口说明;
说明:
(1)这个接口返回的地址,不是图片上传到服务器后的真实地址,这是我们自定义的非真实地址;这主要是出于安全考虑;
(2)虽然这个接口的url中有admin,但是只访问这个接口时,可以不是管理员用户登录的状态;而且,我们在【Spring Boot电商项目27:商品分类模块六:统一校验管理员身份;(选用【J2EE中的过滤器】来实现需求;重难点是【如何在Spring Boot项目中,使用过滤器】;)】中配置的时候,也没有配置【/admin/upload/file】这个地址;
但及时如此,在项目上线后,用户是无法单独调用【上传图片】接口的;;;而是在调用【增加图片】接口的时候,顺带调用【上传图片】接口;
二:开发【上传图片】接口:在ProductAdminController中,创建上传图片的方法:upload()方法;
/** * 上传文件(这儿具体来说,就是图片) * @param httpServletRequest * @param file * @return */ @ApiOperation("上传文件(这儿具体来说,就是图片)") @PostMapping("/admin/upload/file") @ResponseBody public ApiRestResponse upload(HttpServletRequest httpServletRequest, @RequestParam("file") MultipartFile file) { //获取文件的原始名字 String fileName = file.getOriginalFilename(); //通过截取最后一个“.”后面的内容,获取文件扩展名 String suffix = fileName.substring(fileName.lastIndexOf(".")); //利用UUID,生成文件上传到服务器中的文件名; UUID uuid = UUID.randomUUID();//通过Java提供的UUID工具类,获取一个UUID; //把uuid和文件扩展名,拼凑成新的文件名; String newFileName = uuid.toString() + suffix; //生成文件夹的File对象; File fileDirectory = new File(Constant.FILE_UPLOAD_DIR); //生成文件的File对象; File destFile = new File(Constant.FILE_UPLOAD_DIR + newFileName); //如果文件夹不存在的话 if (!fileDirectory.exists()) { //如果在创建这个文件夹时,创建失败,就抛出文件夹创建失败异常 if (!fileDirectory.mkdir()) { throw new ImoocMallException(ImoocMallExceptionEnum.MKDIR_FAILED); } } //如果能执行到这儿,说明文件夹已经创建成功了;;;那么就把传过来的文件,写入到我们指定的File对象指定的位置中去; try { file.transferTo(destFile); } catch (IOException e) { e.printStackTrace(); } //执行到这儿以后,表示,我们已经把文件,存放到指定的位置了; //接下来,就是组织图片的url,返回给前端; try { // System.out.println(httpServletRequest.getRequestURL() + ""); // System.out.println(getHost(new URI(httpServletRequest.getRequestURL() + ""))); return ApiRestRespo