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>
查看代码
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>${commons-fileupload.version}</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或其他技术都是可以做到的,然后也需要将该路径写入数据库进行保存。
用户点评