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

  • 相关阅读:
    2017ccpc全国邀请赛(湖南湘潭) E. Partial Sum
    Codeforces Round #412 C. Success Rate (rated, Div. 2, base on VK Cup 2017 Round 3)
    2017 中国大学生程序设计竞赛 女生专场 Building Shops (hdu6024)
    51nod 1084 矩阵取数问题 V2
    Power收集
    红色的幻想乡
    Koishi Loves Segments
    Wood Processing
    整数对
    Room and Moor
  • 原文地址:https://www.cnblogs.com/yiychao/p/11790047.html
Copyright © 2011-2022 走看看