在比较绚丽多彩的网站或者业务逻辑比较丰富的程序设计过程中,图片的相关操作时必不少的,尤其时图片的上传。还没有彻底摆脱纸质办公可能需要将纸质的文件备份上传,网站的建设可能需要上传用户头像、图片描述等等,这些都需要将图片从本地上传到网上(服务器)。下面将介绍笔者今天在做图片上传过程中所遇到的坑~

一、业务描述

  业务要求是将机器在不断生产的照片上传到网上,以便于能在网站上查看。

二、解决思路

  由于对图片这一块的处理已经比较生疏,所以打算一点一点解决这些业务需求。首先将业务分解为以下几个部分:

  (1)服务器接收浏览器端上传的图片。这一点比较好实现,因为服务器端的开发大多数都是基于B/S架构的,也就是逻辑与浏览器端进行开发的。

  (2)服务器接收客户端上传的图片。这一点看似也不难,但是如何正确的发送出数据确是有点难度,也是笔者今天踩坑的地方。

  (3)业务逻辑的优化完善。

三、服务器接收浏览器端上传的图片

  1、新建网页

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>图片上传</title>
  6. </head>
  7. <body>
  8. <form action="/plant/upload.action" enctype="multipart/form-data"
  9. method="post">
  10. 图片:<input type="file" name="img"/> <br/>
  11. <input type="submit" value="上传"/>
  12. </form>
  13. </body>
  14. </html>

查看代码

  此处需要注意的是 form标签enctype属性的添加,还有就是input输入框中name属性的设置,这与后台的代码相对应。    

  2、编写Controller层的代码

  1. @Controller
  2. public class UploadController {
  3.  
  4. @RequestMapping(value="/upload",method=RequestMethod.POST)
  5. @ResponseBody
  6. public String uploadImg(@RequestParam("img") MultipartFile img, HttpServletRequest request,HttpServletResponse response) {
  7. String contentType = img.getContentType(); // 获取文件的类型
  8. System.out.println("文件类型为:" + contentType);
  9. String originalFilename = img.getOriginalFilename(); // 获取文件的原始名称
  10. // 判断文件是否为空
  11. if(!img.isEmpty()) {
  12. File targetImg = new File("F:/img");
  13. // 判断文件夹是否存在
  14. if(!targetImg.exists()) {
  15. targetImg.mkdirs(); //级联创建文件夹
  16. }
  17. try {
  18. // 开始保存图片
  19. FileOutputStream outputStream = new FileOutputStream("F:/img/" + originalFilename);
  20. outputStream.write(img.getBytes());
  21. outputStream.flush();
  22. outputStream.close();
  23. } catch (IOException e) {
  24. e.printStackTrace();
  25. }
  26. }
  27. return "SUCCESS";
  28. }
  29. }

查看代码

  3、Spring配置文件的修改和项目依赖的添加(小坑)

  1. <!-- 文件上传组件 -->
  2. <dependency>
  3. <groupId>commons-fileupload</groupId>
  4. <artifactId>commons-fileupload</artifactId>
  5. <version>1.3.1</version>
  6. </dependency>

查看代码

  1. <!-- 支持文件上传 -->
  2. <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  3. <!-- 请求编码格式 -->
  4. <property name="defaultEncoding" value="utf-8"></property>
  5. <!-- 上传文件大小(单位:字节) -->
  6. <property name="maxUploadSize" value="50000000"></property>
  7. <!-- 缓冲区大小(单位:KB) -->
  8. <property name="maxInMemorySize" value="1024"></property>
  9. </bean>

查看代码

  4、启动项目,打开浏览器显示相应的图片上传的网页,选择图片,点击上传,如果不出以外的化本地路径上应该会看到刚刚上传的图片。

四、服务器接收客户端上传的图片

  网上有不少内容关于本部分都是介绍使用HttpURLConnection进行上传,这中方法一是比较复杂,需要自己手动封装请求,洋洋洒洒几十行代码;二是如果项目比较复杂,用到Session或者Cookie的话,那就真没辙了~

  基于上述原因,本文选择使用HttpClient进行本地图片的上传

  1、引入相关的依赖

  1. <dependency>
  2. <groupId>org.apache.httpcomponents</groupId>
  3. <artifactId>httpclient</artifactId>
  4. <version>4.5.3</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.httpcomponents</groupId>
  8. <artifactId>httpmime</artifactId>
  9. <version>4.5.3</version>
  10. </dependency>

