URLConnection(二)

news2024/11/17 10:51:51

文章目录

    • 1. 缓存
    • 2. Java的Web缓存

1. 缓存

Web浏览器会缓存页面和图片,将资源缓存在本地,每次需要时会从缓存中重新加载,而不是每次都请求远程服务器。一些HTTP首部(包括Expires和Cache-Control)可以控制首部。默认情况下,一般认为使用GET通过HTTP访问的页面都可以缓存,也应当缓存。使用HTTPS或POST访问的页面通常不应当缓存,不过HTTP可以对此进行调整。

  • Expires首部(主要针对HTTP 1.0)指示可以缓存这个资源表示,直到时间为止
  • Cache-control首部(HTTP 1.1)提供了细粒度的缓存策略
  • max-age=[seconds]:从现在直到缓存项过期之前的秒数
  • s-maxage=[seconds]:从现在起,知道缓存项在共享缓存中过期之前的秒数
  • public:可以缓存一个经过认证的响应。否则已认证的响应不会缓存
  • private:仅单个缓存可以保存响应,而共享缓存不应保存
  • no-cache:客户端每次访问时要用一个Etag或Last-modified首部重新验证响应的状态
  • no-store:不管怎么样都不缓存

如果Cache-control和Expires首部都出现,Cache-control会覆盖Expires。服务器可以在一个首部中发送多个Cache-contrll首部,只要它们没有冲突

  • Last-modified:表示资源最后一次修改的时间,只有本地缓存的时间早于这个时间时才会执行get来获得资源
  • Etag首部(HTTP 1. 1)是资源改变时这个资源的唯一标识符,只有当本地缓存的副本有一个不同的Etag时,它才会执行GET来获取资源。下面代码展示了Java解析和查询Cache-control首部的过程:
public class QuizCardBuilder {

    public static void main(String[] args) throws IOException {
       URL u = new URL("\n" +
               "https://hm.baidu.com/hm.gif?hca=36FB9E633015756B&cc=1&ck=1&cl=24-bit&ds=1920x1080&vl=1001&ep=7111%2C2543&et=10&ja=0&ln=zh-cn&lo=0&lt=1684721081&rnd=108138644&si=6bcd52f51e9b3dce32bec4a3997715ac&su=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DQUDdVYc4ExLePOefaclpkkQyDsywEmMmz4W37KJFhafJByp_lyapL-JzapNuyFy2rK_qZJfRbkQ6CuWmXotAc4dSqZuZENMBepfFjFjxwdq%26wd%3D%26eqid%3D95614ab00000085400000005646f571f&v=1.3.0&lv=3&sn=52924&r=0&ww=705&p=islogin*1*1!isonline*1*1!isvip*0*1!uid_*qq_43456605*1!view_h_*914&u=https%3A%2F%2Fblog.csdn.net%2Fqq_44231797%2Farticle%2Fdetails%2F121343892 ");
       String header="";
       URLConnection ur=u.openConnection();
        for (int i = 1; ; i++) {
            if(ur.getHeaderField(i)==null)break;
            String myheader=ur.getHeaderFieldKey(i)+": "+ur.getHeaderField(i);
            System.out.println(myheader);
            header+=myheader;
        }
        CacheControl cacheControl=new CacheControl(header);
        System.out.println("________________________________________________________");
        System.out.println(cacheControl);

    }
}
class  CacheControl{
    private Date MaxAge=null;
    private Date sMaxAge=null;
    private boolean mustRevalidate=false;
    private boolean noCache=false;
    private boolean noStore=false;
    private boolean proxyRevalidate=false;
    private boolean publicCache=false;
    private boolean privateCache=false;

    public Date getMaxAge() {
        return MaxAge;
    }

    public void setMaxAge(Date maxAge) {
        MaxAge = maxAge;
    }

    public Date getsMaxAge() {
        return sMaxAge;
    }

    public void setsMaxAge(Date sMaxAge) {
        this.sMaxAge = sMaxAge;
    }

