简约之美Jodd-http--应用一箩筐

标签: jodd http 应用 | 发表时间:2015-07-11 10:59 | 作者:
出处:http://m635674608.iteye.com

Jodd-http是一个微型的、简约的http client,然而简单而且方便。使用它可以轻松的实现发送请求和读取响应。它的目标就是日常应用变的非常简单,从而简化开发人员的工作。

了解Jodd-http的最好方法就是示例程序。

简单的GET方法

    HttpRequest httpRequest = HttpRequest.get("http://jodd.org");
    HttpResponse response = httpRequest.send();

    System.out.println(response);

上述代码实现了一个get请求,并打印出响应结果。

我们看一下响应结果:

HTTP/1.1 200 OK
Date: Fri, 12 Jun 2015 02:43:50 GMT
Server: Apache
Last-Modified: Mon, 25 May 2015 21:44:44 GMT
Accept-Ranges: bytes
Content-Length: 14056
Cache-Control: max-age=0, public
Expires: Fri, 12 Jun 2015 02:43:50 GMT
Vary: Accept-Encoding
Connection: close
Content-Type: text/html; charset=utf-8

<!DOCTYPE html>
<html>
<head>
..................................
...................................
</body>
</html>

请结合下图理解

wKiom1MpmHWALc2UAADu14JLceA655.jpg

你也可以这么写:

    HttpResponse response = HttpRequest.get("http://jodd.org").send();

    System.out.println(response);

或者一步步构建:

    HttpRequest request = new HttpRequest();
    request
        .method("GET")
        .protocol("http")
        .host("srv")
        .port(8080)
        .path("/api/jsonws/user/get-user-by-id");

好吧,了解一下请求的样式吧:

wKioL1MpX-qwK1-PAAExXPRpR8M814.jpg

读取响应报文

   发送消息后,响应报文存放在HttpResponse实例中,可以调用HttpResponse的方法获取statusCode、 statusPhrase或者报文头属性。

  读取报文本身的方法主要有三种:

  body()--通常是ISO-8859-1编码格式的基本报文内容。

  bodyText()--根据报文头"Content-Type"属性值的编码格式编译的报文。

  BodyByte()--以字节数组形式返回的基本报文,例如下载一个要保存的文件。

注意:在使用bodyText()方法前,必须使用charset()方法指定编码格式。

查询参数

在get方法中,查询参数可以在url中指定(需要正确的编码),如:

    HttpResponse response = HttpRequest
        .get("http://srv:8080/api/jsonws/user/get-user-by-id?userId=10194")
        .send();

或者通过query()方法设置,如:

    HttpResponse response = HttpRequest
        .get("http://srv:8080/api/jsonws/user/get-user-by-id")
        .query("userId", "10194")
        .send();

设置一个参数可以使用query()方法,或者每个参数调用一次query()方法。

当然也可以使用Map<String,String>做为一个参数进行传参。

注意:查询参数(报文头或者表单参数)可以重复的。内部它们存储在数组中。使用removeQuery方法来删除参数或者多次调用query方法来替换参数。

query还可以读取所有内部参数:

    Map<String, Object[]> httpParams = request.query();
    httpParams.put("userId", new String[] {"10194"});

基本认证

基本认证非常简单:

request.basicAuthentication("test", "test");

post方法和表单参数

和get方法中的query类似:

    HttpResponse response = HttpRequest
        .post("http://srv:8080/api/jsonws/user/get-user-by-id")
        .form("userId", "10194")
        .send();

可以看出,在post方法中使用form来指定表单参数。form使用方法和query的使用方法完全相同。

上传文件

同样,也非常容易,只需要将文件增加到form参数中。示例如下:

    HttpRequest httpRequest = HttpRequest
        .post("http://srv:8080/api/jsonws/dlapp/add-file-entry")
        .form(
            "repositoryId", "10178",
            "folderId", "11219",
            "sourceFileName", "a.zip",
            "mimeType", "application/zip",
            "title", "test",
            "description", "Upload test",
            "changeLog", "testing...",
            "file", new File("d:\\a.jpg.zip")
        );

    HttpResponse httpResponse = httpRequest.send();

