HTTP说明: 1、无连接,一次处理一个请求 2、无状态,对于请求处理没有记忆能力 3、应用层的协议,底层为socket协议,TCP
HTTP请求:
//请求行
GET /test HTTP/ (CRLF)
//消息报头
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.8,en;q=0.6 Connection:keep-alive Host:127.0.0.1:8080 Upgrade-Insecure-Requests:1 User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
//请求正文
user=jeffrey&pwd=1234
HTTP响应:
//状态行
HTTP/1.1 200 OK (CRLF)
//消息报头
Cache-Control:no-cache Content-Type:application/json;charset=UTF-8 Date:Tue, 11 Jul 2017 06:07:43 GMT Expires:Thu, 01 Jan 1970 00:00:00 GMT Pragma:no-cache Server:Apache-Coyote/1.1 Transfer-Encoding:chunked
//响应正文
{"RetMsg":"请求报文为空","RetCode":"9998"}
关于请求参数乱码问题:
1、设置相关字符集,包括服务端tomcat字符集
请求参数特殊字符被转换:
1、URLHttpConnection的GET和POST都会有这个问题
2、HttpClient的GET有这个问题,POST没有这个问题
3、在请求或者接收报文是,对特殊字符做相应的替换操作。例如,在报文值中要传递+,可先将+转换为+,再传输
项目结构:
package com.utils; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.Map; public class HttpUrl { private static final String CHARSET = "utf-8"; private static final int TIMEOUT = 10*1000; /** * HttpUrlConnection * jdk自带 * * 注意: * 1、字符集设置 * 2、请求报文值有+等特殊字符,服务端获取时转换成了空格,如何处理? */ /** * get请求,请求参数放在url后面 * @param urlPath * @return */ public static String doGet(String urlPath){ try { System.out.println("请求地址:"+urlPath); URL url = new URL(urlPath); HttpURLConnection connect = (HttpURLConnection) url.openConnection(); connect.setInstanceFollowRedirects(false); // 禁止自动重定向跳转,302重定向响应码 connect.setConnectTimeout(TIMEOUT); // 连接超时时间,毫秒,默认不会超时 connect.setReadTimeout(TIMEOUT); // 传递数据超时时间,毫秒,默认不会超时 // 获取响应码和响应信息 int responseCode = connect.getResponseCode(); String responseMsg = connect.getResponseMessage(); System.out.println("【状态码:"+responseCode+",状态信息:"+responseMsg+"】"); if(responseCode!=HttpURLConnection.HTTP_OK){ return null; } // 获取响应消息体 InputStream is = connect.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(is, CHARSET)); StringBuffer sb = new StringBuffer(); String readLine = null; while((readLine=bufferedReader.readLine())!=null){ sb.append(readLine); } is.close(); bufferedReader.close(); connect.disconnect(); System.out.println("返回报文:"+sb.toString()); return sb.toString(); } catch (MalformedURLException e) { e.printStackTrace(); System.out.println("创建链接失败"); return null; } catch (IOException e) { e.printStackTrace(); System.out.println("打开链接失败"); return null; } } /** * post请求,参数以流的形式写出,返回报文以流的形式读取 * @param urlPath * @param params * @return */ public static String doPost(String urlPath, Map<String, Object> params){ try { System.out.println("请求地址:"+urlPath); URL url = new URL(urlPath); HttpURLConnection connect = (HttpURLConnection) url.openConnection(); // 生成一个连接对象 connect.setDoInput(true); // 允许输入,默认true connect.setDoOutput(true); // 允许输出,默认false。正好说明了post请求需要用流的形式写出参数 connect.setRequestMethod("POST"); // 设置请求类型,默认为get connect.setUseCaches(false); // 禁用缓存 connect.setInstanceFollowRedirects(false); // 禁止自动重定向跳转,302重定向响应码 connect.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); // 报文类型,MIME,已表单键值对格式提交 connect.setConnectTimeout(TIMEOUT); // 连接超时时间,毫秒,默认不会超时 connect.setReadTimeout(TIMEOUT); // 传递数据超时时间,毫秒,默认不会超时 connect.connect(); // 打开连接 DataOutputStream out = new DataOutputStream(connect.getOutputStream()); StringBuffer sb = new StringBuffer(); if(params!=null){ for(String key : params.keySet()){ sb.append(key + "=" + params.get(key) +"&"); } } String content = sb.length()==0?"":sb.substring(0, sb.length()-1); System.out.println("请求报文:"+content); out.write(content.getBytes(CHARSET)); // 注意此处的字符集设置 out.flush(); out.close(); // 获取响应码和响应信息 int responseCode = connect.getResponseCode(); String responseMsg = connect.getResponseMessage(); System.out.println("【状态码:"+responseCode+",状态信息:"+responseMsg+"】"); if(responseCode!=HttpURLConnection.HTTP_OK){ return null; } // 获取响应消息体 InputStream in = connect.getInputStream(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, CHARSET)); StringBuffer sb_1 = new StringBuffer(); String readLine = null; while((readLine=bufferedReader.readLine())!=null){ sb_1.append(readLine); } in.close(); bufferedReader.close(); connect.disconnect(); System.out.println("返回报文:"+sb_1.toString()); return sb_1.toString(); } catch (MalformedURLException e) { e.printStackTrace(); System.out.println("创建链接失败"); return null; } catch (IOException e) { e.printStackTrace(); System.out.println("打开链接失败"); return null; } } public static void main(String[] args) { long timeBegin = System.currentTimeMillis(); System.out.println(timeBegin); Map<String, Object> params = new HashMap<String, Object>(); params.put("name", "周星星"); params.put("wife", "zixia"); HttpUrl.doPost("http://127.0.0.1:8080/olt/org/test", params); // HttpUrl.doGet("http://127.0.0.1:8080/olt/org/test?a=1&b=周星星"); long timeEnd = System.currentTimeMillis(); System.out.println(timeEnd); System.out.println("耗时:"+(timeEnd-timeBegin)); } } package com.test; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; public class HttpClientTest { private static final int TIMEOUT = 10*1000; // 60s private static final String CHARSET = "utf-8"; /** * get请求,相关配置通过RequestConfig配置 * @param urlPath * @return */ public static String doGet(String urlPath){ System.out.println("请求地址:"+urlPath); HttpGet httpGet = new HttpGet(urlPath); // HttpClient hc = new DefaultHttpClient(); // 过时了 CloseableHttpClient httpClient = HttpClients.createDefault(); try { RequestConfig config = RequestConfig.custom() .setConnectTimeout(TIMEOUT) .setSocketTimeout(TIMEOUT) // read time out .build(); httpGet.setConfig(config); // 相关配置 CloseableHttpResponse httpResponse = httpClient.execute(httpGet); int responseCode = httpResponse.getStatusLine().getStatusCode(); System.out.println("【状态码:"+responseCode+"】"); HttpEntity httpEntity = httpResponse.getEntity(); InputStream in = httpEntity.getContent(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in, CHARSET)); StringBuffer sb = new StringBuffer(); String readLine = null; while((readLine=bufferedReader.readLine())!=null){ sb.append(readLine); } in.close(); bufferedReader.close(); httpClient.close(); System.out.println("返回报文:"+sb.toString()); return sb.toString(); } catch (IOException e) { e.printStackTrace(); System.out.println("创建连接异常"); return null; } } /** * POST请求 * @param urlPath * @param params * @return */ public static String doPost(String urlPath, Map<String, Object> params){ System.out.println("请求地址:"+urlPath); HttpPost httpPost = new HttpPost(urlPath); CloseableHttpClient httpClient = HttpClients.createDefault(); // 请求参数 List<NameValuePair> urlParams = new ArrayList<NameValuePair>(); if(params!=null){ for(String key : params.keySet()){ urlParams.add(new BasicNameValuePair(key, params.get(key)+"")); } } try { HttpEntity httpEntity = new UrlEncodedFormEntity(urlParams, CHARSET); // 设置字符集 httpPost.setEntity(httpEntity); RequestConfig config = RequestConfig.custom() .setConnectTimeout(TIMEOUT) .setSocketTimeout(TIMEOUT) // read time out .build(); httpPost.setConfig(config); // 请求配置 CloseableHttpResponse httpResponse = httpClient.execute(httpPost); int responseCode = httpResponse.getStatusLine().getStatusCode(); System.out.println("【状态码:"+responseCode+"】"); InputStream in = httpEntity.getContent(); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); StringBuffer sb = new StringBuffer(); String readLine = null; while((readLine=bufferedReader.readLine())!=null){ sb.append(readLine); } System.out.println("返回报文:"+sb.toString()); return sb.toString(); } catch (Exception e) { e.printStackTrace(); System.out.println("请求异常"); return null; } } public static void main(String[] args) { long timeBegin = System.currentTimeMillis(); System.out.println(timeBegin); Map<String, Object> params = new HashMap<String, Object>(); params.put("name", "周星星"); params.put("wife", "zixia"); HttpClientTest.doPost("http://127.0.0.1:8080/olt/org/test", params); // HttpClientTest.doGet("http://127.0.0.1:8080/olt/org/test?name=周星星&wift=zixia"); long timeEnd = System.currentTimeMillis(); System.out.println(timeEnd); System.out.println("耗时:"+(timeEnd-timeBegin)); } }