    public boolean isMustRevalidate() {
        return mustRevalidate;
    }

    public void setMustRevalidate(boolean mustRevalidate) {
        this.mustRevalidate = mustRevalidate;
    }

    public boolean isNoCache() {
        return noCache;
    }

    public void setNoCache(boolean noCache) {
        this.noCache = noCache;
    }

    public boolean isNoStore() {
        return noStore;
    }

    public void setNoStore(boolean noStore) {
        this.noStore = noStore;
    }

    public boolean isProxyRevalidate() {
        return proxyRevalidate;
    }

    public void setProxyRevalidate(boolean proxyRevalidate) {
        this.proxyRevalidate = proxyRevalidate;
    }

    public boolean isPublicCache() {
        return publicCache;
    }

    public void setPublicCache(boolean publicCache) {
        this.publicCache = publicCache;
    }

    public boolean isPrivateCache() {
        return privateCache;
    }

    public void setPrivateCache(boolean privateCache) {
        this.privateCache = privateCache;
    }

    public CacheControl(String s){
        if(s==null|| !s.contains(":")){
            return;
        }
        //trim() 函数移除字符串两侧的空白字符或其他预定义字符
        String value=s.split(":")[1].trim();
        String[] components=value.split(",");
        Date now=new Date();
        for(String component: components){
            try {
                //表示中国时间
                component=component.trim().toLowerCase(Locale.CHINA);
                if(component.startsWith("max-age=")){
                    int secondsInTheFuture=Integer.parseInt(component.substring(8));
                    MaxAge=new Date(now.getTime()+1000*secondsInTheFuture);
                }else if(component.startsWith("s-maxage=")){
                    int secondsInTheFuture=Integer.parseInt(component.substring(8));
                    sMaxAge=new Date(now.getTime()+1000*secondsInTheFuture);
                }else if(component.equals("must-revalidate")){
                    mustRevalidate=true;
                }else if(component.equals("proxy-revalidate")){
                    proxyRevalidate=true;
                }else if(component.equals("no-cache")){
                    noCache=true;
                }else if(component.equals("public")){
                    publicCache=true;
                }else if(component.equals("private")){
                    privateCache=true;
                }
            }catch (RuntimeException e){
                continue;
            }
        }

    }

    @Override
    public String toString() {
        return "CacheControl{" +
                "MaxAge=" + MaxAge +
                ", sMaxAge=" + sMaxAge +
                ", mustRevalidate=" + mustRevalidate +
                ", noCache=" + noCache +
                ", noStore=" + noStore +
                ", proxyRevalidate=" + proxyRevalidate +
                ", publicCache=" + publicCache +
                ", privateCache=" + privateCache +
                '}';
    }
}

在这里插入图片描述

2. Java的Web缓存

默认情况下Java并不完成缓存,要安装URL类使用的系统级缓存,需有有:

  • ResponseCache的一个具体子类
  • CacheRequest的一个具体子类
  • CacheResponse的一个具体子类

要安装你的ResponseCache子类来处理你的CacheRequest和CacheResponse子类,需要把它传递到静态方法ResponseCache.setDefault(),这会把这个缓存对象安装为系统默认缓存,Java虚拟机只支持一个共享缓存。一旦安装了缓存,只要系统尝试加载一个新的URL,它首先会从这个缓存中查找,如果缓存返回了所要的内容,URLConnection就不需要与远程服务器连接了。不过,如果所请求的数据不在缓存中,协议处理器将从远程服务器下载相应的数据。完成之后,它会把这个响应放在缓存里面,下一次就可以直接查缓存了。

