java网络编程-HTTP和URLConnection

来源:互联网 发布:淘宝店铺市场分析 编辑:程序博客网 时间:2024/05/30 22:45

  • HTTP和URLConnection
  • HTTP
    • CookieManager
  • URLConnection
    • 读取首部
    • 获取任意首部字段
  • 缓存
  • java的web缓存
    • 配置连接
    • 配置请求的首部
    • 向服务器写数据
  • URLConnection的安全性考虑
  • 猜测MIME类型
  • HttpURLConnection

HTTP和URLConnection

标签(空格分隔): java网络编程

HTTP

get请求是一个空行结束,也就是\r\n\r\n

CookieManager

启用cookie:

CookieManager manager = new CookieManager();CookieHandler.setDefault(manager);

接受策略:

CookiePolicy.ACCEPT_ALL接受所有cookieCookiePolicy.ACCEPT_NONE不接受任何cookieCookiePolicy.ACCEPT_ORIGINAL_SERVER只接受第一坊cookie

使用:

manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER)

自定义:实现CookiePolicy接口:

public boolean  shouldAccept(URI uri, HttpCookie cookie)

例如:

 public class NoGovernmentCookies implements CookiePolicy{     @overide     public boolean shouldAccept(URI uri, HttpCookie cookie){         if (uri.getAuthority().toLowerCase().endsWith(".gov")             || cooke.getDomain().toLowerCase().endsWith(".gov")){             return false;//阻止             }         }         return true;     } }

URLConnection

是一个抽象类,表示指向URL指定资源的活动连接
使用该类的一般步骤(不一定全部执行):

1. 构造一个URL对象2. 调用openConnection创建URLConnection对象3. 配置URLConnection3. 读取首部字段5. 获取输入流并读取数据6. 获取输出流并写入数据7. 关闭连接

第一次构造URLConnection时,是没有socket连接这两个主机,connect()方法在本地和远程主机之间建立一个连接。同时对于getInputStream(),getContent(),getHeaderField()和其他要求打开连接的方法,如果未打开,会自动调用connect()
案例:用URLConnection下载一个WEB页面:

public class SourceViewer2 {public static void main(String[] args) {    if (args.length > 0) {        try {            URL u = new URL(args[0]);            URLConnection uc = u.openConnection();            try (InputStream raw = uc.getInputStream()) {                InputStream buffer = new BufferedInputStream(raw);                Reader reader = new InputStreamReader(buffer);                int c;                while ((c = reader.read()) != -1) {                    System.out.println((char) c);                }            }        } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}

}

URLConnection和URL的区别

URLConnection 提供了对HTTP首部的访问可以配置服务器的请求参数可以向服务器写入数据

读取首部

public String getContentType()

返回响应主体的MIME类型(可能包括编码类型,因此可以按指定的编码方式解码)

public int getContentLength()

内容有多少字节,如果没有该首部就返回-1,如果字节数超出int范围应该使用:

public long getContentLengthLong();//java7

示例:下载二进制文件

public class BinarySaver {public static void main(String[] args) {    for (int i = 0; i < args.length; i++) {        try {            URL root = new URL(args[i]);            saveBinaryFile(root);        } catch (MalformedURLException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }    }}private static void saveBinaryFile(URL u) throws IOException {    URLConnection uc = u.openConnection();    String contentType = uc.getContentType();    int contentLength = uc.getContentLength();    if (contentType.startsWith("text/") || contentLength == -1) {        throw new IOException("This is not a binary file.");    }    try (InputStream rwa = uc.getInputStream()) {        InputStream in = new BufferedInputStream(rwa);        byte[] data = new byte[contentLength];        int offset = 0;        while (offset < contentLength) {            int bytesRead = in.read(data, offset, data.length - offset);            if (bytesRead ==-1) break;            offset += bytesRead;        }        if (offset != contentLength) {            throw new IOException("not read all");        }        String filename = u.getFile();        filename = filename.substring(filename.lastIndexOf("/") + 1);        try (FileOutputStream fout = new FileOutputStream(filename)) {            fout.write(data);            fout.flush();        }    }}

获取内容编码方式(字节如何编码成字节)(不同于字符编码):

public String getContentEncoding()

没有编码 返回null

获取发送时间:

public long getDate();//没有就返回0Date document = new Date(uc.getDate());

过期日期:

public long getExpiration()

最后修改日期:

public long getLastModified

获取任意首部字段

public String getHeaderField(String name);//不区分大小写public String getHeaderFieldKey(int n);//返回第n个首部字段public String getHeaderField(int n);//返回第n个字段的值public long getHeaderFieldDate(String name, long default);//将值转换为longpublic long getHeaderFieldInt(String name, int default);//转化为int

缓存

一般情况下使用get通过HTTP访问的页面可以缓存,也应当缓存,相关的HTTP首部:

Expires首部:指定缓存的时间Cache-control首部(和上面同出现,会覆盖它):    max-aget=[seconds]:    s-maxage=[seconds]: 到过期之前的秒数    public:可以缓存一个经过认证的响应    private: 仅单个用户缓存可以保存响应    no-cache: 客户端每次都要用Etag或Last-modified首部重新验证响应的状态    no-store:不管怎么样都不缓存Last_modified:最后一次修改的日期Etag:验证本地缓存的标志,标志不同时,才执行get请求

java的web缓存

默认情况下java并不完成缓存,如果要缓存需要:

ResponseCache(处理后面两个的类),CacheRequest,CacheResponse

一旦安装了缓存,只要系统尝试加载一个URL,它首先会在这个缓存中找。
ResponseCache的两个方法:

public abstract CacheResponse get(...);//获取缓存数据和首部(其中会用到CacheRequest)public abstract CacheRequest put(...);//获取缓存,通过一个流

java要求一次只能有一个URL缓存。要安装或者改变缓存,需要使用:

public static ResponseCace.setDefault()public static void setDefault(ResponseCache responseCache)

配置连接:

URLConnection主要有7个保护的实例字段,定了发送的请求

URL url;boolean DoInput = true;boolean doOutput = false;allowUserInteraction = defaultAllowUserInteraction;boolean useCaches = defaultUserCaches;long ifModifiedSince = 0;boolean connected = false;

这些值都是通过get和set方法获取和改变(后两个没有get和set,更改在连接之前)

配置请求的首部

URLConnection会有一些默认的首部,添加首部:

public void setRequestProperty(String name, String value);

增加属性:

public void addRequestProperty(String name, String value);

获取属性:

public String getRequestProperty(String name);public Map<String,List<String>> getRequestProperties();

向服务器写数据

URLConnection默认不输出,因此请求输出之前必须调用setDoOutput(true),这时请求方法变成POST。GET仅限于安全的操作,如搜索请求或页面导航,不能用于创建或修改资源的不安全操作。输出通过流输出:

public OutputStream getOutputStream();

案例:提交表单数据
编码转换的类:

public class QueryString {    private StringBuilder query = new StringBuilder();   public QueryString() {   }   public synchronized void add(String name, String value) {       query.append("&");       encode(name, value);   }   private void encode(String name, String value) {       try {           query.append(URLEncoder.encode(name, "UTF-8"));           query.append("=");           query.append(URLEncoder.encode(value, "UTF-8"));       } catch (UnsupportedEncodingException e) {           e.printStackTrace();       }   }   public synchronized String getQuery() {       return query.toString();   }   @Override   public String toString() {       return getQuery();   }}

主类:

public class FormPoster {    private URL url;    private QueryString query = new QueryString();    public FormPoster(URL url) {        if (!url.getProtocol().toLowerCase().startsWith("http")) {            throw new IllegalArgumentException("not http URLs");        }        this.url = url;    }    public void add(String name, String value) {        query.add(name, value);    }    public URL getURL() {        return this.url;    }    public InputStream post() throws IOException {        URLConnection uc = url.openConnection();        uc.setDoOutput(true);        try (OutputStreamWriter out = new OutputStreamWriter(uc.getOutputStream(),"UTF-8")) {            out.write(query.toString());            out.write("\r\n");            out.flush();        }        return uc.getInputStream();    }    public static void main(String[] args) {        URL url;        if (args.length > 0) {            try {                url = new URL(args[0]);            } catch (MalformedURLException e) {                e.printStackTrace();                return;            }        } else {            try {                url = new URL("http://www.xx.com/xx.html");            } catch (MalformedURLException e) {                e.printStackTrace();                return;            }        }        FormPoster poster = new FormPoster(url);        poster.add("name", "xx");        poster.add("email", "xx");        try (InputStream in = poster.post()) {            Reader r = new InputStreamReader(in);            int c ;            while ((c = r.read()) != -1) {                System.out.println((char)c);            }        } catch (IOException e) {            e.printStackTrace();        }    }}

URLConnection的安全性考虑

public Permission getPermission() throws IOException

返回一个Permission来测试是否能建立URLConnection连接

猜测MIME类型

仅是猜测

public static String guessContentTypeFromName(String name);public static String guessContentTypeFromStream(InputStream in);

HttpURLConnection

该类是URLConnection的抽象子类。可以改变请求方法(默认是GET):

public void setRequestMethos(String method) throws ProtocolException

参数选项:GET POST HEAD PUT DELETE OPTIONS TRACE

获取响应吗和响应内容:

public int getResponseCode() throws IOExceptionpublic String getResponseMessage() throws IOException

得到错误消息:

public InputStream getErrorStream()
0 0