前话说一句:conn.setDefaultRequestProperty(key, value);这个函数是设置属性的,其实可以没有!
 
自己写了一个简单的get,容易控制
public static String callURLtoGet(String strURL) {
try {

            URL url = new URL(strURL);

//            BufferedReader receiver = new BufferedReader(new InputStreamReader(url.openStream()));

            BufferedReader receiver = new BufferedReader(new InputStreamReader(url.openConnection().getInputStream()));

            StringBuffer msg = new StringBuffer();

            char[] data = new char[512];

            int n = 0;

            while ((n = receiver.read(data, 0, 512)) != -1) {

                msg.append(data, 0, n);

            }

            return msg.toString().trim();

        } catch (Exception e) {

            e.printStackTrace();

            return "sdjfaijsdfoiajfjasklfqwh";

        }
}
 
post比较麻烦

public static String sendPost(String strURL) throws Exception {

        URL url = new URL(strURL);

        String result = "";

try {

            HttpURLConnection conn = (HttpURLConnection) url.openConnection();

            conn.setDoOutput(true);

            conn.setDoInput(true);

            conn.setRequestMethod("POST");

            // PrintWriter out = new

            // PrintWriter(httpConn.getOutputStream());//PrintWriter一个打印输出类0,不会自动进行flush和close,继承writer,有多少字符就写多少。

            // 不同于PrintStream类,如System.out这个对象,虽然输出都是write(),但PrintStream会自动进行flush和close,使用outputstream类。

conn.setUseCaches(false);

// conn.setFollowRedirects(true);

            conn.setInstanceFollowRedirects(true);

//            String key = "campaigns";

//            String value = "json";

//            conn.setDefaultRequestProperty(key, value);

            // conn.connect();//

            DataOutputStream out = new DataOutputStream(conn.getOutputStream());// getOutputStream()中隐含的进行了conn.connect;

            // 有乱码可能有问题value;

//            String content = "campaigns=" + "{\"

            JSONObject campaignInfoJSON = new JSONObject();

            campaignInfoJSON = JSONObject.fromObject(content);

            content = "campaigns=" + campaignInfoJSON.toString();

//            content = "campaigns=" + content;

            out.writeBytes(content);

            out.flush();

            out.close();

BufferedReader receiver = new BufferedReader(new InputStreamReader(

                    conn.getInputStream()));

            String line;

            while ((line = receiver.readLine()) != null) {

                result += line;

            }

            receiver.close();

            conn.disconnect();

        } catch (Exception e) {

            e.printStackTrace();

            System.out.println("没有结果!" + e);

        }

// try{

        // URL httpurl = new URL(url);

        // HttpURLConnection httpConn =

        // (HttpURLConnection)httpurl.openConnection();

        // httpConn.setDoOutput(true);

        // httpConn.setDoInput(true);

        // PrintWriter out = new

        // PrintWriter(httpConn.getOutputStream());//PrintWriter一个打印输出类0,不会自动进行flush和close,继承writer,有多少字符就写多少。

        // 不同于PrintStream类,如System.out这个对象,虽然输出都是write(),但PrintStream会自动进行flush和close,使用outputstream类。

        // out.print(param);

        // out.flush();

        // out.close();

        // BufferedReader in = new BufferedReader(new

        // InputStreamReader(httpConn.getInputStream()));

        // String line;

        // while ((line = in.readLine())!= null)

        // {

        // result += line;

        // }

        // in.close();

        // }catch(Exception e){

        // System.out.println("没有结果!"+e);

        // }

        return result;

    }

 
 
 
自己懒得写了,引自网上一个说明,具体说明各个步骤中,函数的内容: 
最常用的Http请求无非是get和post,get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet,post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。

在Java中可以使用HttpURLConnection发起这两种请求,了解此类,对于了解soap,和编写servlet的自动测试代码都有很大的帮助。

下面的代码简单描述了如何使用HttpURLConnection发起这两种请求,以及传递参数的方法:

