Java HttpClient +Rest WCF

如果想透彻了解什么是REST,这里有Roy Fielding博士最原始的文档:http://yun.baidu.com/share/link?shareid=3150451374&uk=170352852

用到的主要工具包:

1.Apache httpclient 4.4.1 网址:http://hc.apache.org/

2.jackson-annotations-2.5.0,jackson-core-2.5.0,jackson-databind-2.5.0 网址:http://wiki.fasterxml.com/JacksonDownload

首先来个流程图,便于理解整个功能实现

1.JAVA客户端:

1.1 主函数文件

这是客户端的主函数文件,try...catch{}语句分别调用四种HTTP方法,需要注意的是各个方法是否幂等,GET,PUT,DELETE方法是幂等的,但是POST不是,

所以有的时候不能图省事就只用POST或者其他方法也用POST。

Invoker.java

  1 package superman.jackson.qianzhilan;
  2 import org.json.JSONObject;
  3 import entity.jackson.qianzhilan.Student;
  4 
  5 public class Invoker {
  6     
  7     /* the address of services */
  8     private static String HOST="http://ip address";
  9     private static String BAREHOST="ip address";
 10     private static String SERVICE_ADD="/wcf/MyService.svc/stuRegister";
 11     private static String SERVICE_SELECT="/wcf/MyService.svc/SelStuInfo";
 12     private static String SERVICE_UPDATE="/wcf/MyService.svc/updStudent";
 13     private static String SERVICE_DELETE="/wcf/MyService.svc/delStudent";
 14     
 15     public static void main(String args[])
 16     {
 17         String result="";
 18         WebClient client=new WebClient();
 19         JSONObject json = new JSONObject();
 20         
 21         /**
 22          * HttpClient Put method 
 23          * 
 24          */
 25         try {
 26             
 27             Student stu = new Student();
 28             stu.setS_id(90010);
 29             stu.setSname("90010");     
 30             stu.setBirthplace("");
 31             stu.setEducation("");
 32             stu.setE_mail("");
 33             stu.setId_card_no("");
 34             stu.setPwd("");
 35             stu.setSalary(0);
 36             stu.setSex("");
 37             stu.setWork_place("");
 38             
 39             result = client.doInsert(HOST+SERVICE_ADD, stu,"application/json");
 40     
 41         } catch (Exception e) {
 42             // TODO Auto-generated catch block
 43             e.printStackTrace();
 44         }
 45         
 46         /**
 47          * HttpClient GET method 
 48          * input params:id
 49          * out params:DataTable
 50          */
 51         try {
 52             int s_id=90015;
 53             String reString;
 54             reString= client.doSelect(BAREHOST,SERVICE_SELECT,s_id);
 55             
 56             if(reString==null)
 57                 System.err.println("select failure!");
 58 
 59         } catch (Exception e) {
 60             // TODO: handle exception
 61             e.printStackTrace();
 62         }
 63 
 64 
 65     
 66     /**
 67      * HttpClient POST (update) method 
 68      * 
 69      */
 70 
 71     try {
 72         
 73         Student stu = new Student();
 74         stu.setS_id(90015);
 75         stu.setSname("90015");     
 76         stu.setBirthplace("山东省");
 77         stu.setEducation("本科");
 78         stu.setE_mail("foo@yeah.ent");
 79         stu.setId_card_no("");
 80         stu.setPwd("");
 81         stu.setSalary(10000);
 82         stu.setSex("男");
 83         stu.setWork_place("");
 84         
 85         result = client.doUpdate(HOST+SERVICE_UPDATE, stu,"application/json");
 86 
 87     } catch (Exception e) {
 88         // TODO Auto-generated catch block
 89         e.printStackTrace();
 90         }
 91 
 92     /**
 93      * HttpClient Delete method 
 94      * 
 95      */
 96 
 97     try {
 98         
 99 
100         client.doDelete(BAREHOST,SERVICE_DELETE,103);
101        
102 
103     } catch (Exception e) {
104         // TODO Auto-generated catch block
105         e.printStackTrace();
106         }
107     }
108     
109     
110 }

 

1.2 调用函数实现文件

要特别注意doSelect和doDelete方法与其他两个方法实现的不同,好像HTTP1.1并不推荐在消息中携带body,因此只有在Uri添加比较简单的参数。

之前看到网上有些人是重写了自己的HttpGet和HttpDelete方法实现其携带body的方法,但是这不符合HTTP1.1的规范。

