5.1.3 用HTTP响应消息头传输中文信息

优质
小牛编辑
132浏览
2023-12-01

使用HTTP响应头传递信息是一件非常“酷”的事。但遗憾的是,在传递中文时,会出现乱码问题。其实要解决这个问题也非常简单,只需要对要传输的中文进行编码,然后在接收它们的客户端再对其进行解码即可。

例子 : 用HTTP响应消息头传输中文信息

1. 实例说明

在本程序中通过HTTP响应消息头分别传输英文消息、中文消息和被编码后的中文消息(对中文消息的编码可以采用多种方式,在本例中采用了URL编码的方式,也就是使用java.net.URLEncoder.encode方法对中文消息进行编码),并在客户端使用Socket来访问该Servlet程序,并输出相应的中、英文消息。

2. 编写ChineseHeader类

ChineseHeader是一个Servlet类,负责向客户端发送HTTP响应消息,该类的实现代码如下:

public class ChineseHeader
{
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //  设置英文响应消息头
        response.addHeader("English", "information");
        //  设置中文响应消息头
        response.addHeader("Chinese", "中文头信息");
        //  设置被编码的中文响应消息头
        response.addHeader("NewChinese", java.net.URLEncoder.encode("中文头信息",
                "utf-8"));
        out.println("响应正文");
    }
}

上面的代码向客户端输出了三个自定义的HTTP响应消息头字段:English、Chinese和NewChinese。其中English字段值是英文消息、Chinese字段值是未编码的中文消息,而NewChinese字段值是用UTF-8格式编码的中文消息。

ChineseHeader类的配置代码如下:

<servlet>
    <servlet-name>ChineseHeader</servlet-name>
    <servlet-class>chapter5.ChineseHeader</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>ChineseHeader</servlet-name>
    <url-pattern>/ChineseHeader</url-pattern>
</servlet-mapping>

3. 查看HTTP响应消息头

查看HTTP响应消息头的方法很多,如可以使用telnet或自己编写程序来获得HTTP响应消息头信息。但这些方式都需要编写程序,比较麻烦。因此,可以借助更简单的工具来完成这个工作。在本例中使用了一个叫“影音传送带”的下载工具。读者也可以使用其它的下载工具。

使用影音传送带下载如下的URL:

   http://localhost:8080/demo/ChineseHeader

然后查看影音传送带的下载日志,如图5.1所示。

01

图5.1 查询HTTP响应消息头

图5.1中的黑框中的内容就是在服务端设置的三个自定义HTTP响应消息头。由此可以看出,English字段的值正常显示了,而Chinese和NewChinese字段的值并没有正常显示。其中Chinese字段的值是乱码,而NewChinese字段的值显示的是URL编码格式。其实这些编码就是“中文头消息”的UTF-8编码,要想获得正确的中文消息,必须要使用java.net.URLDecoder类对其解码。

从以上结果可以得出一个结论,使用setCharacterEncoding或其他方法设置字符集编码,并不会对HTTP响应消息头进行编码,而只会对响应正文进行编码。

4. 编写访问ChineseHeader的客户端程序(MyChineseHeader类)

MyChineseHeader类是一个控制台程序,在该类中通过java.net.Socket类来访问服务端程序,并对被编码的中文消息进行解码。MyChineseHeader类的实现代码如下:

package chapter5;
import java.net.*;
import java.io.*;
public class MyChineseHeader
{
    public static void main(String[] args) throws Exception
    {
        Socket socket = new Socket("localhost", 8080);
        OutputStream os = socket.getOutputStream();
        java.io.OutputStreamWriter osw = new OutputStreamWriter(os);
        // 向服务端发送HTTP请求消息(只有请求头)
        osw.write("GET /demo/ChineseHeader HTTP/1.1\r\n");
        osw.write("Host:localhost:8080\r\n");
        osw.write("Connection:close\r\n\r\n");
        osw.flush();
        //  从服务端获得HTTP响应消息头
        InputStream is = socket.getInputStream();
        InputStreamReader isr = new InputStreamReader(is, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String s = "";
        String responseData = "";
        // 按行读取HTTP响应消息头
        while((s = br.readLine()) != null)
        {
            responseData += s + "\r\n";
        }
        responseData = java.net.URLDecoder.decode(responseData, "UTF-8");       
        System.out.println(responseData);       // 输出解码后的HTTP响应头
        is.close();   
        os.close();           
    }
}

在编写上面的代码时要注意的是在进行解码时,解码格式必须和服务端一致,也就是说decode方法和encode方法的第二个参数值必须是相同的编码格式,在本例中都是UTF-8。

5. 获得解码后的HTTP响应头信息

运行MyChineseHeader程序,在IDE的Console中将会输出如图5.2所示的HTTP响应消息头信息。   从图5.2输出的信息可以看出,NewChinese字段的值已经正确显示了。

02

图5.2 输出正常的HTTP响应头消息