URLConnection(四)

news2024/11/25 12:39:18

文章目录

  • 1. 配置客户端请求HTTP首部
  • 2. 向服务器写入数据
  • 3. URLConnection的安全考虑
  • 4. HttpURLConnection

1. 配置客户端请求HTTP首部

HTTP客户端(如浏览器)向服务器发送一个请求行和一个首部,如下:
在这里插入图片描述
web服务器可以根据这个信息向不同的客户端提供不同的页面,获取和设置cookie,通过口令认证用户。通过在客户端发送和服务器响应的首部中放置不同的字段,就可以完成这些工作。在打开连接前可以使用setRequestProoerty()方法为HTTP首部增加首部字段。

public void setRequestProperty(String name,String value)

该方法用指定的名和值为这个URLConnection的首部增加一个字段。这个方法只能在连接打开之前调用。如果连接打开了,它将抛出一个IllegalStateException异常。getRequestProperty()会返回这个URLConnection所用HTTP首部中指定字段的值,public Map<String,List<String>> getRequestProperties()会将字段值用map的形式返回。如果我们要给URLConnection添加新的属性值就调用addRequestProperty(String name, String value)方法。其实并没有一个固定的首部,服务器一般会忽略无法识别的首部,HTTP确实对首部字段的名和值的内容有一定的限制,例如,名不能包含空格,值不能包含换行符号等待,不然getRequestProperty()public Map<String,List<String>> getRequestProperties()会抛出IllegalArgumentException

2. 向服务器写入数据

有时你需要向URLConnection写入数据,例如POST向Web服务器提交表单,获者使用PUT上传文件等。getOutputStream()方法返回一个OutputStream,可以用来吸入数据传送给服务器。

注意由于URLConnection默认情况下不允许输出,所以要调用setDoOutput(true)来运行输出,一旦设置该方法,那么GET方法就会变成POST方法

一旦得到OutputStream就可以串链到BufferdOutputStream或BufferedWriter进行缓冲。

public class Main{
    public static void main(String[] args) {
      try{
          URL u=new URL("http://www.baidu.com?");
          URLConnection uc=u.openConnection();
          uc.setDoOutput(true);
          OutputStream raw=uc.getOutputStream();
          OutputStream bufferd=new BufferedOutputStream(raw);
          OutputStreamWriter out=new OutputStreamWriter(bufferd,"8859_1");
          out.write("first=Julie&middle=&last=Harting&work=String+Quarter\r\n");
          out.flush();
          out.close();
          //开始连接
          uc.connect();
          BufferedReader in=new BufferedReader(new InputStreamReader(uc.getInputStream(),"utf-8"));
          String line=null;
          StringBuffer rest=new StringBuffer();
          while (null != (line=in.readLine())){
                rest.append(line);
          }
          System.out.println(rest.toString());
      }catch(IOException e){
          System.err.print(e);
      }
    }
}

下面是百度的响应输出:
在这里插入图片描述
利用POST发送数据和GET几乎一样,区别是我们利用POST方法是通过URLConnection的getOutputStream()方法写入查询字符串,而不是附加到URL。java会缓冲写入输出流的所有数据,直到流关闭。所以只要你能控制客户端和服务器,就可以使用你喜欢的任何其他数据编码方式。

下面这段程序使用URLConnection类和QueryString类来提交POST表单数据,构造函数设置了URL。查询字符串是使用add方法来构建的。post()方法具体向服务器发送数据,它打开与指定URL的URLConnection,设置其doOutput字段为true,并将查询字符串写入输出流,然后返回包含服务器响应的输入流。

public class Main{
    public static void main(String[] args) throws IOException {
      URL url;
      try{
          url=new URL("http://www.cafeaulait.org/books/jnp4/postquery.phtml");
      }catch(MalformedURLException ex){
          System.err.println("Usage: java FormPoster url");
          return;
      }
       FormPoster poster=new FormPoster(url);
       poster.add("name","jakiechai");
       poster.add("email","elharo@ibiblio.org");
       try(InputStream in=poster.post()){
           Reader r=new InputStreamReader(in);
           int c;
           while((c=r.read())!=-1){
               System.out.print((char)c);
           }
           System.out.println();
       }
    }
   
    
}
class FormPoster{
    private URL url;
    static String val="";
    public FormPoster(URL url){
       if(!url.getProtocol().toLowerCase().startsWith("http"))
       {
            throw new IllegalAccessError("Posting only works for http URLs");
       }
       this.url=url;
    }
    public void add(String name,String value){
        val+=name+":"+value;
    }
    public InputStream post() throws IOException{
        URLConnection uc=url.openConnection();
        uc.setDoOutput(true);
        try(OutputStreamWriter out=new OutputStreamWriter(uc.getOutputStream(),"UTF-8")){
            out.write(val);
            out.write("\r\n");
            out.flush();
        }
        return uc.getInputStream();
    }
}

