zoukankan      html  css  js  c++  java
  • Java向服务器上传图片

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

    一、业务描述

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

    二、解决思路

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

      (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或其他技术都是可以做到的,然后也需要将该路径写入数据库进行保存。

  • 相关阅读:
    day5模块
    day5时间复杂度
    day5冒泡排序
    day4正则表达式
    C语言 经典编程100题
    C语言 第八章 函数、指针与宏
    C语言 第七章 数组与字符串
    C语言 第六章 多重循环
    C语言 第五章 循环结构
    C语言 第四章 分支结构练习
  • 原文地址:https://www.cnblogs.com/yiychao/p/11790047.html
Copyright © 2011-2022 走看看