在Java中,协议处理器(Protocol Handler)是一种用于处理特定协议的组件。它允许Java应用程序通过各种网络协议(如HTTP、HTTPS、FTP等)与远程资源进行通信。Java的协议处理器是通过Java的URL(统一资源定位符)类和URLConnection(统一资源链接)类来实现的。URL类表示一个统一资源定位符,而URLConnection类用于建立与指定URL之间的连接,并可以进行读取和写入操作。当Java应用程序需要与远程资源进行通信时,可以使用URL类创建一个URL对象,然后通过openConnection()方法获取与该URL的连接。根据URL的协议,Java会选择适当的协议处理器来处理连接。例如,如果URL的协议是HTTP,Java将使用内置的HTTP协议处理器来处理连接。Java的协议处理器提供了一组标准的方法和接口,用于发送请求、接收响应、处理Cookie、处理重定向等常见的协议操作。同时,它也支持自定义的协议处理器,允许开发人员根据需要实现自定义的协议处理逻辑。总之,Java的协议处理器是一种用于处理特定协议的组件,它允许Java应用程序通过各种网络协议与远程资源进行通信,并提供了一组标准的方法和接口来处理常见的协议操作。

ResponseCache提供了两个抽象方法,可以存储和获取缓存中的数据:

public abstract CacheResponse get(URI uri,String reuqestMethod, Map<String,List<String>> requestHeaders) throws IOException

public abstract CacheRequest put(URI uri,URLConnection connection)

put方法返回一个CacheRequest对象,包装了一个OutputStream,URL将把读取的可缓存数据写入这个输出流,CacheRequest是一个抽象类,它有两个方法

public abstract class CacheRequest{
    public abstract OutputStream getBody() throws IOException
    public abstract void abort();
}

子类中的getOutputStream()方法应当返回一个OutputStream,指向缓存中的“数据库”,这个数据库与同时传入put()方法的URI对应。例如一个数据存储在一个文件中 ,就要返回连接到这个文件的FileOutputStream。协议处理器会把读取的数据复制到这个OutputStream。如果复制时出现了问题(例如,服务器意外的关闭了连接),协议处理器就会调用abort()方法。这个方法应当从缓存中删除为这个请求存储的所有数据。下面实现一个简单的CacheRequest一个子类:

public class SimpleCacheRequest extends CacheRequest{
  private ByteArrayOutputStream out=new ByteArrayOutputStream();
  @Override
  public OutputStream getBody() throws IOException
  {
     return out;
     }
   @Override
   public void abort(){
     out.reset();
   }
   public byte[] getData(){
     if(out.size()==0)
        return null;
     else
        return out.toByteArray();
   }
}

ResponseCache的get()方法从缓存中获取数据和首部,包装在CacheRespose对象中返回。如果所需的URI不在缓存中,则返回null,在这种情况上,协议处理器会正常地从远程服务器加载这个URI。

public abstract class ResponseCache {
    private static ResponseCache theResponseCache;
    public synchronized  static ResponseCache getDefault() {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(SecurityConstants.GET_RESPONSECACHE_PERMISSION);
        }
        return theResponseCache;
    }
    public synchronized static void setDefault(ResponseCache responseCache) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(SecurityConstants.SET_RESPONSECACHE_PERMISSION);
        }
        theResponseCache = responseCache;
    }
    public abstract CacheResponse
        get(URI uri, String rqstMethod, Map<String, List<String>> rqstHeaders)
        throws IOException;
    public abstract CacheRequest put(URI uri, URLConnection conn)  throws IOException;
}

前面说过Java要求一次只能有一个URL缓存,要安装或改变缓存,需要使用静态方法ResponseCache.setDefault()和ResponseCache.getDefault(),这些方法会设置同一个java虚拟机中运行的所有程序所使用的缓存。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/570638.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OJ练习第116题——二进制矩阵中的最短路径(BFS)

二进制矩阵中的最短路径 力扣链接&#xff1a;1091. 二进制矩阵中的最短路径 题目描述 给你一个 n x n 的二进制矩阵 grid 中&#xff0c;返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径&#xff0c;返回 -1 。 二进制矩阵中的 畅通路径 是一条从 左上角 单元格&am…

记一次Redis消息订阅序列化和反序列化的错误

