前话说一句: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. JavaScript 流程语句知识脑图

  2. Python3 JSON 数据解析

    JSON (JavaScript Object Notation) 是一种轻量级的数据交换格式.它基于ECMAScript的一个子集. Python3 中可以使用 json 模块来对 JSON 数据进 ...

  3. Dynamics CRM2016 Web Api之分页查询

    在dynamics crm web api还没出现前,我们是通过fetchxml来实现的,当然这种方式依旧可行,那既然web api来了我们就拥抱新的方式. web api中我们通过指定查询的条数来实 ...

  4. sublimetext 自定义build

    Nodejs { "cmd": "node $file", "shell": "true", "selecto ...

  5. hive分区partition(动态和静态分区混合使用; partition的简介)

    分区是hive存放数据的一种方式.将列值作为目录来存放数据,就是一个分区.这样where中给出列值时,只需根据列值直接扫描对应目录下的数据,不扫面其他不关心的分区,快速定位,查询节省大量时间.分动态和 ...

  6. Android底层开发经验

    最近看到一个博客,他的博文虽然是转载的,但源作者肯定对底层的理解可谓是非常透彻,一副思维导图就可以将整个重要体系建立起来,非常适合大家学习.学习不单单只要有代码,生动有趣更重要.在此推荐一波: htt ...

  7. SQLite 分离数据库(http://www.w3cschool.cc/sqlite/sqlite-detach-database.html)

    SQLite 分离数据库 SQLite的 DETACH DTABASE 语句是用来把命名数据库从一个数据库连接分离和游离出来,连接是之前使用 ATTACH 语句附加的.如果同一个数据库文件已经被附加上 ...

  8. Java学习之参数传递详解

    Java中的参数传递问题: 基本类型:形式参数的改变对实际参数没有影响.在参数传递过程中,形参和实参占用了两个完全不同的内存空间. 引用类型:形式参数的改变直接影响实际参数.在参数传递的过程中,形参和 ...

  9. Android应用打破65K方法数限制

    近日,Android Developers在Google+上宣布了新的Multidex支持库,为方法总数超过65K的Android应用提供了官方支持.如果你是一名幸运的Android应用开发者,正在开 ...

  10. API创建员工联系人

    DECLARE ln_contact_rel_id PER_CONTACT_RELATIONSHIPS.CONTACT_RELATIONSHIP_ID%TYPE; ln_ctr_object_ver_ ...