`
8366
  • 浏览: 812903 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

4种调用https服务的方式

阅读更多

 

 

 

     以前在网厅的时候,请求计费的账单开始使用的是httpclient,后来因为性能问题,换成了使用socket 发送http请求的方式,由于计费服务器端使用了redirect ,因此还需要从响应报文中得到Location 中的url,再次发送一次http请求才能完成整个业务逻辑!

 

    Https 资源在访问的时候会让你输入用户名和密码

 

 

   1.使用linux 的curl命令

 

    [root@xhuvm03 ~]# curl -k --basic --user "tcloudadmin:tcloud123" --data "" --header 'Content-Type: application/xml' https://123.124.189.***/api/account.list

 

 

 <Users>
  <User>
    <isAdmin>1</isAdmin>
    <id>f1ebe39d-d0b6-4292-b3cd-774bf945bf63</id>
    <name>tcloudadmin</name>
    <groupId>be2e0f3a-7684-4b8e-b04d-6ee75aa3d099</groupId>
  </User>
  <User>
    <isAdmin>1</isAdmin>
    <id>653d60c5-dc7b-488a-a861-1c67873057fd</id>
    <name>gaoyang</name>
    <groupId>be2e0f3a-7684-4b8e-b04d-6ee75aa3d099</groupId>
  </User>
  <User>
    <isAdmin>1</isAdmin>
    <id>2d393438-9c8f-4704-8dfd-9f00fb7d7d18</id>
    <name>teststorage</name>
    <groupId>be2e0f3a-7684-4b8e-b04d-6ee75aa3d099</groupId>
  </User>
</Users>
[root@xhuvm03 ~]# 

 

-k/--insecure      Allow connections to SSL sites without certs (H)

 --basic         Use HTTP Basic Authentication (H)

 -u/--user <user[:password]> Set server user and password

 -d/--data <data>   HTTP POST data (H)

-H/--header <line> Custom header to pass to server (H)

 

 

 

 

方式2: 使用socket发送http请求字符串到https 服务上

 

 

curl -k --basic --user "tcloudadmin:tcloud123" --data "" --header 'Content-Type: application/xml' https://123.124.189.***/api/account.list -v

 

使用-v 选项可以 看到http请求的过程和内容,可以作为我们拼 Http 请求字符串的依据

 

 

[root@xlhu-linux ~]# curl -k --basic --user "tcloudadmin:tcloud123" --data "" --header 'Content-Type: application/xml' https://123.124.189.196/api/account.list -v
* About to connect() to 123.124.189.xxx port 443
*   Trying 123.124.189.xxx... connected
* Connected to 123.124.189.xxx (123.124.189.xxx) port 443
* successfully set certificate verify locations:
*   CAfile: /etc/pki/tls/certs/ca-bundle.crt
  CApath: none
* SSLv2, Client hello (1):
SSLv3, TLS handshake, Server hello (2):
SSLv3, TLS handshake, CERT (11):
SSLv3, TLS handshake, Server key exchange (12):
SSLv3, TLS handshake, Server finished (14):
SSLv3, TLS handshake, Client key exchange (16):
SSLv3, TLS change cipher, Client hello (1):
SSLv3, TLS handshake, Finished (20):
SSLv3, TLS change cipher, Client hello (1):
SSLv3, TLS handshake, Finished (20):
SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*        subject: /C=TW/ST=Taipei City/L=Taipei/O=Trend Micro/OU=CloudLego/CN=CloudLego
*        start date: 2010-02-03 02:13:59 GMT
*        expire date: 2020-02-01 02:13:59 GMT
*        common name: CloudLego (does not match '123.124.189.xxx')
*        issuer: /C=TW/ST=Taipei City/L=Taipei/O=Trend Micro/OU=CloudLego/CN=CloudLego
* SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'tcloudadmin'
> POST /api/account.list HTTP/1.1
> Authorization: Basic dGNsb3VkYWRtaW46dGNsb3VkMTIz
> User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
> Host: 123.124.189.xxx
> Accept: */*
> Content-Type: application/xml
> Content-Length: 0
> 
< HTTP/1.1 200 OK
< Date: Sun, 16 Jan 2011 11:40:25 GMT
< Server: Apache/2.2.15 (Fedora)
< Vary: Authorization
< Content-Type: text/xml; charset=utf-8
< Connection: close
< Transfer-Encoding: chunked
<Users>
  <User>
    <isAdmin>1</isAdmin>
    <id>f1ebe39d-d0b6-4292-b3cd-774bf945bf63</id>
    <name>tcloudadmin</name>
    <groupId>be2e0f3a-7684-4b8e-b04d-6ee75aa3d099</groupId>
  </User>
  <User>
    <isAdmin>1</isAdmin>
    <id>653d60c5-dc7b-488a-a861-1c67873057fd</id>
    <name>gaoyang</name>
    <groupId>be2e0f3a-7684-4b8e-b04d-6ee75aa3d099</groupId>
  </User>
  <User>
    <isAdmin>0</isAdmin>
    <id>2a228769-3b2d-4d26-b2c8-697c86f78b65</id>
    <name>test1234</name>
    <groupId>ce2666d0-6c95-47f3-a908-cadf333a214e</groupId>
  </User>
  <User>
    <isAdmin>1</isAdmin>
    <id>543ae799-df16-438d-9071-6618f5c09ba3</id>
    <name>test123</name>
    <groupId>be2e0f3a-7684-4b8e-b04d-6ee75aa3d099</groupId>
  </User>
  <User>
    <isAdmin>0</isAdmin>
    <id>3bbc0f32-4490-49fd-8944-751ae28c1073</id>
    <name>elaster-demo</name>
    <groupId>fb86fe86-210a-4242-b157-fce26ba41545</groupId>
  </User>
  <User>
    <isAdmin>0</isAdmin>
    <id>bd2636fa-b92e-47e8-b658-e540e9307839</id>
    <name>test11</name>
    <groupId>a2b2179a-8f96-420a-be59-1cc5d12394e3</groupId>
  </User>
  <User>
    <isAdmin>0</isAdmin>
    <id>4867561a-9566-4740-a3ce-4bf78289490c</id>
    <name>gavin</name>
    <groupId>237b3b70-5d13-4325-a5aa-83a28aabb693</groupId>
  </User>
</Users>
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):
[root@xlhu-linux ~]# 
 

 

 

这种方式调用要求 掌握Http协议的请求 格式,如果请求协议的格式错误,则不能得到正确的返回结果!

必须要知道的:

 

a.

报文都由5个成员组成,其中请求报文的结构如下:
1、第1成员:请求行(Request-Line)或状态行(Status-line)
2、第2成员:通用头(General-Header)
3、第2成员:请求头(Request-Header)
4、第4成员:实体头(Entity-Header)
5、第5成员:实体主体(Entiry-Body)

 

b. 每个请求行都要以 回车换行结尾

c. 协议结束的标志是 2个换行

c. 如果返回的 响应有 location 字段,也就是重定向了 需要我们根据location 字段重新发起请求

 

 

下面是 一个socket 拼接 http请求字符串的 例子

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;

import javax.net.ssl.SSLSocketFactory;


public class SocketHttpsClient
{
    public static void main(String[] args)  throws Exception
    {
    	String url="https://123.124.189.xxx:443/api/vm.list";
    	SSLSocketFactory ssf = (SSLSocketFactory) SSLSocketFactory.getDefault();
    	String reqMsg=getFirestRequestMsg(url);
		Socket socket=null;
		try {
			System.out.println("请求消息:"+reqMsg);
			 socket = ssf.createSocket("123.124.189.xxx", 443);   
			
			PrintWriter tOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
		      tOut.write(reqMsg);
		      tOut.println();
		      tOut.flush();
		      System.out.println("消息发送成功!等待返回结果。。。");

		      BufferedReader tIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		      String tLine = null;
		      StringBuilder sb=new StringBuilder();
		      while ((tLine = tIn.readLine()) != null) {
		        sb.append(tLine).append("\n");
		      }
		      System.out.println("返回内容:"+sb.toString());
		  
		} catch (Exception e) {
			System.out.println(e);
			throw e;
		}finally{
			if(socket!=null){
				socket.close();
			}
		}
	}
	private static String getFirestRequestMsg(String url){
		StringBuilder reqMsg = new StringBuilder("")
		.append("POST ").append("/api/vm.list").append(" HTTP/1.1").append("\r\n")
		.append("Authorization: Basic dGNsb3VkYWRtaW46dGNsb3VkMTIz").append("\r\n")
		.append("User-Agent: curl/7.15.5 (x86_64-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5").append("\r\n")
		.append("Host: ").append("123.124.189.xxx").append("\r\n")
		.append("Accept: */*").append("\r\n")
		.append("Content-Type: application/xml").append("\r\n")
		.append("Content-Length: 0").append("\r\n")
		.append("\r\n")
		.append("\r\n");
		return reqMsg.toString();
	}
	
}
 

 

 

 

 

3. 使用HttpClient,首先直接访问 https://123.124.189.xxx/api/account.list ,使用firefox 的firebug插件拦截http请求和响应

 

 

 

 

package cn.com.xinli.test.httpclient;
import java.io.InputStream;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.PostMethod;

 

public class TestHttps {

 
/**
 * 参考
 * http://wanglei0119.iteye.com/blog/607046
 */
    /**

     * @param args

     */

    public static void main(String[] args) {
    
    	HttpClient httpclient = new HttpClient();    
    	PostMethod postMethod = new PostMethod("https://123.124.189.xxx:443/api/vm.list");
    	NameValuePair[] data = {};

       try {

           postMethod.addRequestHeader("Content-Type","application/xml");

           postMethod.addRequestHeader("Authorization", "basic dGNsb3VkYWRtaW46dGNsb3VkMTIz");

           postMethod.setRequestBody(data);
   
           httpclient.executeMethod(postMethod);
           InputStream insr = postMethod.getResponseBodyAsStream();
           int respInt = insr.read();

            while (respInt != -1) {

                 System.out.print((char) respInt);

                 respInt = insr.read();
            }

       } catch (Exception e) {

           System.out.println(e.getLocalizedMessage());

       } finally {

           postMethod.releaseConnection();

       }
    }
}

 

 

运行这段代码 会报一个错误 unable to find valid certification path to requested target

 

这个文章有解决方案 :

 

http://wanglei0119.iteye.com/blog/607046

 

 

当使用 正确生成的cert 后 httpclient 可以调用到https的服务了

 

 

方式4 :还是使用httpclient ,使用 httpclient的 X509TrustManager 类,这种调用方式不需要客户端制作证书,很方便!

 

 

package com.platform.vmo.elasterAgent.elaster;
import java.io.InputStreamReader;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpClinetTest {
	public static void main(String[] args) throws Exception{
		// First create a trust manager that won't care.
		X509TrustManager trustManager = new X509TrustManager() {
			public void checkClientTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				// Don't do anything.
			}

			public void checkServerTrusted(X509Certificate[] chain,
					String authType) throws CertificateException {
				// Don't do anything.
			}

			public X509Certificate[] getAcceptedIssuers() {
				// Don't do anything.
				return null;
			}

		};
		// Now put the trust manager into an SSLContext.
		SSLContext sslcontext = SSLContext.getInstance("SSL");
		sslcontext.init(null, new TrustManager[] { trustManager }, null);

		// Use the above SSLContext to create your socket factory
		// (I found trying to extend the factory a bit difficult due to a
		// call to createSocket with no arguments, a method which doesn't
		// exist anywhere I can find, but hey-ho).
		SSLSocketFactory sf = new SSLSocketFactory(sslcontext);
		sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

		DefaultHttpClient httpclient = new DefaultHttpClient();
		httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", sf, 443));
		
		
		String requset ="https://180.168.35.140/api/vm.list";
		HttpPost httpPost = new HttpPost(requset);
		String result = "";
		// Execute HTTP request
		httpPost.setHeader("Authorization",	"basic " + "dGNsb3VkYWRtaW46dGNsb3VkMTIz"); 
		httpPost.setHeader("Content-type", "application/xml");

			StringEntity reqEntity;
		
			reqEntity = new StringEntity("");
			httpPost.setEntity(reqEntity);
			HttpResponse response = httpclient.execute(httpPost);
			HttpEntity resEntity = response.getEntity();
			InputStreamReader reader = new InputStreamReader(resEntity.getContent());

			char[] buff = new char[1024];
			int length = 0;
			while ((length = reader.read(buff)) != -1) {
				result += new String(buff, 0, length);
			}
			httpclient.getConnectionManager().shutdown();
			
			System.out.println(">>>:"+result);
		
		
		
		
	}
}
 

 

 

分享到:
评论

相关推荐

    WebService调用的几种方式

    此外,CXF还支持动态客户端,允许在运行时发现并调用服务。 3. HttpClient:Apache HttpClient是一个通用的HTTP客户端库,虽然不是专门设计用于调用Web服务,但可以用于构建自定义的SOAP或REST请求。使用HttpClient...

    WebService服务的三种调用方式

    ### WebService服务的三种调用方式 在现代软件开发中,WebService作为一种标准的服务提供机制,在分布式系统中的应用非常广泛。本文将详细介绍基于SOAP协议的远程WebService服务的三种常见调用方式,帮助开发者根据...

    三种方式实现java远程调用(rmi),绝对可用

    在提供的压缩包文件中,"三种方式(原始方式_spring_jndi)实现java远程调用(rmi)"包含了相关的示例代码,帮助开发者理解并实践这三种RMI实现方法。在MyEclipse或其他Java开发环境中导入这些代码,可以进行调试和...

    PB 调用webservice 几种方式

    Web服务提供了一种标准的方式,让不同应用程序之间能够交换数据和执行功能。在PB 11.5中,有几种方法可以实现对Web服务的调用,以下将详细介绍这些方法。 1. **SOAP Toolkit**: PB 11.5包含了对SOAP(简单对象...

    Java中如何通过https调用Webservice接口_测试环境.rar

    在Java开发中,HTTPS(Hypertext Transfer Protocol Secure)调用Web Service接口是常见的网络通信方式,主要用于确保数据传输的安全性。本主题将详细讲解如何在Java环境下通过HTTPS协议来安全地调用Web Service接口...

    Java通过Jolt调用Tuxedo服务

    首先,Jolt 是 BEA Tuxedo 自带的一个组件,它提供了一种方式让 Java 应用程序能够与 Tuxedo 服务进行交互。Jolt 包含一组 Java 类库,使得开发者能够在 Java 代码中调用 Tuxedo 的服务,而无需编写 C 语言的客户端...

    cloud 分布式微服务 服务互相注册调用 服务调用方式

    4. Service Mesh:如Istio、Linkerd等,是一种更高级的服务间通信方式,它将网络通信逻辑下沉到代理层,服务间通信由Sidecar代理完成,简化了服务治理,提高了透明性和安全性。 理解并熟练运用这些技术对于构建高效...

    绑定服务调用服务里的方法

    在某些场景下,我们需要与服务进行更紧密的交互,比如调用服务中的特定方法,这时就需要使用到“绑定服务”(Bound Service)。本篇文章将详细介绍如何通过`bindService`方法来实现这一功能。 ### 1. 绑定服务的...

    C#.net 动态调用web服务

    通过实例化该类,并设置其`Url`属性为Web服务的地址,然后调用服务的相应方法即可。 5. **使用`System.ServiceModel`命名空间**:在.NET Framework 3.0及以后版本中,推荐使用`System.ServiceModel`命名空间下的类...

    四种方式调用webservice

    【四种方式调用WebService】 在IT领域,WebService是一种基于开放标准的互联网协议,它允许不同系统之间进行数据交换。本文将详细介绍四种不同的方法来调用WebService,这些方法涵盖了多种编程环境和技术栈。 1. *...

    远程调用服务框架

    本篇文章将深入探讨“远程调用服务框架”,包括其原理、实现方式以及Spring框架如何封装各种远程调用技术。 首先,Spring框架以其模块化和灵活性而著名,它提供了一个统一的编程模型,使得开发者能够轻松地集成不同...

    WPF调用WCF服务

    2. **实例化服务代理**:在需要调用服务的地方,通过代理类的实例来访问服务方法。 3. **调用服务方法**:调用代理类的方法,执行服务器端的业务逻辑。 4. **处理返回结果**:接收服务返回的数据,并在WPF界面中显示...

    C# 调用WCF服务例程

    3. 使用服务:通过代理类调用服务方法。 4. 关闭连接:确保在完成通信后关闭通道和代理。 **高级话题** - **数据契约(Data Contracts)**:用于序列化和反序列化数据,确保客户端和服务之间的数据交换一致性。 - ...

    UE4蓝图调用C++函数的工程分享

    在UE4(Unreal Engine 4)中,开发者可以结合蓝图和C++代码来构建游戏逻辑,这提供了灵活...通过理解并熟练运用这两种调用方式,开发者可以更好地设计和实现游戏的各种功能,同时享受到UE4提供的强大工具集带来的优势。

    .NET调用JAVA web 服务

    4. 调用服务方法:通过代理类实例调用对应的Web服务方法,传递参数,并处理返回的结果。 5. 错误处理:添加适当的异常处理代码,处理可能出现的网络问题或服务端错误。 四、跨平台考虑 由于.NET和Java运行在不同的...

    windows服务调用DLL

    本示例聚焦于如何在Windows服务中调用动态链接库(DLL),这是一种常见的编程实践,可以将可重用的函数封装在单独的模块中,供多个程序共享。 首先,我们要理解DLL的工作原理。DLL文件包含可执行代码和数据,这些...

    使用C#创建webservice及三种调用方式

    本篇将详细讲解如何使用C#创建Web服务以及三种调用Web服务的方式。 一、创建Web服务 1. **设置项目和引用**: 首先,你需要在Visual Studio中创建一个新的ASP.NET Web应用项目,选择“Web服务(.NET Framework)”...

    java调用C#开发的web服务

    它是调用Web服务的标准方式,允许不同语言和平台之间的互操作性。 5. **Java客户端生成**:Java开发者可以使用WSDL(Web服务描述语言)文件生成客户端代理类,该类封装了调用Web服务的所有细节。WSDL文件通常由Web...

    C# 调用Bartender打印的2种方式

    在实际开发中,根据项目需求和复杂性,可以选择适合的调用方式。对于简单的打印任务,直接调用可能更为简洁;而对于复杂的场景,如需要动态生成数据、多任务调度等,间接调用(批处理文件)可能更为灵活。在使用...

    android服务的开启方式及调用服务中的方法的实现

    4. **客户端调用**:在需要调用服务方法的组件中,通过`bindService()`方法建立连接,并实现`ServiceConnection`接口处理连接状态变化。 ```java ServiceConnection connection = new ServiceConnection() { @...

Global site tag (gtag.js) - Google Analytics