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

一、业务描述

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

二、解决思路

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

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

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

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

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

  1、新建网页

 <!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图片上传</title>
</head>
<body>
<form action="/plant/upload.action" enctype="multipart/form-data"
method="post">
图片:<input type="file" name="img"/> <br/>
<input type="submit" value="上传"/>
</form>
</body>
</html>

查看代码

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

  2、编写Controller层的代码

 @Controller
public class UploadController { @RequestMapping(value="/upload",method=RequestMethod.POST)
@ResponseBody
public String uploadImg(@RequestParam("img") MultipartFile img, HttpServletRequest request,HttpServletResponse response) {
String contentType = img.getContentType(); // 获取文件的类型
System.out.println("文件类型为:" + contentType);
String originalFilename = img.getOriginalFilename(); // 获取文件的原始名称
// 判断文件是否为空
if(!img.isEmpty()) {
File targetImg = new File("F:/img");
// 判断文件夹是否存在
if(!targetImg.exists()) {
targetImg.mkdirs(); //级联创建文件夹
}
try {
// 开始保存图片
FileOutputStream outputStream = new FileOutputStream("F:/img/" + originalFilename);
outputStream.write(img.getBytes());
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return "SUCCESS";
}
}

查看代码

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

 <!-- 文件上传组件 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>

查看代码

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

查看代码

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

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

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

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

  1、引入相关的依赖

 <dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.3</version>
</dependency>

查看代码

  2、编写客户端程序

 import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.ByteArrayBody;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils; public class ClientUpload { public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException {
String url = "http://localhost:8090/plant/upload.action";
// String basePath = "F:\\img\\";
String path = "G:\\123.jpg";
uploadImage(url, "dfsdfsdfsdf",path);
} public static String uploadImage(String path, String base64String, String imageFilePath) throws ClientProtocolException, IOException {
// 1. 创建上传需要的元素类型
// 1.1 装载本地上传图片的文件
File imageFile = new File(imageFilePath);
FileBody imageFileBody = new FileBody(imageFile);
// 1.2 装载经过base64编码的图片的数据
// String imageBase64Data = base64String;
// ByteArrayBody byteArrayBody = null;
// if (StringUtils.isNotEmpty(imageBase64Data)) {
// byte[] byteImage = Base64.decodeBase64(imageBase64Data);
// byteArrayBody = new ByteArrayBody(byteImage, "image_name");
// }
// 1.3 装载上传字符串的对象
StringBody name = new StringBody("admin", ContentType.TEXT_PLAIN);
// 2. 将所有需要上传元素打包成HttpEntity对象
// HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("name", name).addPart("img", imageFileBody).addPart("file2", byteArrayBody).build();
HttpEntity reqEntity = MultipartEntityBuilder.create().addPart("name", name).addPart("img", imageFileBody).build();
// 3. 创建HttpPost对象,用于包含信息发送post消息
HttpPost httpPost = new HttpPost(path);
httpPost.setEntity(reqEntity);
// 4. 创建HttpClient对象,传入httpPost执行发送网络请求的动作
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = httpClient.execute(httpPost);
// 5. 获取返回的实体内容对象并解析内容
HttpEntity resultEntity = response.getEntity();
String responseMessage = "";
try {
if (resultEntity != null) {
InputStream is = resultEntity.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
responseMessage = sb.toString();
System.out.println("响应内容为:" + responseMessage);
}
EntityUtils.consume(resultEntity);
} finally {
if (null != response) {
response.close();
}
}
return responseMessage;
}
}

查看代码

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

五、业务逻辑的优化完善

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

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

查看代码

  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. JS基础语法---阶段复习+作业练习+接下来知识点heads up

    调试:调试代码---高级程序员都是从调试开始的 调试: 写代码---打开浏览器--F12(开发人员工具)--->Sources---双击文件,在某一行代码前面点击一下(出现的东西就是断点) 一元 ...

  2. css 关于浮动float的使用以及清除浮动

    float:none | left | right 默认值:none 适用于:所有元素 none:设置对象不浮动left:设置对象浮在左边right:设置对象浮在右边 当该属性不等于none引起对象浮 ...

  3. CocoPods原理

    CocoaPods 的原理是将所有的依赖库都放到另一个名为Pods的项目中, 然而让住项目依赖Pods项目, 这样,源码管理工作任务从主项目移到了Pods项目中. 1.Pods项目最终会编译成一个名为 ...

  4. Troubleshooting ORA-30036 - Unable To Extend Undo Tablespace (Doc ID 460481.1)

    Troubleshooting ORA-30036 - Unable To Extend Undo Tablespace (Doc ID 460481.1) APPLIES TO: Oracle Da ...

  5. 『005』Web集群

    『006』索引-The Web cluster 准备更新中

  6. aspx使用KindEditor副文本框插件出现检测到有潜在危险

    web配置添加    <httpRuntime requestValidationMode="2.0" /> aspx页面添加   ValidateRequest=&q ...

  7. python3.5.3rc1学习十:网络请求

    #sys模块import sys sys.stderr.write('This is stderr text\n')# 因为从定向有缓冲区,所以需要以下这行代码sys.stderr.flush()sy ...

  8. testNG xml文件详解

    网上看到一篇整理的非常详细的xml文件详解,分享一下: 1 <?xml version="1.0" encoding="UTF-8"?> 2 < ...

  9. 【Spring JDBC】JdbcTemplate(三)

    传统Jdbc API与Spring jdbcTemplate比较 //JDBC API Statement statement = conn.createStatement(); ResultSet ...

  10. Ubuntu16.04 UltraEdit 安装&破解&使用

    (1)下载:登录到官网(http://www.ultraedit.com/downloads/uex.html)选在对应的版本进行下载. (2)安装: (使用命令行方式安装)在本地路径进行安装:sud ...