1、使用的SpringBoot&#xff1b; 2、Redis的Config配置了JSON序列化&#xff0c;覆盖JDK序列化&#xff0c;便于中文查看&#xff0c;配置文件使用ConditionalOnProperty断言&#xff1b; 3、Nacos动态配置&#xff1b; 解决思路&#xff1a; 1、查看Redis中存入的数据乱码&am…

最佳WP Grid Builder评测:灵活的网格和过滤器

当您坐下来观看足球比赛时&#xff0c;您从一英里外都很容易看到超级巨星。 时尚而精致的比赛让他们与众不同&#xff0c;并且比赛的结果经常改变。球迷和经理们都喜欢他们&#xff0c;因为当他们踢球时&#xff0c;他们处于绝对最佳状态。 这同样适用于音乐界的巨星。通常&a…

Go中的异常处理(基础)

Go 中异常处理 主要掌握 一下几个方面: 掌握error接口掌握defer延迟掌握panic及recover error接口 error是指程序中出现不正常的情况,从而导致程序无法正常运行; go中为错误的类型提供了简单的错误处理机制 go中error的源码: // The error built-in interface type is t…

舵机云台实现追踪球形目标功能

1. 功能说明 在样机舵机云台上安装一个摄像头&#xff0c;本文示例将实现舵机云台追踪球形物体的功能。 2. 电子硬件 在这个示例中&#xff0c;我们采用了以下硬件&#xff0c;请大家参考&#xff1a; 主控板 Basra主控板&#xff08;兼容Arduino Uno&#xff09;‍ 扩展板 Bi…

Linux之创建进程、查看进程、进程的状态以及进程的优先级

文章目录 前言一、初识fork1.演示2.介绍3.将子进程与父进程执行的任务分离4.多进程并行 二、进程的状态1.进程的状态都有哪些&#xff1f;2.查看进程的状态2.运行&#xff08;R&#xff09;3.阻塞4.僵尸进程&#xff08;Z&#xff09;1.僵尸状态概念2.为什么要有僵尸状态&#…

Rust每日一练(Leetday0011) 下一排列、有效括号、搜索旋转数组

目录 31. 下一个排列 Next Permutation &#x1f31f;&#x1f31f; 32. 最长有效括号 Longest Valid Parentheses &#x1f31f;&#x1f31f;&#x1f31f; 33. 搜索旋转排序数组 Search-in-rotated-sorted-array &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷…

开发 Microsoft 365 Copilot Plugin!

大家好&#xff01;我是韩老师。 昨天凌晨的微软 Build 大会&#xff0c;大家都看了吗&#xff1f; 我看到了凌晨两点&#xff0c;且毫无困意&#xff01; 真的是干货满满~ 列举几个比较大的发布&#xff1a;1. Windows Copilot2. Bing 成为 ChatGPT 的默认搜索体验3. AI 插件生…

一起看 I/O | 移动设备、Web、AI 和 Google Cloud 更新一览

作者 / Developer X 副总裁兼总经理、开发者关系主管 Jeanine Banks 感谢您再次与我们共享 Google I/O 大会的精彩&#xff01;我们正在持续深度投入资源来提升 AI、移动设备、Web 和 Google Cloud&#xff0c;致力于让您的开发工作更加轻松。现在&#xff0c;您看到了许多我们…

实测「360智脑」的真正实力:能否领跑国内百“模”大战?

ChatGPT 的发布&#xff0c;无疑掀起了一股“AI 技术”新浪潮。百度文心一言、华为盘古、商汤日日新、阿里通义千问、讯飞星火等众多大模型的接连问世&#xff0c;使得国内的“百模之战”进入了前所未有的白热化阶段。无论是各大互联网巨头&#xff0c;还是清华、复旦等知名高校…

聊聊「短信」渠道的设计与实现

有多久&#xff0c;没有发过短信了&#xff1f; 一、背景简介 在常规的分布式架构下&#xff0c;「消息中心」的服务里通常会集成「短信」的渠道&#xff0c;作为信息触达的重要手段&#xff0c;其他常用的手段还包括&#xff1a;「某微」、「某钉」、「邮件」等方式&#xff…

