HTTP请求中的Body构建——.NET客户端调用JAVA服务进行文件上传

PS:今日的第二篇,当日事还要当日毕:)
 
http的POST请求发送的内容在Body中,因此有时候会有我们自己构建body的情况。
JAVA使用http—post上传file时,spring框架中有HttpEntity类封装了http请求中的Body内容。JAVA客户端调用时非常方便,直接将File对象赋值进去就可以了。
C#中没有找到有类似的封装的(有发现的大神麻烦告知一声:)),HttpWebRequest是原始的http请求类,因此Body中的内容只能自己写入。
 
首先来看下http请求的内容:

POST /forwardOrder/applyRefund HTTP/1.1
Host: XXXX
Connection: keep-alive
Content-Length: 3478080
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://192.168.1.115:3800
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryHUq1k5ZLV25EmvgR
Referer: http://192.168.1.115:3800/forwardOrder/refundOrder?id=160722103139001234
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: JSESSIONID=52F3D94B82F97240D5A4BBCA2FB08969;
 
------WebKitFormBoundaryHUq1k5ZLV25EmvgR
Content-Disposition: form-data; name="condition"
 
{"orderId":"160722103139001234","fileName":"C:\\fakepath\\12349.jpg"}
------WebKitFormBoundaryHUq1k5ZLV25EmvgR
Content-Disposition: form-data; name="file"; filename="12349.jpg"
Content-Type: image/jpeg
 
����

红色的是HttpHeader的内容,boundary定义了body的分割符。
蓝色的就是我们的Body了,每一个参数使用boundary来进行分割。
特殊的例如文件参数,需要加上Content-Type描述。
乱码部分就是我们的文件字节流了。
最后注意换行和空格的写入。
 
C#代码示例:
  1         /// <summary>
  2         /// 上传文件操作
  3         /// </summary>
  4         /// <param name="fileStream"> 文件流</param>
  5         /// <param name="url"> 上传地址</param>
  6         /// <param name="fileName"> 文件名</param>
  7         /// <param name="contenttype"> 上下文类型 </param>
  8         /// <returns> 返回值</returns>
  9         private Dictionary <string, string> UploadFileEx(Stream fileStream, string url, string fileName, string contenttype)
 10         {
 11             Dictionary<string , string> result = new Dictionary <string, string>();
 12  
 13             if ((contenttype == null ) || (contenttype.Length == 0))
 14             {
 15                 contenttype = "application/octet-stream" ;
 16             }
 17  
 18             Uri uri = new Uri(url);
 19             string boundary = "----" + DateTime.Now.Ticks.ToString( "x");
 20             HttpWebRequest webrequest = (HttpWebRequest )WebRequest.Create(uri);
 21             webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
 22             webrequest.Method = "POST";
 23  
 24             // 构建POST消息头,除文件之外的键值对都需要赋值
 25             StringBuilder sb = new StringBuilder();
 26             sb.AppendFormat( "--{0}", boundary);
 27             sb.AppendLine( string.Empty);
 28             sb.Append( "Content-Disposition: form-data; name=\"uptype\";" );
 29             sb.AppendLine( string.Empty);
 30             sb.AppendLine( string.Empty);
 31             sb.Append( "clbuss");
 32             sb.AppendLine( string.Empty);
 33  
 34             sb.AppendFormat( "--{0}", boundary);
 35             sb.AppendLine( string.Empty);
 36             sb.Append( "Content-Disposition: form-data; name=\"fileName\";" );
 37             sb.AppendLine( string.Empty);
 38             sb.AppendLine( string.Empty);
 39             sb.Append(fileName);
 40             sb.AppendLine( string.Empty);
 41  
 42             sb.AppendFormat( "--{0}", boundary);
 43             sb.AppendLine( string.Empty);
 44             sb.AppendFormat( "Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"" , fileName);
 45             sb.AppendLine( string.Empty);
 46             sb.AppendFormat( "Content-Type: {0}", contenttype);
 47             sb.AppendLine( string.Empty);
 48             sb.AppendLine( string.Empty);
 49  
 50             string postHeader = sb.ToString();
 51             byte[] postHeaderBytes = Encoding .UTF8.GetBytes(postHeader);
 52  
 53             // 构建POST消息尾
 54             StringBuilder endSb = new StringBuilder();
 55             endSb.AppendLine( string.Empty);
 56             endSb.AppendFormat( "--{0}", boundary);
 57             byte[] boundaryBytes = Encoding .UTF8.GetBytes(endSb.ToString());
 58             long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
 59             webrequest.ContentLength = length;
 60             Stream requestStream = webrequest.GetRequestStream();
 61  
 62             // 写入消息头  
 63             requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
 64  
 65             // 写入文件内容
 66             byte[] buffer = new byte[checked(( uint)Math .Min(4096, (int)fileStream.Length))];
 67             int bytesRead = 0;
 68  
 69             while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
 70             {
 71                 requestStream.Write(buffer, 0, bytesRead);
 72             }
 73  
 74             // 写入消息尾 
 75             requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
 76             WebResponse responce = webrequest.GetResponse();
 77             Stream s = responce.GetResponseStream();
 78             StreamReader sr = new StreamReader(s);
 79             string resStr = sr.ReadToEnd();
 80             Dictionary<string , object> resDic = JsonConvert.DeserializeObject<Dictionary <string, object>>(resStr);
 81             if (resDic["code" ].ToString() == "1")
 82             {
 83                 Dictionary<string , string> resDetail = JsonConvert.DeserializeObject<Dictionary <string, string>>(resDic["content" ].ToString());
 84                 if (resDetail["code" ] == "1")
 85                 {
 86                     result.Add( "issucess", "1" );
 87                     result.Add( "address", BaseSysParamCache .GetSysParam("ShareUploadImgUrl") + resDetail["path" ]);
 88                 }
 89                 else
 90                 {
 91                     result.Add( "issucess", "0" );
 92                     result.Add( "msg", resDetail["msg" ]);
 93                 }
 94             }
 95             else
 96             {
 97                 result.Add( "issucess", "0" );
 98                 result.Add( "msg", resDic["message" ].ToString());
 99             }
100  
101             return result;
102         }    
View Code
 
http请求对于JAVA和C#本身其实并无区分,只是使用的方式不同而已。
无论何种情况,源生的HTTP请求内容都是通用的。
posted @ 2016-07-26 18:58  一只LowCoder  阅读(3665)  评论(0编辑  收藏  举报