查看代码

  2、编写客户端程序

  1. import java.io.BufferedReader;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.io.InputStream;
  5. import java.io.InputStreamReader;
  6. import java.util.Arrays;
  7.  
  8. import org.apache.commons.codec.binary.Base64;
  9. import org.apache.commons.lang3.StringUtils;
  10. import org.apache.http.HttpEntity;
  11. import org.apache.http.client.ClientProtocolException;
  12. import org.apache.http.client.methods.CloseableHttpResponse;
  13. import org.apache.http.client.methods.HttpPost;
  14. import org.apache.http.entity.ContentType;
  15. import org.apache.http.entity.mime.MultipartEntityBuilder;
  16. import org.apache.http.entity.mime.content.ByteArrayBody;
  17. import org.apache.http.entity.mime.content.FileBody;
  18. import org.apache.http.entity.mime.content.StringBody;
  19. import org.apache.http.impl.client.CloseableHttpClient;
  20. import org.apache.http.impl.client.HttpClients;
  21. import org.apache.http.util.EntityUtils;
  22.  
  23. public class ClientUpload {
  24.  
  25. public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
  26. String url = "http://localhost:8090/plant/upload.action";
  27. // String basePath = "F:\\img\\";
  28. String path = "G:\\123.jpg";
  29. uploadImage(url, "dfsdfsdfsdf",path);
  30. }
  31.  
  32. public static String uploadImage(String path, String base64String, String imageFilePath) throws ClientProtocolException, IOException {
  33. // 1. 创建上传需要的元素类型
  34. // 1.1 装载本地上传图片的文件
  35. File imageFile = new File(imageFilePath);
  36. FileBody imageFileBody = new FileBody(imageFile);
  37. // 1.2 装载经过base64编码的图片的数据
  38. // String imageBase64Data = base64String;
  39. // ByteArrayBody byteArrayBody = null;
  40. // if (StringUtils.isNotEmpty(imageBase64Data)) {
  41. // byte[] byteImage = Base64.decodeBase64(imageBase64Data);
  42. // byteArrayBody = new ByteArrayBody(byteImage, "image_name");
  43. // }
  44. // 1.3 装载上传字符串的对象
  45. StringBody name = new StringBody("admin", ContentType.TEXT_PLAIN);
  46. // 2. 将所有需要上传元素打包成HttpEntity对象
  47. // HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("name", name).addPart("img", imageFileBody).addPart("file2", byteArrayBody).build();
  48. HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("name", name).addPart("img", imageFileBody).build();
  49. // 3. 创建HttpPost对象,用于包含信息发送post消息
  50. HttpPost httpPost = new HttpPost(path);
  51. httpPost.setEntity(reqEntity);
  52. // 4. 创建HttpClient对象,传入httpPost执行发送网络请求的动作
  53. CloseableHttpClient httpClient = HttpClients.createDefault();
  54. CloseableHttpResponse response = httpClient.execute(httpPost);
  55. // 5. 获取返回的实体内容对象并解析内容
  56. HttpEntity resultEntity = response.getEntity();
  57. String responseMessage = "";
  58. try {
  59. if (resultEntity != null) {
  60. InputStream is = resultEntity.getContent();
  61. BufferedReader br = new BufferedReader(new InputStreamReader(is));
  62. StringBuffer sb = new StringBuffer();
  63. String line = "";
  64. while ((line = br.readLine()) != null) {
  65. sb.append(line);
  66. }
  67. responseMessage = sb.toString();
  68. System.out.println("响应内容为:" + responseMessage);
  69. }
  70. EntityUtils.consume(resultEntity);
  71. } finally {
  72. if (null != response) {
  73. response.close();
  74. }
  75. }
  76. return responseMessage;
  77. }
  78. }

查看代码

  3、到此为止,不出意外的话因该能够在控制台看到令人激动的“SUCCESS”输出

五、业务逻辑的优化完善

  1、由于图片是在不断生成的,所以要将图片不断地上传,并且保证上传地图片不重复。

  1. public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
  2. String url = "http://localhost:8090/plant/upload.action";
  3. String basePath = "F:\\img\\";
  4. // String path = "G:\\123.jpg";
  5. // uploadImage(url, "dfsdfsdfsdf",path);
  6. while (true) {
  7. File file = new File(basePath);
  8. String[] list = file.list();
  9. Arrays.sort(list);
  10. for (String str : list) {
  11. // 图片未标记为上传
  12. if (!str.startsWith("Upload")) {
  13. uploadImage(url, "chao", basePath + str); // 上传图片
  14. new File(basePath + str).renameTo(new File(basePath + "Upload_" + str)); // 重命名图片
  15. }
  16. }
  17. Thread.sleep(1000*60); //等待60秒
  18. }
  19. }

查看代码

  2、服务端的完善

  图片如果想要能够在开发的网站中浏览到,一般业务比较小的话是直接传至Tomcat服务器,然后将路径记录并写入数据库;业务比较庞大的可以现在本地搭建图片服务器,采用Nginx或其他技术都是可以做到的,然后也需要将该路径写入数据库进行保存。

