URLConnection(四)

这篇具有很好参考价值的文章主要介绍了URLConnection(四)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

HTTP客户端(如浏览器)向服务器发送一个请求行和一个首部,如下:
URLConnection(四)
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);
      }
    }
}

下面是百度的响应输出:
URLConnection(四)
利用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

    URLConnection(四)

    上面方法的核心是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());
        }
    

    URLConnection(四)

    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");
            }
    
        }
    }
    

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

    URLConnection(四)

    TRACE
    该方法会发送HTTP首部,服务器将从客户端接受这个HTTP首部。之所以需要这个信息,主要原因是要查看服务器和客户端之间的代理服务器做了哪些修改。文章来源地址https://www.toymoban.com/news/detail-460862.html

    到了这里,关于URLConnection(四)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

    本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

    领支付宝红包 赞助服务器费用

    相关文章

    • uniapp中运行至微信浏览器(客户端)视频自动播放

      属性解释 v-if=\\\"isShow\\\" :用于根据 isShow 的值来判断是否显示该视频标签。如果 isShow 的值为 true ,则显示视频。 :id=\\\"list._id+\\\'_\\\'+index\\\" :为视频元素设置一个唯一的 id ,通常是使用 _id (可能是视频的唯一标识符)与 index (循环索引)的组合。 ref=\\\"videoPlayer\\\" :为视频元素设置一

      2024年02月13日
      浏览(48)
    • XSS攻击:利用Beef劫持被攻击者客户端浏览器

      实验目的:了解什么是XSS;了解XSS攻击实施,理解防御XSS攻击的方法 系统环境:Kali Linux 2、Windows Server 网络环境:交换网络结构 实验工具: Beef;AWVS(Acunetix Web Vulnarability Scanner) 实验步骤: 实验环境搭建。 角色:留言簿网站。存在XSS漏洞;(IIS或Apache、guestbook搭建) 攻击者

      2024年02月03日
      浏览(50)
    • Java编程技巧:获取ip地址、通过ip获取地理位置、获取客户端操作系统、获取客户端浏览器、获取主机名、获取操作系统、获取系统架构

      说明: 大家直接去对应项目位置找到代码,然后看着复制就行了 1.1、若依(自己写的代码) 项目:https://gitee.com/y_project/RuoYi 子模块:ruoyi-common 所在类:com.ruoyi.common.utils.IpUtils 所在方法:getIpAddr 详细位置:整个方法 1.2、Snowy(借助hutool工具包) 项目:https://gitee.com/xiaonuo

      2024年02月04日
      浏览(131)
    • 1.6 服务器处理客户端请求

      客户端进程向服务器进程发送一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)。 从图中我们可以看出,服务器程序处理来自客户端的查询请求大致需要经过三个部分,分别是 连接管理 、 解析与优化 、 存储引擎 。 客户端进程可以采用我

      2024年02月11日
      浏览(40)
    • Java 获取客户端请求IP地址

      2024年02月15日
      浏览(45)
    • SpringBoot3 响应式网络请求客户端

       SpringBoot是一个基于Spring的快速开发框架,它可以帮助我们快速构建、部署和运行Java应用程序。HTTP接口是Web应用程序与外部系统进行通信的一种方式,通过HTTP协议,我们可以实现客户端与服务器之间的数据交互。 SpringBoot 整合提供了很多方式进行远程调用 轻量级客户端方

      2024年02月15日
      浏览(34)
    • JAVA使用WebSocket实现多客户端请求

      工作前提:两个服务之间实现聊天通讯,因为介于两个服务,两个客户端 方案1:多个服务端,多个客户端,使用redis把用户数据ip进行存储,交互拿到redis数据进行推送 方案2: 一个服务端,多个客户端,拿到客户端的id和需要推送的id进行拼接存储 此文章使用的是方案2 1. 引

      2024年02月11日
      浏览(48)
    • 客户端请求+返回 服务端之间的请求和返回 实现rpc通信

      背景:         1.无论什么类型的游戏,我们都会有rpc通信的需求。         2.由于客户端直连的是游戏服,如果工会,匹配之类的服务是单独的服务的话,必然要进行游戏服到业务服之间的转发,我们是否需要再转发时单独定义Req和Res就是我们考虑到的需求。         3.在

      2024年01月25日
      浏览(41)
    • 获取客户端请求IP及IP所属城市

      添加pom依赖       dependency             groupIdorg.lionsoul/groupId             artifactIdip2region/artifactId             version2.6.5/version         /dependency public class IpUtil {     private static Searcher searcher;     private static final String DEFAULT_UNKNOWN=\\\"unknown\\\";     private static final int IP_MIN_LENGT

      2024年02月08日
      浏览(51)
    • MYSQL连接报错:客户端不支持服务器请求的身份验证协议;考虑升级MYSQL客户端数据库

      在进行MYSQL数据库连接时,有时候可能会遇到如上所述的错误:“客户端不支持服务器请求的身份验证协议;考虑升级MYSQL客户端数据库”。这个错误通常发生在客户端使用的MYSQL版本与服务器所要求的身份验证协议不兼容的情况下。幸运的是,您可以通过升级MYSQL客户端来解

      2024年02月03日
      浏览(57)

    觉得文章有用就打赏一下文章作者

    支付宝扫一扫打赏

    博客赞助

    微信扫一扫打赏

    请作者喝杯咖啡吧~博客赞助

    支付宝扫一扫领取红包,优惠每天领

    二维码1

    领取红包

    二维码2

    领红包