【问题标题】:why Encoding in http request?为什么在 http 请求中编码?
【发布时间】:2017-03-20 10:28:16
【问题描述】:

我正在尝试使用 Java 上的 http 协议从服务器学习请求和检索数据,这是我在 Oracle>Tutorial>networking 上找到的代码(代码粘贴在问题的底部)

问题1:out.write("string=" + stringToReverse);为什么“string=”没有被编码?像 stringToReverse 变量

String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

问题 2: 下面有两个代码,一个来自 oracle 代码,另一个来自 android studio tuts

oracle tuts 中的代码

BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

android tuts 代码

inputStream = urlConnection.getInputStream();    
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
                BufferedReader reader = new BufferedReader(inputStreamReader);

为什么在 oracle 代码中缺少 Charset.forName("UTF-8")?


注意:从基础解释非常有用:)

import java.io.*;
import java.net.*;

public class Reverse {
public static void main(String[] args) throws Exception {

    if (args.length != 2) {
        System.err.println("Usage:  java Reverse "
            + "http://<location of your servlet/script>"
            + " string_to_reverse");
        System.exit(1);
    }

    String stringToReverse = URLEncoder.encode(args[1], "UTF-8");

    URL url = new URL(args[0]);
    URLConnection connection = url.openConnection();
    connection.setDoOutput(true);

    OutputStreamWriter out = new OutputStreamWriter(
                                     connection.getOutputStream());
    out.write("string=" + stringToReverse);
    out.close();

    BufferedReader in = new BufferedReader(
                                new InputStreamReader(
                                connection.getInputStream()));
    String decodedString;
    while ((decodedString = in.readLine()) != null) {
        System.out.println(decodedString);
    }
    in.close();
}
}

【问题讨论】:

  • 请注意,您的问题涉及两个不同的事情:URL 编码和字符编码(使用 UTF-8 字符集)。这是完全不同的两件事。

标签: java http networking ascii encode


【解决方案1】:

问题 1

不需要对“string=”进行编码(因为它不包含https://docs.oracle.com/javase/6/docs/api/java/net/URLEncoder.html中解释的任何特殊字符)

问题 2

以下示例中的字符集未明确定义:

BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

因此使用默认字符集(可能不是 UTF-8)

Java 虚拟机的每个实例都有一个默认字符集, 这可能是也可能不是标准字符集之一。默认 字符集在虚拟机启动期间确定,通常 取决于底层使用的语言环境和字符集 操作系统。 (https://docs.oracle.com/javase/7/docs/api/java/nio/charset/Charset.html)

【讨论】:

  • 您好先生,这是我对您的回答的理解。 Question1 如果用户给出了任何特殊字符 无论是客户端编程还是服务器端程序都不应解释具有特殊含义,而是应该在没有任何特殊含义的情况下对其进行处理。为此,我们对它们进行编码。请让我知道我是否正确..
【解决方案2】:

在 url 后面的字符串 ?被称为查询字符串

example.com/users/profile?key1=value1&key2=value2

所以对于上面的 url,查询字符串是“key1=value1&key2=value2” 在查询字符串中有服务器脚本可以访问的键值对。这些键值对被称为请求参数,并由 & 分隔。所以 ?、& 、空格等在 url 中被称为特殊字符,因为它们是被浏览器特殊处理。

如果 value1 本身包含一个 & 字符会发生什么情况。服务器会不小心在 user1 的 & 字符之前结束 value1。

name=user1&23=hello&place=hyd

如果您看到上面的示例,它将无法按预期工作。 所以这就是为什么你使用 url 编码来转换特殊字符,比如 & ,? , 空格等在查询字符串中使用时转换为其他一些非特殊字符。服务器将在收到它们后将它们转换回它们的实际形式。

现在回答您的问题 1),在您的情况下不需要 URL 编码,因为您没有将 string_to_reverse 作为请求参数发送到查询字符串中。正如 jesper 指出的那样,这不是 url 编码。您将其作为正文发送使用输出流。

现在问题2),如果你看到http://docs.oracle.com/javase/7/docs/api/java/net/URLEncoder.html类,它的状态如下

Utility class for HTML form encoding. This class contains static methods for converting a String to the application/x-www-form-urlencoded MIME format.

因此 html 表单数据以 application/x-www-form-urlencoded 形式发布,在您的情况下,URLEncoder 负责处理。如果未指定字符集,则使用默认字符集。How to Find the Default Charset/Encoding in Java?

URLEncoder 类中的 URL 名称对您来说有点误导,因为它在这里并不是真正用于编码 url,而是用于将请求正文(string_to_reverse)编码为 application/x-www-form-urlencoded。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 2013-08-07
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    相关资源
    最近更新 更多