Java向服务器上传图片
在比较绚丽多彩的网站或者业务逻辑比较丰富的程序设计过程中,图片的相关操作时必不少的,尤其时图片的上传。还没有彻底摆脱纸质办公可能需要将纸质的文件备份上传,网站的建设可能需要上传用户头像、图片描述等等,这些都需要将图片从本地上传到网上(服务器)。下面将介绍笔者今天在做图片上传过程中所遇到的坑~
一、业务描述
业务要求是将机器在不断生产的照片上传到网上,以便于能在网站上查看。
二、解决思路
由于对图片这一块的处理已经比较生疏,所以打算一点一点解决这些业务需求。首先将业务分解为以下几个部分:
(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向服务器上传图片的更多相关文章
- 从app上传图片到php,再上传到java后端服务器的方法一览
在现在的网络开发中,上传图片类的需求实在是太普通不过了,但是对于怎么样做到上传图片,对于刚开始建立项目的时候,还是有点不知所措的.也许有幸,我们做的项目是之前已经有人写过类似的用例了,那么我们只需要依 ...
- 从app上传图片到php,再上传到java后端服务器的方法一条龙服务
在现在的网络开发中,上传图片类的需求实在是太普通不过了,但是对于怎么样做到上传图片,对于刚开始建立项目的时候,还是有点不知所措的.也许有幸,我们做的项目是之前已经有人写过类似的用例了,那么我们只需要依 ...
- 一个简单的Java web服务器实现
前言 一个简单的Java web服务器实现,比较简单,基于java.net.Socket和java.net.ServerSocket实现: 程序执行步骤 创建一个ServerSocket对象: 调用S ...
- Java从服务器上获取时间,动态在jsp页面显示
Java获取服务器时间,动态显示到jsp页面,大家都是到Java只能获取一次,到页面的时间是静态的,不过通过js和Java的合作,巧妙地实现此功能 本人是给电视做系统,客户要求页面能显示时间,因为电视 ...
- 常用Java Web 服务器
Java Web应用程序需要部署在Java web服务器中运行,常用的Java Web服务器有Tomcat.GlassFish.WebLogic.JBoss.WebSphere.Jetty.JRun等 ...
- java web服务器tomcat介绍【转载】
机器矩阵2016-08-10 22:14 java程序员亲切地称他为tom猫,看到这只猫可以说明1 服务器部署成功了 ,2 网络是联通的. 到底这只猫是什么来头呢? tomcat是Apache基金会下 ...
- 各种容器与服务器的区别与联系:Servlet容器、WEB容器、Java EE容器、应用服务器、WEB服务器、Java EE服务器
1.容器与服务器的联系 如上图,我们先来看下容器与服务器的联系:容器是位于应用程序/组件和服务器平台之间的接口集合,使得应用程序/组件可以方便部署到服务器上运行. 2.各种容器的区别/联系 2-1.容 ...
- 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服务器 WEB服务器 Java EE服务器
转自:https://blog.csdn.net/tjiyu/article/details/53148174 各种容器与服务器的区别与联系 Servlet容器 WEB容器 Java EE容器 应用服 ...
- 【转】Java做服务器开发语言
版权声明:本文为博主原创文章,未经博主允许不得转载. 随着游戏市场的兴起,特别是网页游戏.手机游戏的崛起,对游戏开发技术的需求越来越多.网络游戏开发是一个庞大的体系,总体来说是客户端与服务器端.客户端 ...
随机推荐
- django6-orm进阶操作
1.创建django环境的脚本 在自定义脚本中操作orm ,但是自定义脚本中不具备django的环境 ###test.py 脚本,引入django的环境即可使用orm操作数据库import os if ...
- HTTP与HTTPS初识
HTTP HTTP是一个属于应用层的协议,特点是简介.快速 HTTP客户端发起请求,创建端口HTTP服务器在端口监听客户端请求HTTP服务器向客户端返回状态和内容 网络请求,页面渲染 1.域名解析 ...
- git clone克隆代码显示“无权限或者确认存储库是否存在”
今天我用公司的电脑要继续完成我自己的git上的小项目的时候,发现git clone失败,提示 然后我在公司电脑上生成公钥感觉又太麻烦了 网上找了个好方法就是把自己电脑上的.ssh文件夹拷贝到公司电脑上 ...
- luoguP3071 [USACO13JAN]座位Seating
https://www.luogu.org/problem/P3071 AC代码: https://www.luogu.org/blog/user33426/solution-p3071 莫名其妙RE ...
- zz高精地图和定位在自动驾驶的应用
本次分享聚焦于高精地图在自动驾驶中的应用,主要分为以下两部分: 1. 高精地图 High Definition Map 拓扑地图 Topological Map / Road Graph 3D栅格地图 ...
- Eclipse中如何安装Git插件
现在的Eclipse一般都自带Git插件. 检查Eclipse是否有Git插件: 方法一:Help—>About Eclipse,出现下面的图标,说明Eclipse中已有Git插件,就不用安装了 ...
- MySQL 行溢出数据
MySQL 行溢出数据 MySQL 对一条记录占用的最大储存空间是有限制的,除了 BLOB 和 TEXT 类型之外,其他所有列 (不包括隐藏列和记录头信息) 占用的字节长度不能超过 65535 个字节 ...
- Leetcode173. 二叉搜索树迭代器
空间复杂度O(h)而不是O(n),因此不能直接在初始化函数中做中序遍历将结果存储到数组中.next()和hasNext()时间复杂度为O(1)首先本题很容易想到用二叉树的中序遍历去解决,外加注意点1. ...
- 无法用排他锁锁定该数据库,以执行该操作。 (Microsoft SQL Server,错误: 5030)
ALTER DATABASE Test_DB modify name = Howie --更改数据库名 EXEC sp_renamedb 'Howie' , 'Howie_Wee' --更改数据库名 ...
- Vue v-for使用 vue中循环输出数据
v-for的使用: 代码: <!doctype html> <html lang="en"> <head> <meta charset=& ...