WebClient.java

  1 package superman.jackson.qianzhilan;
  2 
  3 import java.io.IOException;
  4 import java.net.HttpURLConnection;
  5 import java.net.URI;
  6 
  7 import org.apache.http.HttpResponse;
  8 import org.apache.http.client.ClientProtocolException;
  9 import org.apache.http.client.HttpClient;
 10 import org.apache.http.client.methods.HttpDelete;
 11 import org.apache.http.client.methods.HttpGet;
 12 
 13 import org.apache.http.client.methods.HttpPost;
 14 import org.apache.http.client.methods.HttpPut;
 15 import org.apache.http.client.utils.URIBuilder;
 16 import org.apache.http.entity.StringEntity;
 17 import org.apache.http.impl.client.HttpClients;
 18 import org.apache.http.util.EntityUtils;
 19 
 20 import org.json.JSONStringer;
 21 
 22 
 23 import com.fasterxml.jackson.databind.ObjectMapper;
 24 
 25 import entity.jackson.qianzhilan.Student;
 26 
 27 public class WebClient {
 28     
 29     public WebClient() {
 30 
 31     }
 32 
 33     /**
 34      * @param url 
 35      * @param Student 
 36      * @param contentType 
 37      * @return json string
 38      */
 39     public String doInsert(String url, Student stu, String contentType) {
 40 
 41         String strResp = "";
 42         HttpPut request = new HttpPut(url);
 43         request.setHeader("Accept", contentType);
 44         request.setHeader("Content-type", contentType);
 45 
 46         /* method one:user org.json jar to generate the data of json format */
 47         JSONStringer jStr;
 48         /* method one:user jackson jars to generate the data of json format */
 49         String jsonStr;
 50         ObjectMapper mapper=new ObjectMapper();
 51         try {
 52             
 53             /* method one:user org.json jar to generate the data of json format */
 54 //             jStr = (JSONStringer)(new JSONStringer()
 55 //                 .object().key("stu")
 56 //                     .object()
 57 //                         .key("s_id").value(stu.getS_id())
 58 //                         .key("sname").value(stu.getSname())
 59 //                         .key("sex").value(stu.getSex())
 60 //                         .key("id_card_no").value(stu.getId_card_no())
 61 //                         .key("education").value(stu.getEducation())
 62 //                         .key("work_place").value(stu.getWork_place())
 63 //                         .key("salary").value(stu.getSalary())
 64 //                         .key("birthplace").value(stu.getBirthplace())
 65 //                         .key("pwd").value(stu.getPwd())
 66 //                         .key("e_mail").value(stu.getE_mail())
 67 //                    .endObject()
 68 //                .endObject());
 69             
 70             jsonStr=mapper.writeValueAsString(stu);
 71             StringEntity entity = new StringEntity(jsonStr);
 72             request.setEntity(entity);
 73             System.out.printf("send the content:"+jsonStr+"
");
 74             // create the httpclient 
 75             HttpClient httpClient = HttpClients.createDefault();
 76 
 77            //  httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,30000);
 78              HttpResponse response = httpClient.execute(request);
 79             // judge the response status 
 80             if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK)
 81                 {
 82                 String tmpString;
 83                 tmpString = EntityUtils.toString(response.getEntity());
 84                 System.out.println("the result:"+tmpString );
 85                 }
 86             
 87             System.out.printf("server reply: "
 88                     +response.getEntity().getContent()+ 
 89                      response.getFirstHeader("Content-type")+
 90                      response.getStatusLine().toString()+"
");
 91         } catch (Exception e) {
 92             // TODO Auto-generated catch block
 93             e.printStackTrace();
 94         } 
 95 
 96         // Reload plate numbers
 97 
 98         return strResp;
 99 
100     }
101     public String doSelect(String host,String servUri,int s_id) throws Exception  {
102         
103         String strResp=null;
104 //        JSONObject json = new JSONObject();
105 //        json.put("s_id", s_id);
106         URI uri = new URIBuilder()
107         .setScheme("http")
108         .setHost(host)
109         .setPath(servUri)
110         .setParameter("s_id", String.valueOf(s_id))
111         .build();
112         HttpGet httpGet = new HttpGet(uri);
113 //        StringEntity entity = new StringEntity(json.toString(),"UTF-8");
114 //        entity.setContentType(contentType);
115         
116 //        httpGet.setEntity(entity);
117         HttpClient client2 = HttpClients.createDefault();
118         HttpResponse resp;
119         try {
120             resp = client2.execute(httpGet);
121             
122             if (resp.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK)
123             {
124                 strResp = EntityUtils.toString(resp.getEntity());
125                 System.out.println("the select result:"+strResp);
126                 
127             } else System.out.println("Error select Response:"
128                         + resp.getStatusLine().toString());
129         } catch (ClientProtocolException e) {
130             // TODO Auto-generated catch block
131             e.printStackTrace();
132         } catch (IOException e) {
133             // TODO Auto-generated catch block
134             e.printStackTrace();
135         }
136         
137         return strResp;
138     }
139     public String doUpdate(String url,Student stu,String contentType)
140     {
141         
142         String tmpString=null;    
143         HttpPost request=new HttpPost(url);
144         request.setHeader("Accept", contentType);
145         request.setHeader("Content-type", contentType);
146         
147         ObjectMapper mapper=new ObjectMapper();
148         String jsonString;
149         
150         try {
151             jsonString=mapper.writeValueAsString(stu);
152             StringEntity entity=new StringEntity(jsonString,"UTF-8");
153             request.setEntity(entity);
154             
155             HttpClient client=HttpClients.createDefault();
156             HttpResponse response=client.execute(request);
157             // judge the response status 
158             if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK)
159             {
160                 tmpString= EntityUtils.toString(response.getEntity());
161                 System.out.println("the update result:"+tmpString);
162             } else System.out.println("the update failure");
163         } catch (ClientProtocolException e) {
164             // TODO Auto-generated catch block
165             e.printStackTrace();
166         } catch (IOException e) {
167             // TODO Auto-generated catch block
168             e.printStackTrace();
169         }
170         return tmpString;
171     }
172     
173     public String doDelete(String host,String servUri,int s_id) throws Exception {
174 //        JSONStringer jStr;
175 //         jStr = (JSONStringer)(new JSONStringer()
176 //         .object().key("s_id").value(90012)
177 //         .endObject());
178         String tmpString=null;    
179 //        HttpPost request=new HttpPost(url);
180 //        request.setHeader("Accept", contentType);
181 //        request.setHeader("Content-type", contentType);
182         HttpDelete delete=new HttpDelete();
183 //
184         try {
185 
186 //            System.out.println(jStr.toString());
187 //            StringEntity entity=new StringEntity(jStr.toString());
188 //            entity.setContentType(contentType);
189 //            request.setEntity(entity);
190 //            /* method of delete */
191             URI uri = new URIBuilder()
192             .setScheme("http")
193             .setHost(host)
194             .setPath(servUri)
195             .setParameter("s_id",s_id)
196             .build();
197             delete.setURI(uri);
198             HttpClient client=HttpClients.createDefault();
199             HttpResponse response=client.execute(delete);
200             // judge the response status 
201             if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK)
202             {
203                 tmpString= EntityUtils.toString(response.getEntity());
204                 System.out.println("the delete result:" + tmpString);
205             } else System.out.println("the delete failure"+response.getStatusLine().toString());
206         } catch (ClientProtocolException e) {
207             // TODO Auto-generated catch block
208             e.printStackTrace();
209         } catch (IOException e) {
210             // TODO Auto-generated catch block
211             e.printStackTrace();
212         }
213         return tmpString;
214     }
215 
216 }