上面就是全部代码了。

监控文件上传进度

  上传大文件时,需要监控上传进度。 HttpProgressListener提供了这种功能:

    HttpResponse response = HttpRequest
        .post("http://localhost:8081/hello")
        .form("file", file)
        .monitor(new HttpProgressListener() {
            @Override
            public void transferred(long len) {
                System.out.println(len/size);
            }
        })
        .send();

  在文件上传前, HttpProgressListener计算出callbackSize---每次要传输的文件块的字节数。默认情况下为整个文件的1%大小。一般情况下,不会少于512字节。

  HttpProgressListener包含了一个内部成员size,代表了整个请求的大小。注意:整个请求的size不仅仅是文件,它是整个要发送的请求的真实字节数,通常比大文件的size要大一些(参见请求报文格式)。

报文头

增加或者获取报文头参数,可以使用header()方法。一些通用的报文头参数已经定义好了,因此你可以通过contentType()等类似方法来查询。

压缩、解压报文

使用unzip()解压报文示例

    HttpResponse response = HttpRequest
        .get("http://www.liferay.com")
        .acceptEncoding("gzip")
        .send();

    System.out.println(response.unzip());

使用body方法

可以手动设置请求报文的内容--有时,一些api允许在body内指明类似的命令:

    HttpResponse response = HttpRequest
        .get("http://srv:8080/api/jsonws/invoke")
        .body("{'$user[userId, screenName] = /user/get-user-by-id' : {'userId':'10194'}}")
        .basicAuthentication("test", "test")
        .send();

设置body后可以摒弃上面form()方法来设置参数。

然而,在HttpResponse中使用body()方法去接收报文内容,这样更有意义。

字符和编码格式

  默认情况下,query和form参数使用utf-8编码。全局上可以通过JoddHttp来重新设置,或者局部如下所示:

    HttpResponse response = HttpRequest
        .get("http://server/index.html")
        .queryEncoding("CP1251")
        .query("param", "value")
        .send();

当然,可以使用类似的方式设置form的编码格式。进而,表单提交时检测报文头"Content-type"中的值,若存在,将使用该值。接收报文时,body()方法通常返回ISO-8859-1编码格式的报文,若要返回指定的格式,可以使用bodyText()方法,此时需要预先设置编码格式"Content-type"的值。

HttpConnection

  HttpConnection是封装了http物理通信的接口,调用send()方法时,http将open()一个连接(不存在该连接时)。内部里,HttpConnectionProvier创建该连接。参见上篇文章( 简约之美Jodd-http--深入源码理解http协议).默认的连接提供者是基于socket的,它通常返回一个新创建的SocketHttpConnection实例,该实例简单包装了一个打开的socket。也可以使用自定义的HttpConnectionProvider,例如你可以扩展SocketHttpConnectionProvider,重写createSocket()方法,让其从socket池中返回socket或者返回不同过期时间的socket。

Socket

  如上所述,http通信通过普通的socket来完成。因此在发送数据前可以改变socket的行为,下面示例展示了http如何改变socket行为。

SocketHttpConnection

  通过httpConnection调用socket:

    HttpRequest request = HttpRequest.get()...;
    request.open();
    SocketHttpConnection httpConnection =
        (SocketHttpConnection) request.httpConnection();
    Socket socket = httpConnection.getSocket();
    socket.setSoTimeout(1000);
    ...
    HttpResponse response = request.send();

SocketHttpConnectionProvider

  另外一种方法是SocketHttpConnectionProvider,创建自己的provider:

    public class MyConnectionProvider extends SocketHttpConnectionProvider {
        protected Socket createSocket(
                SocketFactory socketFactory, String host, int port)
                throws IOException {
            Socket socket = super.createSocket(socketFactory, host, port);
            socket.setSoTimeout(1000);
            return socket;
        }
    }

然后使用open方法获取socket

    HttpConnectionProvider connectionProvider = new MyConnectionProvider();
    ...
    HttpRequest request = HttpRequest.get()...;
    HttpResponse response = request.open(connectionProvider).send();

