C#以post方式調用struts rest-plugin service的問題

來源:互聯網
上載者:User

標籤:style   blog   http   io   color   os   ar   java   for   

struts2: 玩轉 rest-plugin 一文中,學習了用struts2開發restful service的方法,發現用c#以post方式調用時各種報錯,但java、ajax,包括firefox 的rest client外掛程式測試也無問題。

 

先給出rest service中的這個方法:

 1     // POST /orders 2     public HttpHeaders create() throws IOException, ServletException { 3         ordersService.doSave(model); 4         HttpServletResponse response = ServletActionContext.getResponse(); 5         HttpServletRequest request = ServletActionContext.getRequest(); 6         String ContentType = request.getHeader("Content-Type").toLowerCase(); 7         if (ContentType.startsWith("application/xml")) { // 返回xml視圖 8             response.sendRedirect("orders/" + model.getId() + ".xml"); 9         } else if (ContentType.startsWith("application/json")) { // 返回json視圖10             response.sendRedirect("orders/" + model.getId() + ".json");11         } else {// 返回xhtml整頁模式12             response.sendRedirect("orders/");13         }14         return null;15     }
View Code

代碼不複雜,post一段String過來(xml/json/html格式均可),自動對應成Order對象的執行個體model,然後根據請求HttpHeader中的Content-Type,如果是xml(application/xml),則返回model對應的xml,如果是json(application/json),則返回model對應的json,其它則返回頁面

 

c#的調用代碼:

 1 static string PostDataByWebClient(String postUrl, String paramData, String mediaType) 2 { 3     String result = String.Empty; 4     try 5     { 6         byte[] postData = Encoding.UTF8.GetBytes(paramData); 7         WebClient webClient = new WebClient(); 8         webClient.Headers.Add("Content-Type", mediaType); 9         byte[] responseData = webClient.UploadData(new Uri(postUrl), "POST", postData);10         result = Encoding.UTF8.GetString(responseData);11     }12     catch (Exception e)13     {14         Console.WriteLine(e);15         result = e.Message;16     }17     return result;18 }19 20 static string PostDataByWebRequest(string postUrl, string paramData, String mediaType)21 {22     string result = string.Empty;23     Stream newStream = null;24     StreamReader sr = null;25     HttpWebResponse response = null;26     try27     {28         byte[] byteArray = Encoding.UTF8.GetBytes(paramData);29         HttpWebRequest webReq = (HttpWebRequest)WebRequest.Create(new Uri(postUrl));30         webReq.Method = "POST";31         webReq.ContentType = mediaType;32         webReq.ContentLength = byteArray.Length;33         newStream = webReq.GetRequestStream();34         newStream.Write(byteArray, 0, byteArray.Length);35         response = (HttpWebResponse)webReq.GetResponse();36         sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);37         result = sr.ReadToEnd();38     }39     catch (Exception ex)40     {41         Console.WriteLine(ex);42         result = ex.Message;43     }44     finally45     {46         if (sr != null)47         {48             sr.Close();49         }50         if (response != null)51         {52             response.Close();53         }54         if (newStream != null)55         {56             newStream.Close();57         }58     }59     return result;60 }
View Code

這二種常用的調用方式,居然全跪了,返回的結果是一堆java異常:
 java.lang.NullPointerException
        at org.apache.struts2.convention.ConventionUnknownHandler.handleUnknownActionMethod(ConventionUnknownHandler.java:423)
        at com.opensymphony.xwork2.DefaultUnknownHandlerManager.handleUnknownMethod(DefaultUnknownHandlerManager.java:96)

...

無奈百度了一圈,發現還有另一種方法,利用TcpClient調用

 1 static string PostDataByTcpClient(string postUrl, string paramData, String mediaType) 2 { 3     String result = String.Empty; 4     TcpClient clientSocket = null; 5     Stream readStream = null; 6     try 7     { 8         clientSocket = new TcpClient(); 9         Uri URI = new Uri(postUrl);10         clientSocket.Connect(URI.Host, URI.Port);11         StringBuilder RequestHeaders = new StringBuilder();//用來儲存HTML協議頭部資訊12         RequestHeaders.AppendFormat("{0} {1} HTTP/1.1\r\n", "POST", URI.PathAndQuery);13         RequestHeaders.AppendFormat("Connection:close\r\n");14         RequestHeaders.AppendFormat("Host:{0}\r\n", URI.Host);15         RequestHeaders.AppendFormat("Content-Type:{0}\r\n",mediaType);16         RequestHeaders.AppendFormat("\r\n");17         RequestHeaders.Append(paramData + "\r\n");18         Encoding encoding = Encoding.UTF8;19         byte[] request = encoding.GetBytes(RequestHeaders.ToString());20         clientSocket.Client.Send(request);21         readStream = clientSocket.GetStream();22         StreamReader sr = new StreamReader(readStream, Encoding.UTF8);23         result = sr.ReadToEnd();24     }25     catch (Exception e)26     {27         Console.WriteLine(e);28         result = e.Message;29     }30     finally31     {32         if (readStream != null)33         {34             readStream.Close();35         }36         if (clientSocket != null)37         {38             clientSocket.Close();39         }40     }41     return result;42 }
View Code

總算調用成功了,但是由於java端是用SendRedirect在用戶端重新導向的,所以該方法得到的返回結果如下:

HTTP/1.1 302 Found
Server: Apache-Coyote/1.1
Location: http://localhost/struts2-rest-ex/rest/orders/230.xml
Content-Length: 0
Date: Mon, 27 Oct 2014 03:18:56 GMT
Connection: close

是一堆http頭的原文,只能曲線救國,將其中的Location:後的部分(即重新導向的url),取出來再次get請求,這裡還有一個坑,該url返回時,把port弄丟了,正確的重新導向url應該是:

http://localhost:8080/struts2-rest-ex/rest/orders/230.xml

手動把連接埠拼上,再次get,總算返回正確了

 

C#以post方式調用struts rest-plugin service的問題

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.