Java向服务器上传图片的更多相关文章

  1. 从app上传图片到php,再上传到java后端服务器的方法一览

    在现在的网络开发中,上传图片类的需求实在是太普通不过了,但是对于怎么样做到上传图片,对于刚开始建立项目的时候,还是有点不知所措的.也许有幸,我们做的项目是之前已经有人写过类似的用例了,那么我们只需要依 ...

  2. 从app上传图片到php,再上传到java后端服务器的方法一条龙服务

    在现在的网络开发中,上传图片类的需求实在是太普通不过了,但是对于怎么样做到上传图片,对于刚开始建立项目的时候,还是有点不知所措的.也许有幸,我们做的项目是之前已经有人写过类似的用例了,那么我们只需要依 ...

  3. 一个简单的Java web服务器实现

    前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...

  4. Java从服务器上获取时间,动态在jsp页面显示

    Java获取服务器时间,动态显示到jsp页面,大家都是到Java只能获取一次,到页面的时间是静态的,不过通过js和Java的合作,巧妙地实现此功能 本人是给电视做系统,客户要求页面能显示时间,因为电视 ...

  5. 常用Java Web 服务器

    Java Web应用程序需要部署在Java web服务器中运行,常用的Java Web服务器有Tomcat.GlassFish.WebLogic.JBoss.WebSphere.Jetty.JRun等 ...

  6. java web服务器tomcat介绍【转载】

    机器矩阵2016-08-10 22:14 java程序员亲切地称他为tom猫,看到这只猫可以说明1 服务器部署成功了 ,2 网络是联通的. 到底这只猫是什么来头呢? tomcat是Apache基金会下 ...

  7. 各种容器与服务器的区别与联系:Servlet容器、WEB容器、Java EE容器、应用服务器、WEB服务器、Java EE服务器

    1.容器与服务器的联系 如上图,我们先来看下容器与服务器的联系:容器是位于应用程序/组件和服务器平台之间的接口集合,使得应用程序/组件可以方便部署到服务器上运行. 2.各种容器的区别/联系 2-1.容 ...

  8. 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服务器 WEB服务器 Java EE服务器

    转自:https://blog.csdn.net/tjiyu/article/details/53148174 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服 ...

  9. 【转】Java做服务器开发语言

    版权声明:本文为博主原创文章,未经博主允许不得转载. 随着游戏市场的兴起,特别是网页游戏.手机游戏的崛起,对游戏开发技术的需求越来越多.网络游戏开发是一个庞大的体系,总体来说是客户端与服务器端.客户端 ...

随机推荐

  1. django2-登录与出版社

    1.django核心功能 因为django功能很多 ,出版社可以使用到部分功能,最快最简单了解django的运行模式,每个点后续细化去梳理 django的路由 django的视图 django的模板 ...

  2. js绑定事件代理的坑

    js通过事件代理的方式绑定跳转事件,我这里的逻辑是把click事件绑定在最外层container上面,如果e.target包含我已经写好的class,则执行跳转逻辑.但是这种方式好像只能是在点击的元素 ...

  3. webpack管理资源(loader操作)

    1.加载css npm install --save-dev style-loader css-loader webpack.config.js文件中: const path = require('p ...

  4. 挑战常规 -- 为什么不要再用cookie作为储存?

    不要使用cookie当存储 Cookie 是什么? Cookie 由浏览器储存在本地,每次访问目标网址会带上的请求头,服务器可以通过Set-Cookie响应头设置Cookie. Cookie的用途 由 ...

  5. MAC TXT文本

    Mac系统下.txt格式的纯文本怎么保存? 作者:佚名 字体:[增加 减小] 来源:互联网 时间:06-02 14:29:23 我要评论 Mac系统下.txt格式的纯文本怎么保存?.txt是个用途广泛 ...

  6. HOW TO: Setting up Encrypted Communications Channels in Oracle Databas

    access_timeSeptember 22, 2015 person_outlineMartin Rakhmanov share In this article, I will explain h ...

  7. Mysql—配置文件my.ini或my.cnf的详解

    [mysqld] log_bin = mysql-bin binlog_format = mixed expire_logs_days = # 超过7天的binlog删除 slow_query_log ...

  8. Python Pyinstaller 打包程序及遇到的问题总结

    一.如何打包py程序 1.安装打包模块 pip install pyinstaller 2.定义保存包的路径 CMD ,CD 比方:把最终*.exe运行文件,保存到H盘 install 文件夹下. 输 ...

  9. 如何将MagicaVoxel模型导入UE4中(1)

    前言 当初在选择自己项目的美术风格时,由于自己的美术基础实在是太差,所以选择了体素风格来构建(其实还是MagicaVoxel的建模操作很容易上手),但是将自己千辛万苦做好的模型导入至项目中时,出现了这 ...

  10. 01-Django 简介

    一.MVC框架(模型-视图-控制器缩写,软件的构建模式) 一种软件设计典范,用一种业务逻辑.数据.界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需 ...