若要设置自定义的connectionProvider的默认ConnectionProvider而适用于所有的通信,只需要将它赋给JoddHttp.httpConnectionProvider就不必显式调用open()方法。

持久连接(keep-alive)

  默认情况下,所有的连接时关闭的。http允许通设置连接为keep-alive模式从而使连接一直存在。在keep-alive模式下,在通信会话中,第一次请求时打开一个HttpConnection,以后重用该连接;若非必要,socket不会再次打开,因而可以被多个request重复使用。

File:HTTP persistent connection.svg

  有许多方法可以做到,但最简单的方法如下所示:

        HttpRequest request = HttpRequest.get("http://jodd.org");
        HttpResponse response = request.connectionKeepAlive(true).send();

        // next request
        request = HttpRequest.get("http://jodd.org/jodd.css");
        response = request.keepAlive(response, true).send();

        ...

        // last request
        request = HttpRequest.get("http://jodd.org/jodd.png");
        response = request.keepAlive(response, false).send();

        // optionally
        //response.close();

代理

  HttpConnectionProvider支持代理,只需要提供指明代理信息(类型、地址、端口、用户名、密码)的ProxyInfo实例即可。支持HTTP/SOCKS4/SOCKET5三种类型,其区别是:

SOCKS:防火墙安全会话转换协议 (Socks:Protocol for sessions traversal across firewall securely) Socks 协议提供一个框架,在 TCP 和 UDP 域中的客户机/服务器应用程序能更方便安全地使用网络防火墙所提供的服务。这个协议从概念上来讲是介于应用层和传输层之间的 “中介层(shim-layer)”,所以不提供传递 ICMP 信息之类的网络层网关服务。
Socks4和Socks5都属于Socks协议,只是由于所支持的具体应用不同而存在差异。
Socks4代理只支持TCP应用,而Socks5代理则可以支持TCP和UDP两种应用。不过由于Socks5代理还支持各种身份验证机制,服务器端域名解析等;而Socks4代理没有,所以通常对外开放的 Socks代理都是Socks4代理。因此,UDP应用通常都不能被支持。也就是说,Socks4能做的Socks5都可以做,而socks5能做的,Socks4不一定都可以做。

 输入流解析

   HttpRequest和HttpResponse都实现了读取输入流的方法readFrom(InputStream)。下面举例说明服务器如何读取请求。

HttpBrowser

   当需要通过改变目标地址来模拟一下"移动"的场景时,仅仅发送请求、接收响应是不够。例如登陆需要在当前session内读取不同目标地址的内容。

  HttpBrowser能完成这种功能。它发送请求,自动处理301和302跳转,从响应报文中读取cookies存到新的请求报文中等等。简单示例如下:

    HttpBrowser browser = new HttpBrowser();

    HttpRequest request = HttpRequest.get("www.facebook.com");
    browser.sendRequest(request);

    // request is sent and response is received

    // process the page:
    String page = browser.getPage();

    // create new request
    HttpRequest newRequest = HttpRequest.post(formAction);

    browser.sendRequest(newRequest);

HttpTunnel

   jodd-http提供了一个灵活的构建http隧道的方法(简单代理和目的地址的隧道),HttpTunnel实现了此功能。

参考文献:

【1】 http://jodd.org/doc/http.html

【2】http://www.it165.net/admin/html/201403/2541.html

【3】http://www.cnblogs.com/skynet/archive/2010/12/11/1903347.html

【4】http://www.ccproxy.com/socks4-yu-socks5-de-qu-bie-jie-shao.htm

 

http://www.cnblogs.com/davidwang456/p/4571327.html



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [jodd http 应用] 推荐:

简约之美Jodd-http--应用一箩筐

- - zzm
Jodd-http是一个微型的、简约的http client,然而简单而且方便. 使用它可以轻松的实现发送请求和读取响应. 它的目标就是日常应用变的非常简单,从而简化开发人员的工作. 了解Jodd-http的最好方法就是示例程序. 上述代码实现了一个get请求,并打印出响应结果. 好吧,了解一下请求的样式吧:.

