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中,没有异常,则打印出响应的内容,有异常,抛出异常或打印出输出流的值。