基于客户端和安卓访问HTTP服务器
1.基本使用,简单访问post/getmethod
package clienthttptest;
import java.io.IOException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
public class GetTest {
public static void main(String args[]){
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");
HttpMethod method=getPostmethod();
try {
client.executeMethod(method);
System.out.println(method.getStatusLine());
System.out.println(method.getResponseBodyAsString());
System.out.println(method.getResponseHeader("location"));
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
method.releaseConnection();
}
}
public static HttpMethod getGetmethod(){
return new GetMethod("/simcard.php?simcard=1330227");
}
public static HttpMethod getPostmethod(){
PostMethod post=new PostMethod("/simcard.php");
NameValuePair name1=new NameValuePair("simcard","1330227");
NameValuePair name2=new NameValuePair("","");
NameValuePair name3=new NameValuePair("","");
post.setRequestBody(new NameValuePair[] {name1});
return post;
}
}
2.处理重定向
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost("127.0.0.1", 80, "http");
// 用户重定向
PostMethod get = new PostMethod("/book/redirect.jsp");
try {
client.executeMethod(get);
System.out.println(get.getStatusCode());
// System.out.println(get.getResponseBodyAsString());
Header header = get.getResponseHeader("location");//获取头部信息下一次的url
System.out.println("~~~~~~~~~");
String url = header.getValue();
PostMethod gets = new PostMethod("/book/" + url);
client.executeMethod(gets);
System.out.println(gets.getStatusCode());
// System.out.println(gets.getResponseBodyAsString());
get.releaseConnection();
gets.releaseConnection();
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
3.模拟过程,其实就是将postmethod进行对表单填充域值,获取session等机制
PostMethod postmethod = new PostMethod("/book/servlet/LoginForm");
NameValuePair users_name = new NameValuePair("users_name", "yaoge33");
NameValuePair users_password = new NameValuePair("users_password",
"yaoge33");
NameValuePair yanzhen = new NameValuePair("yanzhen", "0768");
postmethod.setRequestBody(new NameValuePair[] { users_name,
users_password, yanzhen });
try {
client.executeMethod(postmethod);
System.out.println(postmethod.getStatusCode());
System.out.println(postmethod.getResponseBodyAsString());
CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
Cookie[] cookies = cookiespec.match("127.0.0.1", 80, "/book", false,
client.getState().getCookies());
if (cookies.length == 0) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.length; i++) {
System.out.println(cookies[i].toString());
}
}
} catch (HttpException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
postmethod.releaseConnection();
}
4.传递参数主要为jsonarray或者jsonobject
个人觉得传递参数适用json没有什么意思,直接使用get/postmethod就可以了
有用的是接受参数用jsonarray来进行传递
基于jsonarray-->jsonobject处理是最好的,在传递过程中,jsonarray依旧是以某中格式[{jsonobject1},{2},{3}]字符串来进行传递,所以在接收端能够处理此类字符串
可以直接使用jsonarray.fromobject(object o)进行格式化,取出jsonobejct,在取出过程中,不可以直接装换,需要迭代出后以jsonobjetc jso=(jsonobject)object操作,不能直接在jsonarray.toarra()强制装换,这个应该是把强制装换的操作交给jsonobject,而与toarray操作互斥,装换失败
一般的情况下我们都是使用IE或者Navigator浏览器来访问一个WEB服务器,用来浏览页面查看信息或者提交一些数据等等。所访问的这些页面有的仅 仅是一些普通的页面,有的需要用户登录后方可使用,或者需要认证以及是一些通过加密方式传输,例如HTTPS。目前我们使用的浏览器处理这些情况都不会构 成问题。不过你可能在某些时候需要通过程序来访问这样的一些页面,比如从别人的网页中“偷”一些数据;利用某些站点提供的页面来完成某种功能,例如说我们 想知道某个手机号码的归属地而我们自己又没有这样的数据,因此只好借助其他公司已有的网站来完成这个功能,这个时候我们需要向网页提交手机号码并从返回的 页面中解析出我们想要的数据来。如果对方仅仅是一个很简单的页面,那我们的程序会很简单,本文也就没有必要大张旗鼓的在这里浪费口舌。但是考虑到一些服务 授权的问题,很多公司提供的页面往往并不是可以通过一个简单的URL就可以访问的,而必须经过注册然后登录后方可使用提供服务的页面,这个时候就涉及到 COOKIE问题的处理。我们知道目前流行的动态网页技术例如ASP、JSP无不是通过COOKIE来处理会话信息的。为了使我们的程序能使用别人所提供 的服务页面,就要求程序首先登录后再访问服务页面,这过程就需要自行处理cookie,想想当你用java.net.HttpURLConnection 来完成这些功能时是多么恐怖的事情啊!况且这仅仅是我们所说的顽固的WEB服务器中的一个很常见的“顽固”!再有如通过HTTP来上传文件呢?不需要头 疼,这些问题有了“它”就很容易解决了!
我们不可能列举所有可能的顽固,我们会针对几种最常见的问题进行处理。当然了,正如前面说到 的,如果我们自己使用java.net.HttpURLConnection来搞定这些问题是很恐怖的事情,因此在开始之前我们先要介绍一下一个开放源码 的项目,这个项目就是Apache开源组织中的httpclient,它隶属于Jakarta的commons项目,目前的版本是2.0RC2。 commons下本来已经有一个net的子项目,但是又把httpclient单独提出来,可见http服务器的访问绝非易事。
Commons -httpclient项目就是专门设计来简化HTTP客户端与服务器进行各种通讯编程。通过它可以让原来很头疼的事情现在轻松的解决,例如你不再管是 HTTP或者HTTPS的通讯方式,告诉它你想使用HTTPS方式,剩下的事情交给httpclient替你完成。本文会针对我们在编写HTTP客户端程 序时经常碰到的几个问题进行分别介绍如何使用httpclient来解决它们,为了让读者更快的熟悉这个项目我们最开始先给出一个简单的例子来读取一个网 页的内容,然后循序渐进解决掉前进中的所有问题。
1. 读取网页(HTTP/HTTPS)内容
下面是我们给出的一个简单的例子用来访问某个页面
* Created on 2003-12-14 by Liudong
*/
package http.demo;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/**
* 最简单的HTTP客户端,用来演示通过GET或者POST方式访问某个页面
* @author Liudong
*/
public class SimpleClient {
public static void main(String[] args) throws IOException
{
HttpClient client = new HttpClient();
//设置代理服务器地址和端口
//client.getHostConfiguration().setProxy("proxy_host_addr",proxy_port);
//使用GET方法,如果服务器需要通过HTTPS连接,那只需要将下面URL中的http换成https
HttpMethod method = new GetMethod("http://java.sun.com";);
//使用POST方法
//HttpMethod method = new PostMethod("http://java.sun.com";);
client.executeMethod(method);
//打印服务器返回的状态
System.out.println(method.getStatusLine());
//打印返回的信息
System.out.println(method.getResponseBodyAsString());
//释放连接
method.releaseConnection();
}
}
在 这个例子中首先创建一个HTTP客户端(HttpClient)的实例,然后选择提交的方法是GET或者POST,最后在HttpClient实例上执行 提交的方法,最后从所选择的提交方法中读取服务器反馈回来的结果。这就是使用HttpClient的基本流程。其实用一行代码也就可以搞定整个请求的过 程,非常的简单!
2. 以GET或者POST方式向网页提交参数
其实前面一个最简单的示例中我们已经介绍了如何使用GET或者 POST方式来请求一个页面,本小节与之不同的是多了提交时设定页面所需的参数,我们知道如果是GET的请求方式,那么所有参数都直接放到页面的URL后 面用问号与页面地址隔开,每个参数用&隔开,例如:http://java.sun.com?name=liudong&mobile=123456,但是当使用POST方法时就会稍微有一点点麻烦。本小节的例子演示向如何查询手机号码所在的城市,代码如下:
* Created on 2003-12-7 by Liudong
*/
package http.demo;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.*;
/**
* 提交参数演示
* 该程序连接到一个用于查询手机号码所属地的页面
* 以便查询号码段1330227所在的省份以及城市
* @author Liudong
*/
public class SimpleHttpClient {
public static void main(String[] args) throws IOException
{
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost("www.imobile.com.cn", 80, "http");
HttpMethod method = getPostMethod();//使用POST方式提交数据
client.executeMethod(method);
//打印服务器返回的状态
System.out.println(method.getStatusLine());
//打印结果页面
String response = new String(method.getResponseBodyAsString().getBytes("8859_1"));
//打印返回的信息
System.out.println(response);
method.releaseConnection();
}
/**
* 使用GET方式提交数据
* @return
*/
private static HttpMethod getGetMethod(){
return new GetMethod("/simcard.php?simcard=1330227");
}
/**
* 使用POST方式提交数据
* @return
*/
private static HttpMethod getPostMethod(){
PostMethod post = new PostMethod("/simcard.php");
NameValuePair simcard = new NameValuePair("simcard","1330227");
post.setRequestBody(new NameValuePair[] { simcard});
return post;
}
}
在上面的例子中页面http://www.imobile.com.cn/simcard.php需要一个参数是simcard,这个参数值为手机号码段,即手机号码的前七位,服务器会返回提交的手机号码对应的省份、城市以及其他详细信息。GET的提交方法只需要在URL后加入参数信息,而POST则需要通过NameValuePair类来设置参数名称和它所对应的值
3. 处理页面重定向
在JSP/Servlet 编程中response.sendRedirect方法就是使用HTTP协议中的重定向机制。它与JSP中的<jsp:forward …>的区别在于后者是在服务器中实现页面的跳转,也就是说应用容器加载了所要跳转的页面的内容并返回给客户端;而前者是返回一个状态码,这些状态 码的可能值见下表,然后客户端读取需要跳转到的页面的URL并重新加载新的页面。就是这样一个过程,所以我们编程的时候就要通过 HttpMethod.getStatusCode()方法判断返回值是否为下表中的某个值来判断是否需要跳转。如果已经确认需要进行页面跳转了,那么可 以通过读取HTTP头中的location属性来获取新的地址。
状态码
对应HttpServletResponse的常量
详细描述
301
SC_MOVED_PERMANENTLY
页面已经永久移到另外一个新地址
302
SC_MOVED_TEMPORARILY
页面暂时移动到另外一个新的地址
303
SC_SEE_OTHER
客户端请求的地址必须通过另外的URL来访问
307
SC_TEMPORARY_REDIRECT
同SC_MOVED_TEMPORARILY
下面的代码片段演示如何处理页面的重定向
System.out.println(post.getStatusLine().toString());
post.releaseConnection();
//检查是否重定向
int statuscode = post.getStatusCode();
if ((statuscode == HttpStatus.SC_MOVED_TEMPORARILY) ||
(statuscode == HttpStatus.SC_MOVED_PERMANENTLY) ||
(statuscode == HttpStatus.SC_SEE_OTHER) ||
(statuscode == HttpStatus.SC_TEMPORARY_REDIRECT))
{//读取新的URL地址
Header header = post.getResponseHeader("location");
if (header != null) {
String newuri = header.getValue();
if ((newuri == null) || (newuri.equals("")))
newuri = "/";
GetMethod redirect = new GetMethod(newuri);
client.executeMethod(redirect);
System.out.println("Redirect:"+ redirect.getStatusLine().toString());
redirect.releaseConnection();
} else {
System.out.println("Invalid redirect");
} 我们可以自行编写两个JSP页面,其中一个页面用response.sendRedirect方法重定向到另外一个页面用来测试上面的例子。
4. 模拟输入用户名和口令进行登录
本 小节应该说是HTTP客户端编程中最常碰见的问题,很多网站的内容都只是对注册用户可见的,这种情况下就必须要求使用正确的用户名和口令登录成功后,方可 浏览到想要的页面。因为HTTP协议是无状态的,也就是连接的有效期只限于当前请求,请求内容结束后连接就关闭了。在这种情况下为了保存用户的登录信息必 须使用到Cookie机制。以JSP/Servlet为例,当浏览器请求一个JSP或者是Servlet的页面时,应用服务器会返回一个参数,名为 jsessionid(因不同应用服务器而异),值是一个较长的唯一字符串的Cookie,这个字符串值也就是当前访问该站点的会话标识。浏览器在每访问 该站点的其他页面时候都要带上jsessionid这样的Cookie信息,应用服务器根据读取这个会话标识来获取对应的会话信息。
对于 需要用户登录的网站,一般在用户登录成功后会将用户资料保存在服务器的会话中,这样当访问到其他的页面时候,应用服务器根据浏览器送上的Cookie中读 取当前请求对应的会话标识以获得对应的会话信息,然后就可以判断用户资料是否存在于会话信息中,如果存在则允许访问页面,否则跳转到登录页面中要求用户输 入帐号和口令进行登录。这就是一般使用JSP开发网站在处理用户登录的比较通用的方法。
这样一来,对于HTTP的客户端来讲,如果要访问 一个受保护的页面时就必须模拟浏览器所做的工作,首先就是请求登录页面,然后读取Cookie值;再次请求登录页面并加入登录页所需的每个参数;最后就是 请求最终所需的页面。当然在除第一次请求外其他的请求都需要附带上Cookie信息以便服务器能判断当前请求是否已经通过验证。说了这么多,可是如果你使 用httpclient的话,你甚至连一行代码都无需增加,你只需要先传递登录信息执行登录过程,然后直接访问想要的页面,跟访问一个普通的页面没有任何 区别,因为类HttpClient已经帮你做了所有该做的事情了,太棒了!下面的例子实现了这样一个访问的过程。
* Created on 2003-12-7 by Liudong
*/
package http.demo;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.*;
import org.apache.commons.httpclient.methods.*;
/**
* 用来演示登录表单的示例
* @author Liudong
*/
public class FormLoginDemo {
static final String LOGON_SITE = "localhost";
static final int LOGON_PORT = 8080;
public static void main(String[] args) throws Exception{
HttpClient client = new HttpClient();
client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT);
//模拟登录页面login.jsp->main.jsp
PostMethod post = new PostMethod("/main.jsp");
NameValuePair name = new NameValuePair("name", "ld");
NameValuePair pass = new NameValuePair("password", "ld");
post.setRequestBody(new NameValuePair[]{name,pass});
int status = client.executeMethod(post);
System.out.println(post.getResponseBodyAsString());
post.releaseConnection();
//查看cookie信息
CookieSpec cookiespec = CookiePolicy.getDefaultSpec();
Cookie[] cookies = cookiespec.match(LOGON_SITE, LOGON_PORT, "/", false, client.getState().getCookies());
if (cookies.length == 0) {
System.out.println("None");
} else {
for (int i = 0; i < cookies.length; i++) {
System.out.println(cookies[i].toString());
}
}
//访问所需的页面main2.jsp
GetMethod get = new GetMethod("/main2.jsp");
client.executeMethod(get);
System.out.println(get.getResponseBodyAsString());
get.releaseConnection();
}
}
提交XML格式的参数很简单,仅仅是一个提交时候的ContentType问题,下面的例子演示从文件文件中读取XML信息并提交给服务器的过程,该过程可以用来测试Web服务。
import java.io.FileInputStream;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
/**
* 用来演示提交XML格式数据的例子
*/
public class PostXMLClient {
public static void main(String[] args) throws Exception {
File input = new File(“test.xml”);
PostMethod post = new PostMethod(“http://localhost:8080/httpclient/xml.jsp”);
// 设置请求的内容直接从文件中读取
post.setRequestBody(new FileInputStream(input));
if (input.length() < Integer.MAX_VALUE)
post.setRequestContentLength(input.length());
else
post.setRequestContentLength(EntityEnclosingMethod.CONTENT_LENGTH_CHUNKED);
// 指定请求内容的类型
post.setRequestHeader("Content-type", "text/xml; charset=GBK");
HttpClient httpclient = new HttpClient();
int result = httpclient.executeMethod(post);
System.out.println("Response status code: " + result);
System.out.println("Response body: ");
System.out.println(post.getResponseBodyAsString());
post.releaseConnection();
}
}
httpclient使用了单独的一个HttpMethod子类来处理文件的上传,这个类就是MultipartPostMethod,该类已经封装了文件上传的细节,我们要做的仅仅是告诉它我们要上传文件的全路径即可,下面的代码片段演示如何使用这个类。
filePost.addParameter("fileName", targetFilePath);
HttpClient client = new HttpClient();
//由于要上传的文件可能比较大,因此在此设置最大的连接超时时间
client.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
int status = client.executeMethod(filePost);
7. 访问启用认证的页面
我 们经常会碰到这样的页面,当访问它的时候会弹出一个浏览器的对话框要求输入用户名和密码后方可,这种用户认证的方式不同于我们在前面介绍的基于表单的用户 身份验证。这是HTTP的认证策略,httpclient支持三种认证方式包括:基本、摘要以及NTLM认证。其中基本认证最简单、通用但也最不安全;摘 要认证是在HTTP 1.1中加入的认证方式,而NTLM则是微软公司定义的而不是通用的规范,最新版本的NTLM是比摘要认证还要安全的一种方式。
下面例子是从httpclient的CVS服务器中下载的,它简单演示如何访问一个认证保护的页面:
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.methods.GetMethod;
public class BasicAuthenticationExample {
public BasicAuthenticationExample() {
}
public static void main(String[] args) throws Exception {
HttpClient client = new HttpClient();
client.getState().setCredentials(
"www.verisign.com",
"realm",
new UsernamePasswordCredentials("username", "password")
);
GetMethod get = new GetMethod("https://www.verisign.com/products/index.html";);
get.setDoAuthentication( true );
int status = client.executeMethod( get );
System.out.println(status+""+ get.getResponseBodyAsString());
get.releaseConnection();
}
}
多 线程同时访问httpclient,例如同时从一个站点上下载多个文件。对于同一个HttpConnection同一个时间只能有一个线程访问,为了保证 多线程工作环境下不产生冲突,httpclient使用了一个多线程连接管理器的类: MultiThreadedHttpConnectionManager,要使用这个类很简单,只需要在构造HttpClient实例的时候传入即可,代 码如下:
new MultiThreadedHttpConnectionManager();
HttpClient client = new HttpClient(connectionManager);
相关推荐
Feign HTTP Client 是一个声明式的 Web 服务客户端,...通过阅读 "Feign HTTP Client 使用指南 - Tower.pdf",你可以深入理解如何在实际项目中有效地使用 Feign,优化服务间的通信效率,提高代码的可维护性和可扩展性。
在这个例子中,可能的场景是,我们先使用Kettle的转换或作业从数据源中获取地址信息,然后利用REST Client或Http Client组件向地理编码API发送请求,获取对应的经纬度。收到响应后,我们可以解析JSON或其他格式的...
在这个主题中,“HTTP.rar_http linux_http client_http linux_made”可能指的是一个关于在Linux环境下构建和使用HTTP客户端的资源包。下面将详细探讨HTTP协议、Linux环境以及HTTP客户端的相关知识点。 首先,我们...
本篇文章将深入探讨如何使用C#语言实现HTTP代理功能。 一、HTTP代理的工作原理 HTTP代理服务器充当了客户端与目标Web服务器之间的桥梁。当客户端发送请求时,请求首先被发送到代理服务器,然后由代理服务器转发给...
1.在stm32使用lwip协议栈实现http client,完成向客户端定时发送数据 2.实现DNS域名解析操作 3.实现通过DHCP获取DNS服务器地址,可以通过此地址进行域名解析 4.使用MDK5.20编译
在前端开发中,为了与IPFS进行交互,开发者通常会使用`ipfs-http-client`库,这是一个轻量级、易于使用的JavaScript库,它提供了与IPFS节点通信的HTTP API接口。 `ipfs-http-client`库的主要功能包括: 1. **添加...
在实际使用中,你可以根据需求扩展`http_client`类,增加更多的功能,比如支持PUT、DELETE等其他HTTP方法,或者实现更复杂的请求体编码。 源码编译部分,你需要确保系统中安装了必要的编译工具,如GCC或Clang,并且...
要使用 "http-client" 扩展,首先需要通过 Composer 安装。在终端中运行以下命令: ``` composer require php-http/guzzle6-adapter composer require laravel/http-client ``` 然后,在 `config/app.php` ...
总的来说,W5500例程合集HTTP_Client提供了一个实践平台,让我们能亲手实现一个简单的HTTP客户端,从而增强对网络通信和硬件接口控制的理解。通过这个学习过程,开发者可以更好地应对实际工程中的网络通信挑战,为...
Android HTTP客户端 Android Http Client是一个小型库,用于以简单实用的方式向任何Internet服务发出请求。 您可以实现多个接口来管理响应。 它还包括用于管理文件上载和... JSON :Android Http Client使用获取兼容性
在本文中,我们将深入探讨`node_http_client`的相关知识点,包括如何使用`http`模块进行HTTP请求,以及`http_client 1.js`和`http_client 2.js`可能包含的代码示例。 首先,`http`模块提供了`http.request()`方法,...
测试例子可能包括了如何启动服务器、发送请求以及处理响应的示例代码,这对于理解和学习Qt HTTP服务器客户端的使用非常有帮助。 总结来说,Qt http server client提供了完整的HTTP服务端和客户端实现,允许开发者...
"google-http-java-client-1.13.1-beta" 是Google官方发布的一个Java库,主要用于在Android平台上进行HTTP网络通信。这个库包含了丰富的工具类,能够帮助开发者方便地实现各种HTTP请求,从而满足Android应用中的网络...
本篇文章将深入探讨如何使用C++实现一个HTTP客户端,主要基于提供的资源"CHttpClient.rar"。 HTTP(超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从万维网服务器传输超文本到本地浏览器。HTTP客户端则...
支持 MQTT client 客户端。 支持 MQTT server 服务端。 支持 MQTT 遗嘱消息。 支持 MQTT 保留消息。 支持自定义消息(mq)处理转发实现集群。 MQTT 客户端 阿里云 mqtt 连接 demo。 支持 GraalVM 编译成本机...
本篇文章将详细讲解如何使用Java实现HTTP POST客户端和服务器,并探讨相关知识点。 首先,让我们从服务器端开始。在Java中,我们可以使用内置的`HttpServer`类(来自`com.sun.net.httpserver`包)来创建一个简单的...
- 使用时,遵循API的最佳实践,如使用合适的HTTP状态码,正确的数据格式等。 总之,`Restlet Client`是一款强大的REST API测试工具,它为开发者提供了便捷的API测试环境,是进行SpringBoot或其他基于REST架构项目...
(epoll模型)"是指使用HTTP协议构建的服务器和客户端,并且它们采用了Linux下的epoll模型进行I/O多路复用。这个项目显然经过了商业级的压力测试,能够支持文件下载、续传、IPv6通信、页面展示以及HLS(HTTP Live ...