多种群遗传算法的函数优化算法

以下内容大部分来源于《MATLAB智能算法30个案例分析》&#xff0c;仅为学习交流所用。 1 理论基础 1.1 遗传算法早熟问题 遗传算法是一种借鉴生物界自然选择和进化机制发展起来的高度并行、随机、自适应的全局优化概率搜索算法。由于优化时不依赖于梯度&#xff0c;具有很强…

拥抱新时代的Java

原文链接 拥抱新时代的Java Java作为面向对象编程的王牌语言&#xff0c;曾经风靡一时&#xff0c;在Web领域是绝对的老大。随着时间的推移&#xff0c;一些新的编程范式不断的涌现&#xff0c;如函数式编程&#xff0c;响应式编程&#xff0c;以及对函数的全力支持&#xff0…

北邮22信通:实验五 共射放大电路的频率特性与深负反馈的影响

北邮22信通一枚~ 很高兴以一个新身份与大家见面~ 关注作者&#xff0c;解锁更多邮苑模电实验报告~ 获取更多文章&#xff0c;请访问专栏&#xff1a; 北邮22信通——电子电路_青山如墨雨如画的博客-CSDN博客 目录 实验目的&#xff1a; 实验设备及器件&#xff1a; …

区间预测 | MATLAB实现QGPR高斯过程分位数回归多变量时间序列区间预测

区间预测 | MATLAB实现QGPR高斯过程分位数回归多变量时间序列区间预测 目录 区间预测 | MATLAB实现QGPR高斯过程分位数回归多变量时间序列区间预测效果一览基本介绍模型描述程序设计参考资料 效果一览 基本介绍 MATLAB实现QGPR高斯过程分位数回归多变量时间序列区间预测 1.基于…

可用于Stable Diffusion免费的AI绘画标签生成器

这是一个开源项目&#xff0c;借花献佛&#xff0c;基于原作者的基础上进行了微调还有以及修改内容。 支持中英文&#xff0c;权重以及xxxx词汇&#xff0c;老司机都懂。 直接可在右侧根据需求进行点选操作&#xff0c;然后复制到自己的Stable Diffusion中进行AI绘画。 下载…

【产品经理】移动手机区别于PC端的10点特性

众所周知&#xff0c;当今时代已经是移动互联网时代。相比以前大家热衷于在电脑上浏览网页、玩游戏的情形&#xff0c;现在大家都喜欢通过移动手机去满足个人方方面面的需求&#xff0c;无论是购物、吃饭、求职、阅读、聊天、游戏等等。也就是说&#xff0c;在日常的生活中&…

ChatGPT变现赚钱 第二篇

前面我们已经介绍了一些利用ChatGPT做变现的一些玩法&#xff0c;比如做微信问一问的回答&#xff0c;做AI剪映的一键生成视频的(星球里面有详细的指南和视频)。 现在我们会员群在玩百度问一问答题&#xff0c;这个项目蛮好的&#xff0c;成本很低&#xff0c;现在又有苹果手机…

利用视听短片从自然刺激中获得开放的多模式iEEG-fMRI数据集

在认知神经科学领域&#xff0c;数据共享和开放科学变得越来越重要。虽然许多参与认知神经科学实验的志愿者的数据集现在是公开可用的&#xff0c;但颅内脑电图&#xff08;iEEG&#xff09;数据的共享相对较少。iEEG是一种高时间和空间分辨率的记录技术&#xff0c;通过在患者…

组长给组员派活,把组长自己的需求和要改的bug派给组员,合理吗?

组长把自己的工作派给手下&#xff0c;合理吗&#xff1f; 一位程序员问&#xff1a; 组长给他派活&#xff0c;把组长自己的需求或者要改的bug派给他。组长分派完需求之后&#xff0c;他一个人干两个项目&#xff0c;组长却无所事事&#xff0c;这样合理吗&#xff1f; 有人说…