2.服务器端 [ Rest WCF ]

2.1 配置文件

Web.config

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <configuration>
 3 
 4   <appSettings>
 5     <add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
 6   </appSettings>
 7   <system.web>
 8     <compilation debug="true" targetFramework="4.5" />
 9     <httpRuntime targetFramework="4.5"/>
10   </system.web>
11   
12   <system.serviceModel>
13     <behaviors>
14       <serviceBehaviors>
15         <behavior>
16           <!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
17           <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
18           <!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
19           <serviceDebug includeExceptionDetailInFaults="true"/>
20         
21         </behavior>
22       </serviceBehaviors>
23       <!--endpointBehaviors 下的名为json的bahavior使服务器端支持Http功能 -->
24       <endpointBehaviors>
25         <behavior name="json">
26            <webHttp helpEnabled="true" />
27         </behavior>
28       </endpointBehaviors>
29     </behaviors>
30     <protocolMapping>
31         <add binding="basicHttpsBinding" scheme="https" />
32     </protocolMapping>
33     <!-- sevices下有两个子节点endpoint分别配置提供Http服务接口时和本地服务接口时所应具有的属性 -->
34     <services>
35       <service name="SuperWCF.MyService">
36         <endpoint address="" binding="webHttpBinding" contract="SuperWCF.IHello" behaviorConfiguration="json">
37           
38         </endpoint>
39         
40        <endpoint address="localhost" binding="basicHttpBinding" contract="SuperWCF.IHello" />
41       </service>  
42     </services>
43     
44     <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
45     
46   </system.serviceModel>
47   <system.webServer>
48     <modules runAllManagedModulesForAllRequests="true">
49     <!--
50         若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
51         在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
52       注意:在IIS 7.5 中此处的remove和handlers一定要添加已允许客户端可以使用DELETE和PUT功能-->
53        <remove name="WebDAVModule" />
54     </modules>
55      <handlers>
56         <remove name="WebDAV" />
57       </handlers>
58     <directoryBrowse enabled="true"/>
59   </system.webServer>
60 
61 </configuration>

