HttpMime 处理 多部件 POST 请求

时间:2022-10-23 20:56:30

HttpMime 处理 多部件 POST 请求

在有的场合例如我们要用到上传文件的时候,就不能使用基本的GET请求和POST 请求了,我们要使用多部件的POST请求。由于Android 附带的 HttpClient 版本暂不支持多部件 POST 请求,所以我们需要用到一个 HttpMime 开源项目,该组件是专门处理与 MIME 类型有关的操作。因为 HttpMime 是包含在 HttpComponents 项目中的,所以我们需要去 apache 官方网站下载 HttpComponents,然后把其中的HttpMime.jar 包放到项目中去。

HttpMime 处理 多部件 POST 请求
 1 package com.scott.http;
 2
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.InputStream;
 5
 6 import org.apache.http.HttpResponse;
 7 import org.apache.http.HttpStatus;
 8 import org.apache.http.client.HttpClient;
 9 import org.apache.http.client.methods.HttpGet;
10
11 import android.app.Activity;
12 import android.os.Bundle;
13 import android.view.View;
14 import android.widget.Button;
15 import android.widget.Toast;
16
17 public class HttpActivity extends Activity {
18     @Override
19     protected void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.main);
22         Button btn = (Button) findViewById(R.id.btn);
23         btn.setOnClickListener(new View.OnClickListener() {
24             @Override
25             public void onClick(View v) {
26                 execute();
27             }
28         });
29
30     }
31
32     private void execute() {
33         try {
34             MyApplication app = (MyApplication) this.getApplication();    //获取MyApplication实例
35             HttpClient client = app.getHttpClient();    //获取HttpClient实例
36             HttpGet get = new HttpGet("http://192.168.1.57:8080/web/TestServlet?id=1001&name=john&age=60");
37             HttpResponse response = client.execute(get);
38             if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
39                 InputStream is = response.getEntity().getContent();
40                 String result = inStream2String(is);
41                 Toast.makeText(this, result, Toast.LENGTH_LONG).show();
42             }
43         } catch (Exception e) {
44             e.printStackTrace();
45         }
46     }
47
48     //将输入流转换成字符串
49     private String inStream2String(InputStream is) throws Exception {
50         ByteArrayOutputStream baos = new ByteArrayOutputStream();
51         byte[] buf = new byte[1024];
52         int len = -1;
53         while ((len = is.read(buf)) != -1) {
54             baos.write(buf, 0, len);
55         }
56         return new String(baos.toByteArray());
57     }
58 }
HttpMime 处理 多部件 POST 请求

在实际应用中,我们不能每次都新建 HttpClient,而是应该只为整个应用创建一个HttpClient,并将其用于所有 HTTP 通信。此外,还应该注意在通过一个 HttpClient 同时发出多个请求时可能发生的多线程问题。针对这两个问题,我们需要改进一下我们的项目:

1、扩展系统默认的 Application,并应用在项目中。

2、使用 HttpClient 类库提供的 ThreadSafeClientManager 来创建和管理 HttpClient。

HttpMime 处理 多部件 POST 请求
 1 package com.scott.http;
 2
 3 import org.apache.http.HttpVersion;
 4 import org.apache.http.client.HttpClient;
 5 import org.apache.http.conn.ClientConnectionManager;
 6 import org.apache.http.conn.scheme.PlainSocketFactory;
 7 import org.apache.http.conn.scheme.Scheme;
 8 import org.apache.http.conn.scheme.SchemeRegistry;
 9 import org.apache.http.conn.ssl.SSLSocketFactory;
