一个java web客户端,适合从服务器到服务器的通信

在实际应用中,web应用一般是基于b/s,如果是基于c/s呢?比如从web服务器到另一个web服务器之间的通信,在b/s模式下,浏览器帮我们处理了通信细节,比如发送和接收请求,而从服务器到服务器通信,自己得构建一个客户端,当然,套接字是可行的选择,不过要写出满足http协议的套接字,需要做很多事情。利用jdk提供的HttpURLConnection,我们做一个简单的封装,就可以实现自己的HttpClient,而无需使用apache HttpClient那个庞然大物了。不废话上代码。其中要使用到的json包,在本人共享云盘中可以下载。java代码分享:http://pan.baidu.com/s/1hszGxV2

HttpClient.java

  1 /**
  2  * 
  3  */
  4 package com.jjh.common;
  5 
  6 import java.io.ByteArrayInputStream;
  7 import java.io.IOException;
  8 import java.io.InputStream;
  9 import java.io.OutputStream;
 10 import java.lang.reflect.ParameterizedType;
 11 import java.lang.reflect.Type;
 12 import java.net.HttpURLConnection;
 13 import java.net.URL;
 14 import java.nio.charset.Charset;
 15 import java.nio.charset.StandardCharsets;
 16 import java.util.Objects;
 17 
 18 import javax.activation.MimeType;
 19 import javax.activation.MimeTypeParseException;
 20 import javax.xml.bind.JAXB;
 21 
 22 import org.json.JSONArray;
 23 import org.json.JSONException;
 24 import org.json.JSONObject;
 25 
 26 /**
 27  * @author Administrator
 28  *
 29  */
 30 public abstract class HttpClient<S, R> {
 31     /**
 32      * @author Administrator
 33      *
 34      */
 35     public static enum Response {
 36         SUCCESS(200, "OK"), PAGE_NOT_FOUND(404, "页面没找到"), ERROR(500, "服务器内部错误");
 37 
 38         private final int responseCode;
 39         private final String responseMessage;
 40 
 41         /**
 42          * @param responseCode
 43          * @param responseMessage
 44          */
 45         private Response(int responseCode, String responseMessage) {
 46             this.responseCode = responseCode;
 47             this.responseMessage = responseMessage;
 48         }
 49 
 50         /**
 51          * @return the responseCode
 52          */
 53         public int getResponseCode() {
 54             return responseCode;
 55         }
 56 
 57         /**
 58          * @return the responseMessage
 59          */
 60         public String getResponseMessage() {
 61             return responseMessage;
 62         }
 63 
 64         public static Response getResponse(int responseCode) {
 65             switch (responseCode) {
 66             case 200:
 67                 return SUCCESS;
 68             case 404:
 69                 return PAGE_NOT_FOUND;
 70             case 500:
 71                 return ERROR;
 72             }
 73             return null;
 74         }
 75 
 76     }
 77 
 78     private HttpURLConnection conn;
 79     private MimeType mimeType;
 80     private Class<S>  SType;
 81     private Class<R>  RType;
 82 
 83     /**
 84      * @param mimeType
 85      */
 86     @SuppressWarnings("unchecked")
 87     public HttpClient(MimeType mimeType) {
 88         super();
 89         this.mimeType = mimeType;
 90         Type type=getClass().getGenericSuperclass();
 91         ParameterizedType pt = (ParameterizedType) type;
 92         SType=(Class<S>)pt.getActualTypeArguments()[0];
 93         RType=(Class<R>)pt.getActualTypeArguments()[1];
 94     }
 95 
 96     /**
 97      * @throws MimeTypeParseException 
 98      * 
 99      */
100     public HttpClient() throws MimeTypeParseException{
101         // TODO Auto-generated constructor stub
102         this(new MimeType("application/x-www-form-urlencoded;charset=utf-8"));        
103     }
104     
105     protected S onReady() {
106         return null;
107     }
108 
109     abstract protected void onComplete(R response);
110 
111     protected void onError(Response response) {
112         System.err.println(response.getResponseCode() + "," + response.getResponseMessage());
113     }
114 
115     public Runnable get(String uri) throws IOException {
116         S data=onReady();
117         // 先发送数据
118         if (Objects.nonNull(data)) {
119             if(SType!=String.class)
120                 throw new IOException("'"+data+"'必须是字符串");
121             int index=uri.lastIndexOf("?");
122             //后面没有?
123             if(index==-1)
124                 uri+="?"+data;
125             //后面有?
126             else if(index==uri.length()-1)
127                 uri+=data;
128             //后面有查询字符串,类似于:?name=jjh
129             else
130                 uri+="&"+data;
131         }
132         conn = (HttpURLConnection) new URL(uri).openConnection();
133         conn.setUseCaches(false);
134         conn.setConnectTimeout(3000);
135         conn.setReadTimeout(3000);
136         conn.setRequestProperty("Content-Type", mimeType.toString());
137 
138         conn.setRequestMethod("GET");
139         conn.setDoInput(true);
140         conn.setDoOutput(false);
141         conn.connect();
142 
143         // 可以处理连接失败的信息(忽略)
144         // 处理发送和接收
145         // 返回一个Runnable
146         return () -> {
147             try {
148                 // 后处理响应
149                 read();
150             } catch (Exception e) {
151                 e.printStackTrace();
152             }
153         };
154     }
155     
156     public Runnable post(String uri) throws IOException {
157         conn = (HttpURLConnection) new URL(uri).openConnection();
158         conn.setUseCaches(false);
159         conn.setConnectTimeout(3000);
160         conn.setReadTimeout(3000);
161         conn.setRequestProperty("Content-Type", mimeType.toString());
162 
163         conn.setRequestMethod("POST");
164         conn.setDoInput(true);
165         conn.setDoOutput(true);
166         conn.connect();
167 
168         // 可以处理连接失败的信息(忽略)
169         // 处理发送和接收
170         // 返回一个Runnable
171         return () -> {
172             try {
173                 // 先发送数据
174                 write();
175                 // 后处理响应
176                 read();
177             } catch (Exception e) {
178                 e.printStackTrace();
179             }
180         };
181     }
182 
183     private void read() throws IOException, JSONException {
184         // TODO Auto-generated method stub
185         int responseCode = conn.getResponseCode();
186         Response response = Response.getResponse(responseCode);
187         switch (response) {
188         case SUCCESS:
189             onComplete(success());
190             break;
191         default:
192             onError(response);
193         }
194     }
195 
196     @SuppressWarnings("unchecked")
197     private R success() throws IOException, JSONException {
198         // TODO Auto-generated method stub
199         InputStream in = conn.getInputStream();
200         R result = null;
201         byte[] ret = Files.read(in);
202         in.close();
203         if (RType == JSONObject.class) {
204             result = (R) new JSONObject(new String(ret, Charset.forName("UTF-8")));
205         } else if (RType == JSONArray.class) {
206             result = (R) new JSONArray(new String(ret, Charset.forName("UTF-8")));
207         } else if (RType == String.class) {
208             result = (R) new String(ret, Charset.forName("UTF-8"));
209         } else if (RType == byte[].class) {
210             result = (R)ret;
211         } else {
212             result = JAXB.unmarshal(new ByteArrayInputStream(ret), RType);
213         }
214         return result;
215     }
216 
217     private void write() throws IOException {
218         // TODO Auto-generated method stub
219         S data = onReady();
220         OutputStream out = conn.getOutputStream();
221         if (SType == JSONObject.class || SType == JSONArray.class) {
222             out.write(data.toString().getBytes(StandardCharsets.UTF_8));
223         } else if (SType == String.class) {
224             String s = (String) data;
225             out.write(s.getBytes(StandardCharsets.UTF_8));
226         } else if (SType == byte[].class) {
227             byte[] s = (byte[]) data;
228             out.write(s);
229         } else {
230             JAXB.marshal(data, out);
231         }
232         out.flush();
233         out.close();
234     }
235     
236     public static void main(String[] args) throws IOException, MimeTypeParseException {
237         Runnable r=new  HttpClient<String, String>(){
238 
239             @Override
240             protected void onComplete(String response) {
241                 // TODO Auto-generated method stub
242                 System.out.println(response);
243             }
244 
245             /* (non-Javadoc)
246              * @see com.jjh.common.HttpClient#onReady()
247              
248             @Override
249             protected String onReady() {
250                 // TODO Auto-generated method stub
251                 return "username=张三&password=123456";
252             }*/
253             
254             
255             
256         }.get("https://www.baidu.com/");
257         r.run();
258     }
259 
260 }

main方法中是测试,代码注释很少,想了解的加我qq:412383550

 

posted @ 2017-04-14 11:03  江金汉  阅读(423)  评论(0编辑  收藏  举报