注意:

(1)34-42行的代码的总结点的配置,从中可以看出其中有两个总结点,line36:是配置http调用服务的终结点,line42是提供win form调用的终结点。

(2)system.webServer节点的配置,这将允许你调用wcf服务提供的DELETE方法。如果你发现了调用后的status code为 405,估计这个时候你就需要它了

2.2 接口文件

IHello.cs

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Runtime.Serialization;
 5 using System.ServiceModel;
 6 using System.ServiceModel.Web;
 7 using System.Text;
 8 using System.Data;
 9 using Npgsql;
10 using NpgsqlTypes;
11 
12 namespace SuperWCF
13 {
14     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
15     [DataContract]
16     public class Student
17     {
18         [DataMember(Name = "s_id")]
19         public int s_id { get; set; }
20         [DataMember(Name="sname")]
21         public string sname { get; set; }
22         [DataMember(Name="sex")]
23         public string sex { get; set; }
24         [DataMember(Name="id_card_no")]
25         public string id_card_no { get; set; }
26         [DataMember(Name = "education")]
27         public string education { get; set; }
28         [DataMember(Name = "work_place")]
29         public string work_place { get; set; }
30         [DataMember(Name = "salary")]
31         public int salary { get; set; }
32 
33         [DataMember(Name = "birthplace")]
34         public string birthplace { get; set; }
35         [DataMember(Name = "pwd")]
36         public string pwd { get; set; }
37         [DataMember(Name = "e_mail")]
38         public string e_mail { get; set; }
39 
40     };
41     [ServiceContract]
42     public interface IHello
43     {
44         // TODO: 在此添加您的服务操作
45         [OperationContract]
46         [WebInvoke(
47             Method="PUT",
48             BodyStyle = WebMessageBodyStyle.Bare,
49             ResponseFormat = WebMessageFormat.Json,
50             RequestFormat = WebMessageFormat.Json)]
51         String stuRegister(Student stu);
52 
53         [OperationContract]
54         [WebInvoke(
55             Method="GET",
56             BodyStyle = WebMessageBodyStyle.Bare,
57             ResponseFormat = WebMessageFormat.Json)]
58         DataSet SelStuInfo(string s_id);
59 
60         [OperationContract]
61         [WebInvoke(
62             Method = "POST",
63             BodyStyle = WebMessageBodyStyle.Bare,
64             ResponseFormat = WebMessageFormat.Json,
65             RequestFormat = WebMessageFormat.Json)]
66         int updStudent(Student stu);
67         [OperationContract]
68         [WebInvoke(
69             Method = "DELETE",UriTemplate = "/delStudent?s_id={s_id}",
70             BodyStyle = WebMessageBodyStyle.Bare,
71             RequestFormat = WebMessageFormat.Json)]
72         int delStudent(string s_id);
73 
74     }
75 }

 2.3 服务接口实现

  MyService.svc.cs

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Runtime.Serialization;
  5 using System.ServiceModel;
  6 using System.ServiceModel.Web;
  7 using System.Text;
  8 using System.Data;
  9 using Npgsql;
 10 using NpgsqlTypes;
 11 
 12 namespace SuperWCF
 13 {
 14     // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码、svc 和配置文件中的类名“Service1”。
 15     // 注意: 为了启动 WCF 测试客户端以测试此服务,请在解决方案资源管理器中选择 Service1.svc 或 Service1.svc.cs,然后开始调试。
 16   
 17 
 18     public class MyService : IHello
 19     {
 20         const string constr = "host=localhost;port=1991;uid=postgres;pwd=database password;database=database name;";
 21         public String stuRegister(Student stu)
 22         {
 23             string sql = "insert into "InfoSystem"."Student"(s_id,sname, sex, id_card_no, education, work_place, salary,brithplace,pwd,email) values(@s_id,@sname,@sex,@id_card_no,@education,@work_place,@salary,@birthplace,md5(@pwd),@email)";
 24 
 25             NpgsqlConnection mycon = new NpgsqlConnection(constr);
 26             mycon.Open();
 27             NpgsqlCommand myad = new NpgsqlCommand(sql, mycon);
 28             myad.Parameters.Add("@s_id", NpgsqlDbType.Integer).Value = stu.s_id;
 29             myad.Parameters.Add("@sname", NpgsqlDbType.Char, 20).Value = stu.sname;
 30             myad.Parameters.Add("@sex", NpgsqlDbType.Char, 1).Value = stu.sex;
 31             myad.Parameters.Add("@id_card_no", NpgsqlDbType.Char, 100).Value = stu.id_card_no;
 32             myad.Parameters.Add("@education", NpgsqlDbType.Char, 10).Value = stu.education;
 33             myad.Parameters.Add("@work_place", NpgsqlDbType.Char, 40).Value = stu.work_place;
 34             myad.Parameters.Add("@salary", NpgsqlDbType.Integer).Value = stu.salary;
 35             myad.Parameters.Add("@birthplace", NpgsqlDbType.Char, 50).Value = stu.birthplace;
 36             myad.Parameters.Add("@pwd", NpgsqlDbType.Char, 100).Value = stu.pwd;
 37             myad.Parameters.Add("@email", NpgsqlDbType.Char, 50).Value = stu.e_mail;
 38 
 39             if (myad.ExecuteNonQuery() > 0)
 40             {
 41                 mycon.Close();
 42                 return "true";
 43 
 44             }
 45             else
 46             {
 47                 mycon.Close();
 48                 return "false";
 49             }
 50       
 51         }
 52 
 53 
 54         public DataSet SelStuInfo(String s_id)
 55         {
 56             string sql = "select * from "InfoSystem"."Student" where s_id=@s_id";
 57             DataSet dt = new DataSet();
 58     
 59             NpgsqlConnection mycon = new NpgsqlConnection(constr);
 60 
 61             mycon.Open();
 62             NpgsqlDataAdapter myad = new NpgsqlDataAdapter(sql, mycon);
 63             myad.SelectCommand.Parameters.Add("@s_id", NpgsqlDbType.Integer).Value = s_id;
 64             myad.Fill(dt);
 65             return dt;
 66         }
 67         public int updStudent(Student stu)
 68         {
 69             string sql = "UPDATE "InfoSystem"."Student" SET sname=@sname,sex=@sex,id_card_no=@id_card_no,education=@education,work_place=@work_place,salary=@salary,brithplace=@brithplace,email=@email where s_id=@s_id";
 70 
 71             NpgsqlConnection mycon = new NpgsqlConnection(constr);
 72             mycon.Open();
 73             NpgsqlCommand myad = new NpgsqlCommand(sql, mycon);
 74 
 75             myad.Parameters.Add("@sname", NpgsqlDbType.Char, 20).Value = stu.sname;
 76             myad.Parameters.Add("@sex", NpgsqlDbType.Char, 1).Value = stu.sex;
 77             myad.Parameters.Add("@id_card_no", NpgsqlDbType.Char, 18).Value = stu.id_card_no;
 78             myad.Parameters.Add("@education", NpgsqlDbType.Char, 10).Value = stu.education;
 79             myad.Parameters.Add("@work_place", NpgsqlDbType.Char, 40).Value = stu.work_place;
 80             myad.Parameters.Add("@salary", NpgsqlDbType.Integer).Value = stu.salary;
 81             myad.Parameters.Add("@brithplace", NpgsqlDbType.Char, 50).Value = stu.birthplace;
 82             myad.Parameters.Add("@email", NpgsqlDbType.Char, 50).Value = stu.e_mail;
 83             myad.Parameters.Add("@s_id", NpgsqlDbType.Integer).Value = stu.s_id;
 84 
 85             int res = myad.ExecuteNonQuery();
 86             if (res > 0)
 87             {
 88                 mycon.Close();
 89                 return 1;
 90 
 91             }
 92             else
 93             {
 94                 mycon.Close();
 95                 return 0;
 96             }
 97         }
 98         public int delStudent(string s_id)
 99         {
100             string sql = "delete from "InfoSystem"."Student" where s_id=@s_id";
101 
102             NpgsqlConnection mycon = new NpgsqlConnection(constr);
103             mycon.Open();
104             NpgsqlCommand myad = new NpgsqlCommand(sql, mycon);
105             myad.Parameters.Add("@s_id", NpgsqlDbType.Integer).Value =Convert.ToInt32(s_id);
106             if (myad.ExecuteNonQuery() > 0)
107             {
108                 mycon.Close();
109                 return 1;
110 
111             }
112             else
113             {
114                 mycon.Close();
115                 return 0;
116             }
117 
118         }
119     }
120 }

 有问题欢迎提问!

原文地址:https://www.cnblogs.com/qianzhilan/p/4436107.html