10 import org.apache.http.impl.client.DefaultHttpClient;
11 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
12 import org.apache.http.params.BasicHttpParams;
13 import org.apache.http.params.HttpParams;
14 import org.apache.http.params.HttpProtocolParams;
15 import org.apache.http.protocol.HTTP;
16
17 import android.app.Application;
18
19 public class MyApplication extends Application {
20
21     private HttpClient httpClient;
22
23     @Override
24     public void onCreate() {
25         super.onCreate();
26         httpClient = this.createHttpClient();
27     }
28
29     @Override
30     public void onLowMemory() {
31         super.onLowMemory();
32         this.shutdownHttpClient();
33     }
34
35     @Override
36     public void onTerminate() {
37         super.onTerminate();
38         this.shutdownHttpClient();
39     }
40
41     //创建HttpClient实例
42     private HttpClient createHttpClient() {
43         HttpParams params = new BasicHttpParams();
44         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
45         HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
46         HttpProtocolParams.setUseExpectContinue(params, true);
47
48         SchemeRegistry schReg = new SchemeRegistry();
49         schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
50         schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
51
52         ClientConnectionManager connMgr = new ThreadSafeClientConnManager(params, schReg);
53
54         return new DefaultHttpClient(connMgr, params);
55     }
56
57     //关闭连接管理器并释放资源
58     private void shutdownHttpClient() {
59         if (httpClient != null && httpClient.getConnectionManager() != null) {
60             httpClient.getConnectionManager().shutdown();
61         }
62     }
63
64     //对外提供HttpClient实例
65     public HttpClient getHttpClient() {
66         return httpClient;
67     }
68 }
HttpMime 处理 多部件 POST 请求

在 testUpload 测试用例,我们用 HttpMime 提供的 InputStreamBody 处理文件流参数,用 StringBody 处理普通文本参数,最后把所有类型参数都加入到一个 MultipartEntity 的实例中,并将这个 multipartEntity 设置为此次 POST 请求的参数实体,然后执行 POST请求。

HttpMime 处理 多部件 POST 请求
 1 package com.scot.http.test;
 2
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.InputStream;
 5 import java.util.ArrayList;
 6 import java.util.List;
 7
 8 import junit.framework.Assert;
 9
10 import org.apache.http.HttpEntity;
11 import org.apache.http.HttpResponse;
12 import org.apache.http.HttpStatus;
13 import org.apache.http.NameValuePair;
14 import org.apache.http.client.HttpClient;
15 import org.apache.http.client.entity.UrlEncodedFormEntity;
16 import org.apache.http.client.methods.HttpGet;
17 import org.apache.http.client.methods.HttpPost;
18 import org.apache.http.entity.mime.MultipartEntity;
19 import org.apache.http.entity.mime.content.InputStreamBody;
20 import org.apache.http.entity.mime.content.StringBody;
21 import org.apache.http.impl.client.DefaultHttpClient;
22 import org.apache.http.message.BasicNameValuePair;
23
24 import android.test.AndroidTestCase;
25
26 public class HttpTest extends AndroidTestCase {
27
28     private static final String PATH = "http://192.168.1.57:8080/web";
29
30     public void testGet() throws Exception {
31         HttpClient client = new DefaultHttpClient();
32         HttpGet get = new HttpGet(PATH + "/TestServlet?id=1001&name=john&age=60");
33         HttpResponse response = client.execute(get);
34         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
35             InputStream is = response.getEntity().getContent();
36             String result = inStream2String(is);
37             Assert.assertEquals(result, "GET_SUCCESS");
38         }
39     }
40
41     public void testPost() throws Exception {
42         HttpClient client = new DefaultHttpClient();
43         HttpPost post = new HttpPost(PATH + "/TestServlet");
44         List<NameValuePair> params = new ArrayList<NameValuePair>();
45         params.add(new BasicNameValuePair("id", "1001"));
46         params.add(new BasicNameValuePair("name", "john"));
47         params.add(new BasicNameValuePair("age", "60"));
48         HttpEntity formEntity = new UrlEncodedFormEntity(params);
49         post.setEntity(formEntity);
50         HttpResponse response = client.execute(post);
51         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
52             InputStream is = response.getEntity().getContent();
53             String result = inStream2String(is);
54             Assert.assertEquals(result, "POST_SUCCESS");
55         }
56     }
57
58     public void testUpload() throws Exception {
59         InputStream is = getContext().getAssets().open("books.xml");
60         HttpClient client = new DefaultHttpClient();
61         HttpPost post = new HttpPost(PATH + "/UploadServlet");
62         InputStreamBody isb = new InputStreamBody(is, "books.xml");
63         MultipartEntity multipartEntity = new MultipartEntity();
64         multipartEntity.addPart("file", isb);
65         multipartEntity.addPart("desc", new StringBody("this is description."));
66         post.setEntity(multipartEntity);
67         HttpResponse response = client.execute(post);
68         if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
69             is = response.getEntity().getContent();
70             String result = inStream2String(is);
71             Assert.assertEquals(result, "UPLOAD_SUCCESS");
72         }
73     }
74
75     //将输入流转换成字符串
76     private String inStream2String(InputStream is) throws Exception {
77         ByteArrayOutputStream baos = new ByteArrayOutputStream();
78         byte[] buf = new byte[1024];
79         int len = -1;
80         while ((len = is.read(buf)) != -1) {
81             baos.write(buf, 0, len);
82         }
83         return new String(baos.toByteArray());
84     }
85 }
HttpMime 处理 多部件 POST 请求