HTTP 204和205的应用

- robin - 风雪之隅
作者: Laruence(. 本文地址: http://www.laruence.com/2011/01/20/1844.html. 之前和人讨论过这个问题,,, 今天感冒在家休息, 就回忆了一下, 整理如下.. 我们很多的应用在使用Ajax的时候, 大多数情况都是询问型操作, 比如提交数据, 则Ajax只是期待服务器返回:.

Java常用工具包 Jodd

- - Java - 编程语言 - ITeye博客
Jodd 是一个开源的 Java 工具集, 包含一些实用的工具类和小型框架. Jodd 被分成众多模块,按需选择,其中. jodd-core        一些工具类,包括. Fast buffers等等. jodd-bean        BeanUtil以及类型检查转换工具. jodd-props       更强大的Java Properties替代.

HTTP幂等性概念和应用

- rockmaple - 酷壳 - CoolShell.cn
[ 感谢 Todd 同学投递本文 ]. 基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式. 无论是在大型互联网应用还是企业级架构中,我们都见到了越来越多的SOA或RESTful的Web API. 为什么Web API如此流行呢. 我认为很大程度上应归功于简单有效的HTTP协议.

Jodd - 不仅仅是个工具包

- - Java - 编程语言 - ITeye博客
Jodd - 不仅仅是个工具包. TypeConverter 一个强大的类型转换工具. BeanUtil 高效的Bean工具,支持嵌套的属性,以及标准的集合类. JDateTime 增强的时间类. IO 快速高性能的各种Buffer、Writer、OutputStream. Wildcard 通配符工具.

HTTP中的ETag在移动客户端的应用

- - SegmentFault 最新的文章
绝大多数移动客户端在设计网络模块时,都会选用HTTP作为客户端和服务端通信的网络协议. 随着业务的不断发展以及用户量的持续增长,整个客户端的稳定性和性能会逐渐成为关注的焦点,其中网络的性能优化更是重中之重,本文介绍的 ETag 缓存技术,可以在缓存数据的同时做到数据的实时更新,适用于对数据实效性要求较高的业务.

HTTP Headers 入门

- johnny - Time Machine
非常感谢 @ytzong 同学在twitter上推荐这篇文章,原文在此. 本文系统的对HTTP Headers进行了简明易懂的阐述,我仅稍作笔记. 什么是HTTP Headers. HTTP是“Hypertext Transfer Protocol”的所写,整个万维网都在使用这种协议,几乎你在浏览器里看到的大部分内容都是通过http协议来传输的,比如这篇文章.

HTTP基础

- - ITeye博客
HTTP的结构主要包括下面几个要点:. HTTP的版本主要有1.0,1.1 和更高版本.    1.1 及以上版本允许在一个TCP连接上传送多个HTTP协议,1.0能 .    1.1 及以上版本多个请求和响应可以重叠,1.0不能.    1.1 增加了很多的请求头和响应头.     一个请求行,若干小心头,以及实体内容,其中的一些消息头和实体内容是可选的,消息头和实体内容需要空行隔开.

HTTP Header 详解

- - 博客园_Ruby's Louvre
HTTP(HyperTextTransferProtocol)即超文本传输协议,目前网页传输的的通用协议. HTTP协议采用了请求/响应模型,浏览器或其他客户端发出请求,服务器给与响应. 就整个网络资源传输而言,包括message-header和message-body两部分. 首先传递message- header,即 http header消息.

基于HTTP缓存轻松实现客户端应用的离线支持及网络优化

- - Oasis Feng
常规的客户端应用开发实践中,为了支持离线特性,往往需要引入本地数据存储并增加相应的『离线状态』逻辑分支. 本地存储的大量使用对数据结构的前后向兼容设计提出了很高的要求,一旦考虑不足,往往不得不引入复杂的版本间数据升降级处理,进一步加剧开发和维护成本. 而且针对『离线』与『在线』状态这两条并行的处理分支,对业务逻辑的清晰性和可维护性有一定的破坏,常常容易在后续开发中造成处理遗漏,给测试和维护带来更多的痛苦.