Java核心技术卷2 清单3-7的说明

import java.io.*;
import java.net.*;
import java.nio.file.*;
import java.util.*;

public class Main {

    public static void main(String[] args) throws IOException {
        // write your code here
        String propsFilename = args.length > 0 ? args[0] : "post.properties";
        Properties props = new Properties();
        try (InputStream in = Files.newInputStream(Paths.get(propsFilename)))
        {
            props.load(in);
        }
        String urlString = props.remove("url").toString();
        Object userAgent = props.remove("User-Agent");
        Object redirects = props.remove("redirects");
        CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));
        String result = doPost(new URL(urlString), props,
                userAgent == null ? null : userAgent.toString(),
                redirects == null ? -1 : Integer.parseInt(redirects.toString()));
        System.out.println(result);
    }

    /**
     * Do an HTTP POST.
     * @param url the URL to post to
     * @param nameValuePairs the query parameters
     * @param userAgent the user agent to use, or null for the default user agent
     * @param redirects the number of redirects to follow manually, or -1 for automatic redirects
     * @return the data returned from the server
     */
    public static String doPost(URL url, Map<Object, Object> nameValuePairs, String userAgent, int redirects)
            throws IOException
    {
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        if (userAgent != null)
            connection.setRequestProperty("User-Agent", userAgent);

        if (redirects >= 0)
            connection.setInstanceFollowRedirects(false);

        connection.setDoOutput(true);

        try (PrintWriter out = new PrintWriter(connection.getOutputStream()))
        {
            boolean first = true;
            for (Map.Entry<Object, Object> pair : nameValuePairs.entrySet())
            {
                if (first) first = false;
                else out.print('&');
                String name = pair.getKey().toString();
                String value = pair.getValue().toString();
                out.print(name);
                out.print('=');
                out.print(URLEncoder.encode(value, "UTF-8"));
            }
        }
        String encoding = connection.getContentEncoding();
        if (encoding == null) encoding = "UTF-8";

        if (redirects > 0)
        {
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpURLConnection.HTTP_MOVED_PERM
                    || responseCode == HttpURLConnection.HTTP_MOVED_TEMP
                    || responseCode == HttpURLConnection.HTTP_SEE_OTHER)
            {
                String location = connection.getHeaderField("Location");
                if (location != null)
                {
                    URL base = connection.getURL();
                    connection.disconnect();
                    return doPost(new URL(base, location), nameValuePairs, userAgent, redirects - 1);
                }

            }
        }
        else if (redirects == 0)
        {
            throw new IOException("Too many redirects");
        }

        StringBuilder response = new StringBuilder();
        try (Scanner in = new Scanner(connection.getInputStream(), encoding))
        {
            while (in.hasNextLine())
            {
                response.append(in.nextLine());
                response.append("\n");
            }
        }
        catch (IOException e)
        {
            InputStream err = connection.getErrorStream();
            if (err == null) throw e;
            try (Scanner in = new Scanner(err))
            {
                response.append(in.nextLine());
                response.append("\n");
            }
        }

        return response.toString();
    }
}

关于main函数的说明


此代码清单首先设置了一个Properties类,通过已经设置的post.properties文件得到一个path类,再得到一个InputStream类,使用
properties的load函数来从输入字节流中读取属性列表(键和元素对)。

使用properties的remove函数从map中删除与键key相对应的mapping,并返回这个mapping的值。
接着使用CookieHandler的setDefault方法设置系统范围的cookie处理程序。最后使用doPost函数得到向服务器提交数据表单后得到的
结果(result)。

 

关于doPost函数的说明


此函数执行一个HTTP POST

参数url:将表单数据post到这个url

参数nameValuePairs: 查询参数

参数useragent:要使用的用户代理,或默认空用户代理

参数redirects:手动重定向的数目,或-1表示自动重定向

返回值:返回值是一个String

将url.openConnection()通过强制类型转换 转换为HttpURLConnection。

根据参数useragent和redirects来对connection的属性进行设置。

接着,使用了一个PrintWriter来做一个文本输出对connection.getOutputStream()得到的输出流进行包装,

接着,就使用以下格式将相关的信息附在url的后面:


 

然后,获取从服务器读取的内容,按照服务器的返回的内容的编码格式进行读取,

接着,检查重定向参数redirects,获取响应代码,检查响应代码是否是3个常数之一,是的话,查看location字段是否有值,有的话使用新的url进行重定向。

如果不需要进行重定向,则将结果放在一个StringBuilder中,没有异常,则打印出响应的内容,有异常,抛出异常或打印出输出流的值。
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值