服务端 Servlet 使用 apache 开源项目 FileUpload 进行处理,所以需要 commons-fileupload 和 commons-io 这两个项目的 jar 包。

HttpMime 处理 多部件 POST 请求
 1 package com.scott.web.servlet;
 2
 3 import java.io.FileOutputStream;
 4 import java.io.IOException;
 5 import java.util.Iterator;
 6 import java.util.List;
 7
 8 import javax.servlet.ServletException;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12
13 import org.apache.commons.fileupload.FileItem;
14 import org.apache.commons.fileupload.FileItemFactory;
15 import org.apache.commons.fileupload.FileUploadException;
16 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
17 import org.apache.commons.fileupload.servlet.ServletFileUpload;
18
19 @SuppressWarnings("serial")
20 public class UploadServlet extends HttpServlet {
21
22     @Override
23     @SuppressWarnings("rawtypes")
24     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
25         boolean isMultipart = ServletFileUpload.isMultipartContent(request);
26         if (isMultipart) {
27             FileItemFactory factory = new DiskFileItemFactory();
28             ServletFileUpload upload = new ServletFileUpload(factory);
29             try {
30                 List items = upload.parseRequest(request);
31                 Iterator iter = items.iterator();
32                 while (iter.hasNext()) {
33                     FileItem item = (FileItem) iter.next();
34                     if (item.isFormField()) {
35                         //普通文本信息处理
36                         String paramName = item.getFieldName();
37                         String paramValue = item.getString();
38                         System.out.println(paramName + ":" + paramValue);
39                     } else {
40                         //上传文件信息处理
41                         String fileName = item.getName();
42                         byte[] data = item.get();
43                         String filePath = getServletContext().getRealPath("/files") + "/" + fileName;
44                         FileOutputStream fos = new FileOutputStream(filePath);
45                         fos.write(data);
46                         fos.close();
47                     }
48                 }
49             } catch (FileUploadException e) {
50                 e.printStackTrace();
51             }
52         }
53         response.getWriter().write("UPLOAD_SUCCESS");
54     }
55 }
HttpMime 处理 多部件 POST 请求

