HttpURLConnection 中Cookie 使用
方式一:
如果想通过 HttpURLConnection 访问网站,网站返回cookie信息,下次再通过HttpURLConnection访问时,把网站返回 cookie信息再返回给该网站。可以使用下面代码。
CookieManager manager = new CookieManager(); CookieHandler.setDefault(manager);
通过这两行代码就可以把网站返回的cookie信息存储起来,下次访问网站的时候,自动帮你把cookie信息带上。
CookieManager还可以设置CookiePolicy。设置如下
CookieManager manager = new CookieManager(); //设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
CookiePolicy 策略机制解析
public interface CookiePolicy { public static final CookiePolicy ACCEPT_ALL = new CookiePolicy(){ public boolean shouldAccept(URI uri, HttpCookie cookie) { return true; } }; public static final CookiePolicy ACCEPT_NONE = new CookiePolicy(){ public boolean shouldAccept(URI uri, HttpCookie cookie) { return false; } }; public static final CookiePolicy ACCEPT_ORIGINAL_SERVER = new CookiePolicy(){ public boolean shouldAccept(URI uri, HttpCookie cookie) { if (uri == null || cookie == null) return false; return HttpCookie.domainMatches(cookie.getDomain(), uri.getHost()); } }; public boolean shouldAccept(URI uri, HttpCookie cookie); }
从源码中可以看出CookiePolicy 默认提供了3中策略实现机制
- CookiePolicy.ACCEPT_ALL;
从源码中可以发现直接return true。就是接受所有的cookie。 - CookiePolicy.ACCEPT_NONE;
从源码中可以发现直接return false。就是拒绝所有的cookie。 - CookiePolicy.ACCEPT_ORIGINAL_SERVER;
内部调用了HttpCookie.domainMatches的方法。该方法是判断cookie的域和URL的域是否一样,如果一样就return true。只接收域名相同的Cookie
Cookie实现机制
这样每次在调用HttpURLConnection访问网站的时候,通过CookieHandler.getDefault()方法获取CookieManager实例(静态的方法,全局都可用)。
从解析http的响应头中的cookie调用CookieHandler中的put方法存放到CookieStore中。
再次访问网站的时候调用CookieHandler中的get方法获取该uri响应的cookie,并提交到该站点中。
这样开发人员就不需要干预cookie信息,则每次访问网站会自动携带cookie。
代码示例
本例子中使用到了CookieHandler、CookieManager 、CookieStore、 HttpCookie。
public class CookieManagerDemo { //打印cookie信息 public static void printCookie(CookieStore cookieStore){ List<HttpCookie> listCookie = cookieStore.getCookies(); listCookie.forEach(httpCookie -> { System.out.println("--------------------------------------"); System.out.println("class : "+httpCookie.getClass()); System.out.println("comment : "+httpCookie.getComment()); System.out.println("commentURL : "+httpCookie.getCommentURL()); System.out.println("discard : "+httpCookie.getDiscard()); System.out.println("domain : "+httpCookie.getDomain()); System.out.println("maxAge : "+httpCookie.getMaxAge()); System.out.println("name : "+httpCookie.getName()); System.out.println("path : "+httpCookie.getPath()); System.out.println("portlist : "+httpCookie.getPortlist()); System.out.println("secure : "+httpCookie.getSecure()); System.out.println("value : "+httpCookie.getValue()); System.out.println("version : "+httpCookie.getVersion()); System.out.println("httpCookie : "+httpCookie); }); } public static void requestURL() throws Exception{ URL url = new URL("http://192.168.3.249:9000/webDemo/index.jsp"); HttpURLConnection conn = (HttpURLConnection)url.openConnection(); String basic = Base64.getEncoder().encodeToString("infcn:123456".getBytes()); conn.setRequestProperty("Proxy-authorization", "Basic " + basic); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line = null; while((line=br.readLine())!=null){ System.out.println(line); } br.close(); } public static void main(String[] args) throws Exception { CookieManager manager = new CookieManager(); //设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); CookieHandler.setDefault(manager); printCookie(manager.getCookieStore()); //第一次请求 requestURL(); printCookie(manager.getCookieStore()); //第二次请求 requestURL(); } }
方式一:
获取Cookies,多个cookie是以;分隔
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.CookieHandler; import java.net.CookieManager; import java.net.CookiePolicy; import java.net.CookieStore; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.Proxy; import java.net.URL; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class HttpUtil { public static final String KEY_HEADER_COOKIE="Set-Cookie"; public static final String KEY_REQUEST_COOKIE = "Cookie"; private HttpUtil() { } public static CookieStore setCookieManager(){ CookieManager manager = new CookieManager(); //设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); CookieHandler.setDefault(manager); CookieStore cookieStore = manager.getCookieStore(); return cookieStore; } public static ResponseResult doGet(String path, Map<String, String> headers, boolean redirect,Proxy proxy) { HttpURLConnection connection = null; ResponseResult result = new ResponseResult(); try { // 1. 得到访问地址的URL URL url = new URL(new String(path.getBytes(), "UTF-8")); // 2. 得到网络访问对象java.net.HttpURLConnection if (proxy != null) { connection = (HttpURLConnection) url.openConnection(proxy); } else { connection = (HttpURLConnection) url.openConnection(); } /* 3. 设置请求参数(过期时间,输入、输出流、访问方式),以流的形式进行连接 */ // 设置是否向HttpURLConnection输出 connection.setDoOutput(false); // 设置是否从httpUrlConnection读入 connection.setDoInput(true); // 设置请求方式 connection.setRequestMethod("GET"); // 设置是否使用缓存 connection.setUseCaches(true); // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向 connection.setInstanceFollowRedirects(redirect); // 设置超时时间 connection.setConnectTimeout(3000); if (headers != null) { Set<Entry<String, String>> entrySet = headers.entrySet(); for (Entry<String, String> entry : entrySet) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } } // 连接 connection.connect(); int responseCode = connection.getResponseCode(); result.setResponseCode(responseCode); String responseMessage = connection.getResponseMessage(); result.setResponseMessage(responseMessage); List<String> cookies = connection.getHeaderFields().get(KEY_HEADER_COOKIE); if (cookies != null&&cookies.size()>0) { StringBuffer sb = new StringBuffer(); for (String string : cookies) { sb.append(string).append(";"); } result.setCookies(sb.toString()); } InputStream inputStream = connection.getInputStream(); StringBuffer sb = new StringBuffer(); // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String getLine; while ((getLine = in.readLine()) != null) { sb.append(getLine); } result.setResponseBody(sb.toString()); inputStream.close(); in.close(); connection.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } public static ResponseResult doPost(String path, Map<String, String> headers, boolean redirect,Proxy proxy,String param){ ResponseResult result = new ResponseResult(); HttpURLConnection connection = null; try { // 1. 得到访问地址的URL URL url = new URL(new String(path.getBytes(), "UTF-8")); // 2. 得到网络访问对象java.net.HttpURLConnection if (proxy != null) { connection = (HttpURLConnection) url.openConnection(proxy); } else { connection = (HttpURLConnection) url.openConnection(); } /* 3. 设置请求参数等 */ // 请求方式 connection.setRequestMethod("POST"); // 超时时间 connection.setConnectTimeout(3000); // 设置是否输出 connection.setDoOutput(true); // 设置是否读入 connection.setDoInput(true); // 设置是否使用缓存 connection.setUseCaches(false); // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向 connection.setInstanceFollowRedirects(redirect); // 设置使用标准编码格式编码参数的名-值对 connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); if (headers != null) { Set<Entry<String, String>> entrySet = headers.entrySet(); for (Entry<String, String> entry : entrySet) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } } // 连接 connection.connect(); /* 4. 处理输入输出 */ // 写入参数到请求中 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8")); writer.write(new String(param.getBytes(), "UTF-8")); writer.flush(); writer.close(); int responseCode = connection.getResponseCode(); result.setResponseCode(responseCode); String responseMessage = connection.getResponseMessage(); result.setResponseMessage(responseMessage); List<String> cookies = connection.getHeaderFields().get(KEY_HEADER_COOKIE); if (cookies != null&&cookies.size()>0) { StringBuffer sb = new StringBuffer(); for (String string : cookies) { sb.append(string).append(";"); } result.setCookies(sb.toString()); } InputStream inputStream = connection.getInputStream(); StringBuffer sb = new StringBuffer(); // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String getLine; while ((getLine = in.readLine()) != null) { sb.append(getLine); } result.setResponseBody(sb.toString()); inputStream.close(); in.close(); connection.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } public static ResponseResult doPut(String path, Map<String, String> headers, boolean redirect,Proxy proxy,String param){ ResponseResult result = new ResponseResult(); HttpURLConnection connection = null; try { // 1. 得到访问地址的URL URL url = new URL(new String(path.getBytes(), "UTF-8")); // 2. 得到网络访问对象java.net.HttpURLConnection if (proxy != null) { connection = (HttpURLConnection) url.openConnection(proxy); } else { connection = (HttpURLConnection) url.openConnection(); } /* 3. 设置请求参数等 */ // 请求方式 connection.setRequestMethod("PUT"); // 超时时间 connection.setConnectTimeout(3000); // 设置是否输出 connection.setDoOutput(true); // 设置是否读入 connection.setDoInput(true); // 设置是否使用缓存 connection.setUseCaches(false); // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向 connection.setInstanceFollowRedirects(redirect); // 设置使用标准编码格式编码参数的名-值对 connection.setRequestProperty("Content-Type","application/x-www-form-urlencoded"); if (headers != null) { Set<Entry<String, String>> entrySet = headers.entrySet(); for (Entry<String, String> entry : entrySet) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } } // 连接 connection.connect(); /* 4. 处理输入输出 */ // 写入参数到请求中 BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(), "UTF-8")); writer.write(new String(param.getBytes(), "UTF-8")); writer.flush(); writer.close(); int responseCode = connection.getResponseCode(); result.setResponseCode(responseCode); String responseMessage = connection.getResponseMessage(); result.setResponseMessage(responseMessage); List<String> cookies = connection.getHeaderFields().get(KEY_HEADER_COOKIE); if (cookies != null&&cookies.size()>0) { StringBuffer sb = new StringBuffer(); for (String string : cookies) { sb.append(string).append(";"); } result.setCookies(sb.toString()); } InputStream inputStream = connection.getInputStream(); StringBuffer sb = new StringBuffer(); // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String getLine; while ((getLine = in.readLine()) != null) { sb.append(getLine); } result.setResponseBody(sb.toString()); inputStream.close(); in.close(); connection.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (ProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } public static ResponseResult doDelete(String path, Map<String, String> headers, boolean redirect,Proxy proxy) { HttpURLConnection connection = null; ResponseResult result = new ResponseResult(); try { // 1. 得到访问地址的URL URL url = new URL(new String(path.getBytes(), "UTF-8")); // 2. 得到网络访问对象java.net.HttpURLConnection if (proxy != null) { connection = (HttpURLConnection) url.openConnection(proxy); } else { connection = (HttpURLConnection) url.openConnection(); } /* 3. 设置请求参数(过期时间,输入、输出流、访问方式),以流的形式进行连接 */ // 设置是否向HttpURLConnection输出 connection.setDoOutput(false); // 设置是否从httpUrlConnection读入 connection.setDoInput(true); // 设置请求方式 connection.setRequestMethod("DELETE"); // 设置是否使用缓存 connection.setUseCaches(true); // 设置此 HttpURLConnection 实例是否应该自动执行 HTTP 重定向 connection.setInstanceFollowRedirects(redirect); // 设置超时时间 connection.setConnectTimeout(3000); if (headers != null) { Set<Entry<String, String>> entrySet = headers.entrySet(); for (Entry<String, String> entry : entrySet) { connection.setRequestProperty(entry.getKey(), entry.getValue()); } } // 连接 connection.connect(); int responseCode = connection.getResponseCode(); result.setResponseCode(responseCode); String responseMessage = connection.getResponseMessage(); result.setResponseMessage(responseMessage); List<String> cookies = connection.getHeaderFields().get(KEY_HEADER_COOKIE); if (cookies != null&&cookies.size()>0) { StringBuffer sb = new StringBuffer(); for (String string : cookies) { sb.append(string).append(";"); } result.setCookies(sb.toString()); } InputStream inputStream = connection.getInputStream(); StringBuffer sb = new StringBuffer(); // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8")); String getLine; while ((getLine = in.readLine()) != null) { sb.append(getLine); } result.setResponseBody(sb.toString()); inputStream.close(); in.close(); connection.disconnect(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return result; } } class ResponseResult{ private Integer responseCode; private String responseMessage; private String responseBody; private String cookies; public Integer getResponseCode() { return responseCode; } public void setResponseCode(Integer responseCode) { this.responseCode = responseCode; } public String getResponseMessage() { return responseMessage; } public void setResponseMessage(String responseMessage) { this.responseMessage = responseMessage; } public String getResponseBody() { return responseBody; } public void setResponseBody(String responseBody) { this.responseBody = responseBody; } public String getCookies() { return cookies; } public void setCookies(String cookies) { this.cookies = cookies; } }