下面是服务器返回的内容:

Query Results

Query Results

You submitted the following name/value pairs:

  • name:jakiechaiemail:elharo@ibiblio_org =

The request included the following cookies:

    Here's the HTTP request header:

      
    USER_AGENT: Java/1.8.0_332
    HOST: www.cafeaulait.org
    ACCEPT: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
    X_FORWARDED_PROTO: http
    X_FORWARDED_FOR: 106.15.224.186
    CONNECTION: close
    

    Here's the complete body of the request:

    name:jakiechaiemail:elharo@ibiblio.org
    

    Some links:

    This Page Another Page
    Last Modified July 25, 2004

    在这里插入图片描述

    上面方法的核心是POST方法,它首先打开一个连接,指向存储在url字段中的URL。由于这个URLConnection需要发送输出。所以post()方法将这个连接的doOutput字段设置为true,然后将这个URL的OutputStream串联到一个发送数据的ASCII的OutputStreamWriter,接下来刷新输出并关闭流,流不关闭就不会发送任务数据。最后返回InputStream获得服务器响应。下面总结一下表单提交的步骤:

    • 确定要发送给服务器的名-值对
    • 编写接受和处理请求的服务端程序。如果没有使用定制的数据编码,可以使用普通的HTML表单和WEB浏览器测试这个程序
    • 在Java程序中创建一个查询字符串。字符串的形式如下:
      name=value1&name2=value2&jname3=value3
      在增加到查询字符串之前,先将各个名和值传递到URLEncoder.encode()
    • 打开一个URLConnection,指向接受数据的程序URL
    • 将查询字符串写入到URLConnection的OutputStream
    • 关闭URLConnection的OutputStream
    • 从URLConnection的Input Stream读取服务器的响应

    getOutputStream方法还可以用于PUT请求方法,这是一种在WEB服务器上存储文件的方法。要存储的数据写入getOutputStream返回的OutputStream。不过,这只能在URLConnection的HttpURLConnection子类中进行。

    3. URLConnection的安全考虑

    建立网络连接,读/写文件等存在一些常见的安全限制,URLConnection对象会受到这些安全限制的约束。在尝试连接一个URL前,你可能想知道是否运行连接。为此URLConnection类包含了一个getPermission()方法

    public Permission getPermission()throws IOException
    

    它返回一个Java.security.Permission对象,指出连接这个URL所需的权限。如果不需要任何权限就会返回null。URLConnection的子类会返回java.security.Permission的不同子类。

    Permission 类的主要目的是描述对于系统资源的访问权限。这些系统资源可以是文件、网络连接、操作系统功能等。通过使用权限,Java 应用程序可以定义和强制执行安全策略,以控制对敏感资源的访问。Permission 类是一个抽象类,它定义了权限的基本属性和行为,包括权限的名称、描述、是否允许操作等。具体的权限类(如 FilePermission、SocketPermission 等)是 Permission 类的子类,用于表示特定类型的权限。在 Java 安全模型中,权限由权限名和可选的操作列表组成。权限名是一个字符串,用于标识权限的类型和资源的标识符。操作列表表示对资源所允许的操作,如读取、写入、执行等。权限的粒度可以根据需要进行调整,以满足具体的安全需求。通过使用权限对象,可以进行权限检查,以确保应用程序在访问敏感资源之前具有适当的权限。这有助于提供安全性和防止恶意操作。下面是 Permission 类的一些常用方法:

    • getName():获取权限的名称。
    • getActions():获取权限的操作列表。
    • implies(Permission p):检查当前权限是否包含指定的权限。
    • equals(Object obj):比较两个权限对象是否相等。
    • hashCode():获取权限对象的哈希码值。
    • toString():返回权限对象的字符串表示。

    总结来说,java.security.Permission 类提供了一种标准化的方式来表示和管理 Java 应用程序的访问权限。它是 Java 安全模型的核心组件之一,用于实现安全策略和保护敏感资源。

    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 ");
    
           URLConnection ur=u.openConnection();
            System.out.println(ur.getPermission());
        }
    

    在这里插入图片描述

    java.net.SocketPermission 是 java.security.Permission 的一个具体子类,用于表示对网络套接字的权限。它允许应用程序控制对指定主机和端口的网络连接和解析操作。在给定的示例中,“hm.baidu.com:80” 表示要访问的目标主机和端口。它指定了主机名为 hm.baidu.com,端口号为 80,这是 HTTP 协议的默认端口。“connect,resolve” 是指对该主机和端口所允许的操作。具体来说:connect 表示允许建立网络连接。应用程序可以与指定的主机和端口进行网络通信。resolve 表示允许解析主机名。应用程序可以将主机名解析为 IP 地址。

    4. HttpURLConnection

    java.net.HttpURLConnection类就是URLConnection的抽象子类。它提供了另外一些方法,在处理http URL时尤其有帮助。具体地,它包含的方法可以获得和设置请求方法,确定是否重定向、获取响应码和消息,以及确定是否使用了代理服务器。它还包括了几十个便于记忆的常量,对于各种HTTP响应码。最后,它覆盖了URLConnection超类的getPermission方法。由于这个类是抽象类,唯一的构造函数是保护类型的,所以不能直接创建HttpURLConnection实例及。不过使用http URL构造一个URL对象并调用其Openconnection方法,返回的URLConnection就是HttpURLConnection的一个实例。可以将其强转为HttpURLConnection

    URL u=new URL("http://lesswrong.com/
    URLConnection uc=u.openConnection()
    HttpURLConnection http=(HttpURLConnection) uc;
    

    默认情况下HttpURLConnection会使用GET方法,不过,可以用setRequestMethod来改变请求方法

    public void setRequestMethod(String method)throws ProtocolException
    

    这个方法的参数应当是以下7个字符串之一(区分大小写)

    • GET
    • POST
    • HEAD
    • PUT
    • DELETE
    • OPTIONS(向web服务器询问一个指定URL支持的选项列表)
    • TRACE

    当然单纯的调用setRequestMethod设置请求参数效果是不够的,更多的还需要设置我们的请求头消息

    tips:connect方法和openConnection方法的区别
    url.openConnection() 和 url.connect() 是 Java 中用于建立与指定 URL 的连接的两种方式,它们有一些区别。
    url.openConnection():

    1. url.openConnection() 是 URL 类的一个方法,它返回一个 URLConnection 对象,用于建立与指定 URL 的连接。
    2. URLConnection 是一个抽象类,具体的实现类根据 URL 的协议不同而有所不同,比如对于 HTTP 协议可以返回 HttpURLConnection 的实例。
    3. openConnection() 方法返回的 URLConnection 对象可以通过设置请求头、请求方法、读取响应等方式进行更多的控制和操>作。
    4. openConnection() 方法只是建立了与指定 URL 的连接,实际的网络通信在后续的操作中进行,比如读取输入流或写入输出流。

    url.connect():

    1. url.connect() 是 URL 类的一个方法,它是一个简单的调用,用于显式地建立与指定 URL 的连接。
    2. 它实际上是 openConnection() 方法的一个隐式调用,即在调用 connect() 时会自动执行 openConnection()。
    3. connect() 方法在建立连接后立即返回,不会返回具体的连接对象,因此无法对连接进行更多的控制和操作。
    4. connect() 方法适用于简单的连接场景,不需要对连接进行进一步配置和控制的情况。

    总结来说,url.openConnection() 返回一个具体的 URLConnection 对象,可以对连接进行更多的控制和操作,而 url.connect() 是 openConnection() 方法的简化调用,用于简单的连接场景,无需额外的配置和操作。

    HEAD
    HEAD和GET非常类似,它告诉服务器只返回HTTP首部,不用实际发送文件,这个方法最常用的是检查文件在最后一次缓存之后是否有修改。

    public class QuizCardBuilder {
    
        public static void main(String[] args) throws IOException {
            URL url;
            try{
                url=new URL("http://www.baidu.com");
                HttpURLConnection http=(HttpURLConnection) url.openConnection();
                http.setRequestMethod("HEAD");
                System.out.println(url+"was last modified at"+new Date(http.getLastModified()));
                Map<String, List<String>> map = http.getHeaderFields();
                for (Map.Entry<String, List<String>> entry : map.entrySet()) {
                    System.out.println("Key : " + entry.getKey() +
                            " ,Value : " + entry.getValue());
                }
            }catch(MalformedURLException ex){
                System.err.println("Usage: java FormPoster url");
            }
    
        }
    }
    

    在这里插入图片描述
    DELETE
    DELETE方法将删除WEB服务器上位于指定URL得文件,由于这个请求存在明显的安全风险,所以不是所有的服务器都支持该方法,即便支持,也要进行一定的身份认证。
    PUT
    许多HTML编辑器和其他希望在Web服务器上存储文件的程序会使用PUT方法,这个方法允许客户端将文档放在网站的抽象层次结构中,而不需要知道网站如果映射到实际本地文件系统的。这正与FTP相反,FTP需要知道实际的目录结构,而不是服务器的抽象结构。同样DELETE一样它也是不安全的。
    OPTIONS
    该请求方法询问某个特定的URL支持哪些选项,如果请求的URL是星号,那么这个请求会应用到整个服务器而不是服务器上的某个URL。服务器响应OPTIONS,会发送一个HTTP首部以及这个URL上允许的命令列表。

    在这里插入图片描述

    TRACE
    该方法会发送HTTP首部,服务器将从客户端接受这个HTTP首部。之所以需要这个信息,主要原因是要查看服务器和客户端之间的代理服务器做了哪些修改。

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

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

    相关文章

    Visual Studio 远程调试工具(Remote Debugger)使用方法

    一、关于Remote Debugger 当项目在测试环境上有bug&#xff0c;需要运行代码调试一下&#xff0c;这时就需要在测试环境上安装一个调试工具&#xff08;Remote Debugger&#xff09;&#xff0c;然后在本地运行代码&#xff0c;远程链接到测试环境服务器来调试代码&#xff1b…

    算法基础学习笔记——⑦位运算

    ✨博主&#xff1a;命运之光 ✨专栏&#xff1a;算法基础学习 目录 ✨位运算 ✨操作一 &#x1f353;十进制转化成二进制、八进制、十六进制&#xff08;连除法&#xff09; &#x1f353;二进制、八进制、十六进制转化成十进制 &#x1f353;关于原码&#xff0c;反码&am…

    Unity四叉树地图

    当使用Unity构建大规模的游戏地图或场景时&#xff0c;使用四叉树数据结构可以提高性能和效率。四叉树是一种基于分割的数据结构&#xff0c;将空间划分为四个相等的子区域&#xff0c;并以递归方式构建树结构。在游戏开发中&#xff0c;四叉树常用于空间分区、碰撞检测和可视化…

    Eclipse 教程Ⅱ

    Eclipse 修改字符集 默认情况下 Eclipse 字符集为 GBK&#xff0c;但现在很多项目采用的是 UTF-8&#xff0c;这是我们就需要设置我们的 Eclipse 开发环境字符集为 UTF-8&#xff0c; 设置步骤如下&#xff1a; 在菜单栏选择 Window -> Preferences -> General -> W…

    python的统计函数库scipy.stats是一个很棒的统计包

    描述&#xff1a;在Scipy的模块中&#xff0c;有一个统计的木块——States,其中函数有描述统计(describe)、峰度(kurtosis)、偏度(skew)、众数(mode)、n阶矩。 分布&#xff1a;还有一些分布函数&#xff0c;正泰分布(norm)、对数正态分布(lognorm)、…… 计算&#xff1a;针…

    Go语言介绍以及Go语言环境安装

    初步介绍&#xff1a; Go 是一个开源的编程语言&#xff0c;它能让构造简单、可靠且高效的软件变得容易。 Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发&#xff0c;后来还加入了Ian Lance Taylor, Russ Cox等人&#xff0c;并最终于2009年11月开源&am…

    Manjaro linux 安装svn 并在文件管理器里显示相关图标

    需要先安装svn linux版打开终端执行 1 sudo pacman -S svn 安装完成后执行一下 1 svn --version 出现这个就说明svn已经安装完成了&#xff0c;这个时候我们可以执行 1 svn checkout [路径] 就可以检出svn服务器上相关内容了 但是这个有的时候我们打开文件管理器想要看到被…

    并发编程的三大特性之原子性

    原子性 这个定义是一种规定&#xff0c;描述了Java中的理想就是为了能实现一个操作不能分割&#xff0c;不可中断&#xff0c;一个线程在执行的时候&#xff0c;另一个线程不会去影响他。 Java中的原子性可以理解为多线程操作临界资源&#xff0c;预期的结果和最终的结果一致。…

    STM32基本外设超详细44000字教程

    GPIO GPIO&#xff08;General Purpose Input Output&#xff09;通用输入输出口可配置为8种输入输出模式引脚电平&#xff1a;0V~3.3V&#xff0c;部分引脚可容忍5V输出模式下可控制端口输出高低电平&#xff0c;用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等输入模式下可…

    ML | 5 Logistic回归

    ML | 5 Logistic回归 文章目录 ML | 5 Logistic回归Logistic回归思想基于Logistic回归和Sigmoid函数分类基于最优化方法的最佳回归系数确定梯度上升法**梯度上升法例子&#xff1a;**梯度下降法 训练算法&#xff1a;使用梯度上升找到最佳参数画出决策边界 训练算法&#xff1a…

    本地是如何开启Nginx服务的?

    一、window 配置Nginx服务器 1、Nginx下载地址 http://nginx.org/en/download.html 选择一个适合自己的版本 2、下载后直接解压 3、修改Nginx启动端口 配置文件位置&#xff1a;nginx-1.22.0/conf/nginx.conf 默认80&#xff0c;以防端口被重用&#xff0c;改为8056 4&…

    PFEA112-20 3BSE050091R20 张力控制器

    您的张力测量系统包括&#xff1a; 张力电子PFEA111或PFEA112–PFEA111是一款经济高效的紧凑型用户友好型张力电子产品&#xff0c;提供 来自两个称重传感器的精确可靠的快速模拟SUM信号&#xff0c;用于控制 和/或监测。显示器可以显示SUM、单个A&B和差异信号小尺寸和DIN导…

    k8s 维护node与驱逐pod

    1.维护node节点 设置节点状态为不可调度状态&#xff0c;执行以下命令后&#xff0c;节点状态会多出一个SchedulingDisabled的状态&#xff0c;即新建的pod不会往该节点上调度&#xff0c;本身存在node中的pod保持正常运行 kubectl cordon k8s-node01 kubectl get node 2.驱…

    多线程并发环境生产者-消费者,kotlin

    多线程并发环境生产者-消费者&#xff0c;kotlin 多个生产者-多个消费者&#xff0c;消费者竞争抢占生产者制造的资源。 //存放资源的仓储 val store arrayOfNulls<Int>(1)//资源 var RESOURCE: Int 0fun producer(tid: Long) {synchronized(store) {if (isFull()) {…

    【MySQL】- 02MySQL explain执行

    目录 1.使用explain语句去查看分析结果2.MYSQL中的组合索引3.使用慢查询分析&#xff08;实用&#xff09;4.MYISAM和INNODB的锁定explain用法详解关于MySQL执行计划的局限性&#xff1a;备注&#xff1a; 1.使用explain语句去查看分析结果 如explain select * from test1 whe…

    MicroPython应用基础-准备MicroPython开发板

    MicroPython应用基础-准备基于MM32F5的MicroPython开发板 文章目录 MicroPython应用基础-准备基于MM32F5的MicroPython开发板引言硬件软件搭建MicroPython编译环境获取MicroPython源码编译MicroPython源码生成固件下载MicroPython固件到电路板 运行第一个样例工程 引言 本文主…

    JavaScript变量、数据类型、运算符

    1. 变量 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, in…

    GoWeb -- gin框架的入门和使用

    认识gin go流行的web框架 go从诞生之初就带有浓重的开源属性&#xff0c;其原生库已经很强大&#xff0c;即使不依赖框架&#xff0c;也能进行高性能开发&#xff0c;又因为其语言并没有一定的设计标准&#xff0c;所以较为灵活&#xff0c;也就诞生了众多的框架&#xff0c;各…

    使用朴素贝叶斯过滤垃圾邮件

    使用朴素贝叶斯过滤垃圾邮件 文章目录 使用朴素贝叶斯过滤垃圾邮件流程准备数据构建训练集和测试集分类电子邮件 完整测试代码&#xff1a;欢迎关注公众号【三戒纪元】 朴素贝叶斯的最著名的应用&#xff1a;过滤电子邮件垃圾。 流程 收集数据&#xff1a;提供文本文件准备数据…

    【ISO14229_UDS刷写】-3-$36诊断服务TransferData理论部分

    总目录&#xff1a;&#xff08;单击下方链接皆可跳转至专栏总目录&#xff09; 《UDS/OBD诊断需求编辑工具》总目录https://blog.csdn.net/qfmzhu/article/details/123697014 目录 1 $0x36 TransferData诊断服务描述 2 0x36服务请求消息 2.1 0x36服务请求消息定义 2.2 0…