HttpMime 处理 多部件 POST 请求的更多相关文章

  1. Android中使用HTTP服务

    在Android中,除了使用java.net包下的API访问HTTP服务之外,我们还可以换一种途径去完成工作.Android SDK附带了Apache的HttpClient API.Apache Ht ...

  2. HttpClient 4&period;5&period;x 工具类设计与实现

    最近,业务需要在java服务端发起http请求,需要实现"GET","POST","PUT"等基本方法.于是想以 "HttpCli ...

  3. Composite模式

    1 意图:将对象组成树形结构,以表示“部分——整体”的层次结构.Composite使得用户对单个对象和组合对象的使用具有一致性. 2 动机:同意处理图元对象和包含图元的容器对象.Composite通过 ...

  4. ASP&period;NET Core重写个人博客站点小结

    今天用ASP.NET Core重写了个人博客站点,原来是基于ASP.NET 4.5开发的.重写工作总体很顺利,最后成功发布到Ubunt+Nginx平台上.效果如下: 右边的Header信息里可以看到已 ...

  5. MEF 编程指南(十二):批量组合

    MEF 容器实例并非不可变的.如果目录支持改变(像监控目录变动)或者在运行时添加/移除部件都可能发生改变.以前,你不得不做出改动并且调用 CompositionContainer 上的 Compose ...

  6. NET Core个人博客

    NET Core重写个人博客站点小结 今天用ASP.NET Core重写了个人博客站点,原来是基于ASP.NET 4.5开发的.重写工作总体很顺利,最后成功发布到Ubunt+Nginx平台上.效果如下 ...

  7. Java解析导入Excel文件后台代码实现

    使用MultipartFile上传Excel文件后端代码实现:(springmvc下的spring-webmvc (MultipartFile )上传) 由于POST一个包含文件上传的Form会以mu ...

  8. Odoo Javascript 参考

    本文介绍了odoo javascript框架.从代码行的角度来看,这个框架不是一个大的应用程序,但它是非常通用的,因为它基本上是一个将声明性接口描述转换为活动应用程序的机器,能够与数据库中的每个模型和 ...

  9. Sentry&lpar;v20&period;12&period;1&rpar; K8S 云原生架构探索,JavaScript Enriching Events&lpar;丰富事件信息&rpar;

    系列 Sentry-Go SDK 中文实践指南 一起来刷 Sentry For Go 官方文档之 Enriching Events Snuba:Sentry 新的搜索基础设施(基于 ClickHous ...

随机推荐

  1. Android平台二维码之生成,扫描 &amp&semi; 识别

    1.二维码的前世今生 “二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的:在代码编制上巧妙地利 ...

  2. MySQL之count&lpar;&ast;&rpar;与count&lpar;id&rpar;效率比较&lpar;转&rpar;

    优化总结: 1.任何情况下SELECT COUNT(*) FROM tablename是最优选择: 2.尽量减少SELECT COUNT(*) FROM tablename WHERE COL = ’ ...

  3. 线程join

      class ThreadB extends Thread {     private String ID="0";     private int time=0;     pu ...

  4. Linux的nginx环境的vue 部署

    1.使用WebStrom编程好的vue 进入到Terminal运行npm run build           2.使用WinSCP进入到nginx 目录配置文件下面,找到nginx.conf文件: ...

  5. Solr 06 - Solr中配置使用IK分词器 &lpar;配置schema&period;xml&rpar;

    目录 1 配置中文分词器 1.1 准备IK中文分词器 1.2 配置schema.xml文件 1.3 重启Tomcat并测试 2 配置业务域 2.1 准备商品数据 2.2 配置商品业务域 2.3 配置s ...

  6. 【Dubbo源码学习】负载均衡算法(2)-轮询算法的实现

    @Overrideprotected <T> Invoker<T> doSelect(List<Invoker<T>> invokers, URL ur ...

  7. JavaWeb基础【1】—— Tomcat

    此笔记是学习黑马程序员JavaWeb系列视频的课堂笔记. 感谢黑马程序员. 一.Tomcat概述 Tomcat服务器由Apache提供,开源免费.由于Sun和其他公司参与到了Tomcat的开发中,所以 ...

  8. controller&comma;service&comma;repository&comma;component注解的使用对比

    项目中的controller层使用@controller注解 @Controller 用于标记在一个类上,使用它标记的类就是一个SpringMVC Controller 对象.分发处理器将会扫描使用了 ...

  9. SQLServer导入大sql文件报错 对 COM 组件的调用返回了错误 HRESULT E&lowbar;FAIL。 &lpar;mscorlib&rpar;

    打开cmd执行(d:\script.sql为sql文件位置):  sqlcmd -S 127.0.0.1 -U sa -P sa -i d:\script.sql    From:https://ww ...

  10. HDU 1258 Sum It Up(dfs 巧妙去重)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1258 Sum It Up Time Limit: 2000/1000 MS (Java/Others) ...