publicclass
HttpInvoker...{



public
static
final String GET_URL=
"http://localhost:8080/welcome1";



public
static
final String POST_URL=
"http://localhost:8080/welcome1";



public
static
void readContentFromGet()throws IOException...{

// 拼凑get请求的URL字串,使用URLEncoder.encode对特殊和不可见字符进行编码

String getURL= GET_URL
+ "?username="

+ URLEncoder.encode("fat
man","utf-8");

URL getUrl=
new URL(getURL);

// 根据拼凑的URL,打开连接,URL.openConnection函数会根据URL的类型,

// 返回不同的URLConnection子类的对象,这里URL是一个http,因此实际返回的是HttpURLConnection

HttpURLConnection connection= (HttpURLConnection)
getUrl

.openConnection();

// 进行连接,但是实际上get request要在下一句的connection.getInputStream()函数中才会真正发到

// 服务器

connection.connect();

// 取得输入流,并使用Reader读取

BufferedReader reader=
new BufferedReader(new InputStreamReader(

connection.getInputStream()));

System.out.println("=============================");

System.out.println("Contents of get request");

System.out.println("=============================");

String lines;

while
((lines= reader.readLine())!=
null)...{

System.out.println(lines);

}

reader.close();

// 断开连接

connection.disconnect();

System.out.println("=============================");

System.out.println("Contents of get request ends");

System.out.println("=============================");

}



public
static
void readContentFromPost()throws IOException...{

// Post请求的url,与get不同的是不需要带参数

URL postUrl=
new URL(POST_URL);

// 打开连接

HttpURLConnection connection= (HttpURLConnection)
postUrl

.openConnection();

// Output to the connection. Default is

// false, set to true because post

// method must write something to the

// connection

// 设置是否向connection输出,因为这个是post请求,参数要放在

// http正文内,因此需要设为true

connection.setDoOutput(true);

// Read from the connection. Default is true.

connection.setDoInput(true);

// Set the post method. Default is GET

connection.setRequestMethod("POST");

// Post cannot use caches

// Post 请求不能使用缓存

connection.setUseCaches(false);

// This method takes effects to

// every instances of this class.

// URLConnection.setFollowRedirects是static函数,作用于所有的URLConnection对象。

// connection.setFollowRedirects(true);



// This methods only

// takes effacts to this

// instance.

// URLConnection.setInstanceFollowRedirects是成员函数,仅作用于当前函数

connection.setInstanceFollowRedirects(true);

// Set the content type to urlencoded,

// because we will write

// some URL-encoded content to the

// connection. Settings above must be set before connect!

// 配置本次连接的Content-type,配置为application/x-www-form-urlencoded的

// 意思是正文是urlencoded编码过的form参数,下面我们可以看到我们对正文内容使用URLEncoder.encode

// 进行编码

connection.setRequestProperty("Content-Type",

"application/x-www-form-urlencoded");

// 连接,从postUrl.openConnection()至此的配置必须要在connect之前完成,

// 要注意的是connection.getOutputStream会隐含的进行connect。

connection.connect();

DataOutputStream out=
new DataOutputStream(connection

.getOutputStream());

// The URL-encoded contend

// 正文,正文内容其实跟get的URL中'?'后的参数字符串一致

String content=
"firstname="+ URLEncoder.encode("一个大肥人","utf-8");

// DataOutputStream.writeBytes将字符串中的16位的unicode字符以8位的字符形式写道流里面

out.writeBytes(content);



out.flush();

out.close();// flush and close

BufferedReader reader=
new BufferedReader(new InputStreamReader(

connection.getInputStream()));

String line;

System.out.println("=============================");

System.out.println("Contents of post request");

System.out.println("=============================");

while
((line = reader.readLine())!=
null)...{

System.out.println(line);

}

System.out.println("=============================");

System.out.println("Contents of post request ends");

System.out.println("=============================");

reader.close();

connection.disconnect();

}



/**
*//**

*@param args

*/

public
static
void main(String[] args)...{

// TODO Auto-generated method stub

try
...{

readContentFromGet();

readContentFromPost();


} catch (IOException e)...{

// TODO Auto-generated catch block

e.printStackTrace();

}

}



}

上面的readContentFromGet()函数产生了一个get请求,传给servlet一个username参数,值为"fat man"。

readContentFromPost()函数产生了一个post请求,传给servlet一个firstname参数,值为"一个大肥人"。

HttpURLConnection.connect函数,实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection.getInputStream()这个函数里面才正式发送出去。



在readContentFromPost()中,顺序是重中之重,对connection对象的一切配置(那一堆set函数)都必须要在connect()函数执行之前完成。而对outputStream的写操作,又必须要在inputStream的读操作之前。这些顺序实际上是由http请求的格式决定的。



http请求实际上由两部分组成,一个是http头,所有关于此次http请求的配置都在http头里面定义,一个是正文content,在connect()函数里面,会根据HttpURLConnection对象的配置值生成http头,因此在调用connect函数之前,就必须把所有的配置准备好。



紧接着http头的是http请求的正文,正文的内容通过outputStream写入,实际上outputStream不是一个网络流,充其量是个字符串流,往里面写入的东西不会立即发送到网络,而是在流关闭后,根据输入的内容生成http正文。



至此,http请求的东西已经准备就绪。在getInputStream()函数调用的时候,就会把准备好的http请求正式发送到服务器了,然后返回一个输入流,用于读取服务器对于此次http请求的返回信息。由于http请求在getInputStream的时候已经发送出去了(包括http头和正文),因此在getInputStream()函数之后对connection对象进行设置(对http头的信息进行修改)或者写入outputStream(对正文进行修改)都是没有意义的了,执行这些操作会导致异常的发生。

分享到:

java实现http的post和get的更多相关文章

  1. Spark案例分析

    一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...

  2. 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题

    背景起因: 记起以前的另一次也是关于内存的调优分享下   有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...

  3. Elasticsearch之java的基本操作一

    摘要   接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...

  4. 论:开发者信仰之“天下IT是一家“(Java .NET篇)

    比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...

  5. 故障重现, JAVA进程内存不够时突然挂掉模拟

    背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...

  6. 死磕内存篇 --- JAVA进程和linux内存间的大小关系

    运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...

  7. 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用

    有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...

  8. Java多线程基础学习(二)

    9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...

  9. Java多线程基础学习(一)

    1. 创建线程    1.1 通过构造函数:public Thread(Runnable target, String name){}  或:public Thread(Runnable target ...

  10. c#与java的区别

    经常有人问这种问题,用了些时间java之后,发现这俩玩意除了一小部分壳子长的还有能稍微凑合上,基本上没什么相似之处,可以说也就是马甲层面上的相似吧,还是比较短的马甲... 一般C#多用于业务系统的开发 ...

随机推荐

  1. Web缓存(一) - HTTP协议缓存

    为什么要使用 Web 缓存 Web缓存一般分为浏览器缓存.代理服务器缓存以及网关缓存,本文主要讲的是 浏览器缓存,其它两种缓存大家自行去了解下. Web 缓存游走于服务器和客户端之间.这个服务器可能是 ...

  2. 利用Python进行数据分析——重要的Python库介绍

    利用Python进行数据分析--重要的Python库介绍 一.NumPy 用于数组执行元素级计算及直接对数组执行数学运算 线性代数运算.傅里叶运算.随机数的生成 用于C/C++等代码的集成 二.pan ...

  3. webpack4.1.1的使用详细教程

    安装全局webpack cnpm install -g webpack 安装全局webpack-cli npm install -g webpack-cli 初始化:生成package.json文件 ...

  4. MySQL UPDATE 查询

    MySQL UPDATE 查询 如果我们需要修改或更新MySQL中的数据,我们可以使用 SQL UPDATE 命令来操作.. 语法 以下是 UPDATE 命令修改 MySQL 数据表数据的通用SQL语 ...

  5. Docker 网络

    Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair).建议先熟悉了解这两部分的基本概念再阅读本章. 基本原理 首先,要实现网络通信,机器需要 ...

  6. Docker 列出镜像

    使用 docker images 显示本地已有的镜像. $ sudo docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE ubuntu ...

  7. AWS EC2 CentOS release 6.5 部署zookeeper、kafka、dubbo

    AWS EC2 CentOS release 6.5 部署zookeeper.kafka.dubbo参考:http://blog.csdn.net/yizezhong/article/details/ ...

  8. 十大豪门推送sdk,哪个更适合你

    转自:http://jingyan.baidu.com/article/d621e8da0fd7042865913ff5.html 推送,使得开发者可以即时地向其应用程序的用户推送通知或者消息,与用户 ...

  9. Programming In Scala笔记-第四章、类和对象

    类似于Java,Scala中也有类和对象的概念. 一.类.属性和方法 1.类 类是对一类事物的抽象,当一个类被定义后,就可以以该定义为模板,定义该类的一系列对象.比如说有以下一个模板 人类: 有姓名: ...

  10. Hexo 简明教程

    概述 对于个人独立博客的搭建,或者一些产品网站的介绍我个人比较推崇直接用静态网站生成器来完成这个事情,对于,静态网页部署方便,浏览速度快. 以下为部分静态网站生成器简要列表: Ruby Jekyll ...