`
meiyx
  • 浏览: 183738 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

HttpClient and keytool用法

阅读更多
JDK工具KEYTOOL常用命令
-genkey         在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书
-alias          产生别名
-keystore       指定密钥库的名称(产生的各类信息将不在.keystore文件中
-keyalg         指定密钥的算法  
-validity       指定创建的证书有效期多少天
-keysize        指定密钥长度
-storepass      指定密钥库的密码
-keypass        指定别名条目的密码
-dname          指定证书拥有者信息例如:     "CN=firstName,OU=org,O=bj,L=bj,ST=gd,C=cn"
-list           显示密钥库中的证书信息         keytool -list -v -keystore 别名 -storepass ....
-v              显示密钥库中的证书详细信息
-export         将别名指定的证书导出到文件     keytool -export -alias 别名 -file 文件名.crt
-file           参数指定导出到文件的文件名
-delete         删除密钥库中某条目             keytool -delete -alias 别名 -keystore sage
-keypasswd      修改密钥库中指定条目口令       keytool -keypasswd -alias 别名 -keypass .... -new .... -storepass ... -keystore 别名
-import         将已签名数字证书导入密钥库     keytool -import -alias 别名 -keystore 证书名-file 文件名(可以加.crt 后缀)

1.服务器中生成证书:(注:生成证书时,CN要和服务器的域名相同,如果在本地测试,则使用localhost)
生成证书
keytool -genkey -keystore 文件名(可包含路径) -keyalg rsa -alias 别名 -validity 有效期
keytool -genkey -alias jboss -keyalg RSA -keystore d:\mykeystore -dname "CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN" 
-keystore d:\mykeystore  中的路径和名字有自己制定,提示密码设定也有自己定义例如你可以输入111111.
CN为你的域名
OU为你的组织单位名称
O为你的组织名称
L为你所在的城市名称
S为你所在的省份名称
C为你的国家名称

2 查看证书
keytool -list -v -keystore 路径
keytool -list -v -keystore d:\mykeystore

3 修改密码
keytool -keypasswd -alias 别名 -keypass 旧密码 -new 新密码

4 导出证书,由客户端安装
导出的证书文件是以二进制编码文件,无法用文本编辑器正确显示,可以加上 -rfc参数以一种可打印的编者编码输出。
keytool -export -alias 别名 -keystore 证书名 -rfc -file 文件名(可包含路径)
keytool -export -alias jboss-keystore d:\mykeystore  -rfc -file d:\mykeystore.cer (这一步也可以通过浏览器客户端操作前提是服务器已经配置好)

5 客户端配置:为客户端的JVM导入密钥(将服务器下发的证书导入到JVM中)
keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -file d:\mycerts.cer -storepass changeit

6 查看时客户端是否安装成功
keytool -list -v -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -alias tomcat 不指定别名会把"%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS“下的证书都打印出来
7 删除密钥库中的条目
keytool -delete -alias Tomcat -keystore "JAVA_HOME%/JRE/LIB/SECURITY/CACERTS"

以上操作是有关证书的生成和导入
证书导入到我们电脑中的JAVA_HOME%/JRE/LIB/SECURITY/CACERTS密钥库后。客户端就可以在本地通过HttpClient以https的形式访问客户端了,在写httpClient code之前需告诉大家服务器端的配置。
A、 服务器一般是在生成keystore后例如上面的1操作后会整合jboss或tomcat

B、整合JBOSS(jboss-5.1.0.GA)
(一)将产生的mycerts放到JbossHOME\server\default\conf下 
(二)打开JbossHOME\server\default\deploy\jbossweb.sar\server.xml,修改如下配置: 


Java代码 
1.<!-- SSL/TLS Connector configuration using the admin devl guide keystore   
2.        <Connector port="8443" address="${jboss.bind.address}"        
3.        maxThreads="100" strategy="ms" maxHttpHeaderSize="8192"        
4.        emptySessionPath="true"        
5.        scheme="https" secure="true" clientAuth="false"          
6.        keystoreFile="${jboss.server.home.dir}/conf/mycerts"    
7.        keystorePass="rmi+ssl" sslProtocol = "TLS" />   
8.    -->   
9.    
      <Connector protocol="HTTP/1.1" SSLEnabled="true" 
           port="8443" address="${jboss.bind.address}"
           scheme="https" secure="true" clientAuth="false" 
           keystoreFile="${jboss.server.home.dir}/conf/mycerts"
           keystorePass="111111" sslProtocol = "TLS" />


此时基本配置已经完成。

C、在myeclipse中新建一个WEB工程keytest,启动JBOSS,浏览器地址栏输入http://localhost:8080/keytest 或 https://localhost:8443/keytest都可访问则表示JBoss配置成功。成功会提示安装证书。
根据提示导出证书xx.cer文件。客户端浏览网址https://id:8443/keytest同样会有提示
不过导出的可能是crt文件在,之后双击根据提示生成cer文件。
D、 操作客户端配置:为客户端的JVM导入密钥(将服务器下发的证书即生成的cer文件导入到JVM中)
keytool -import -trustcacerts -alias tomcat -keystore "%JAVA_HOME%/JRE/LIB/SECURITY/CACERTS" -file d:\XX.cer -storepass changeit.
之后就可以在客户端代码code了
E、HttpClient 基本功能的使用


GET 方法

使用 HttpClient 需要以下 6 个步骤:

1. 创建 HttpClient 的实例

2. 创建某种连接方法的实例,在这里是 GetMethod。在 GetMethod 的构造函数中传入待连接的地址

3. 调用第一步中创建好的实例的 execute 方法来执行第二步中创建好的 method 实例

4. 读 response

5. 释放连接。无论执行方法是否成功,都必须释放连接

6. 对得到后的内容进行处理

根据以上步骤,我们来编写用GET方法来取得某网页内容的代码。

•大部分情况下 HttpClient 默认的构造函数已经足够使用。 HttpClient httpClient = new HttpClient();
 


•创建GET方法的实例。在GET方法的构造函数中传入待连接的地址即可。用GetMethod将会自动处理转发过程,如果想要把自动处理转发过程去掉的话,可以调用方法setFollowRedirects(false)。 GetMethod getMethod = new GetMethod("https://id:8443/keytest/list");
 


•调用实例httpClient的executeMethod方法来执行getMethod。由于是执行在网络上的程序,在运行executeMethod方法的时候,需要处理两个异常,分别是HttpException和IOException。引起第一种异常的原因主要可能是在构造getMethod的时候传入的协议不对,比如不小心将"http"写成"htp",或者服务器端返回的内容不正常等,并且该异常发生是不可恢复的;第二种异常一般是由于网络原因引起的异常,对于这种异常 (IOException),HttpClient会根据你指定的恢复策略自动试着重新执行executeMethod方法。HttpClient的恢复策略可以自定义(通过实现接口HttpMethodRetryHandler来实现)。通过httpClient的方法setParameter设置你实现的恢复策略,本文中使用的是系统提供的默认恢复策略,该策略在碰到第二类异常的时候将自动重试3次。executeMethod返回值是一个整数,表示了执行该方法后服务器返回的状态码,该状态码能表示出该方法执行是否成功、需要认证或者页面发生了跳转(默认状态下GetMethod的实例是自动处理跳转的)等。 //设置成了默认的恢复策略,在发生异常时候将自动重试3次,在这里你也可以设置成自定义的恢复策略
getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, 
        new DefaultHttpMethodRetryHandler()); 
//执行getMethod
int statusCode = client.executeMethod(getMethod);
if (statusCode != HttpStatus.SC_OK) {
  System.err.println("Method failed: " + getMethod.getStatusLine());
}
 


•在返回的状态码正确后,即可取得内容。取得目标地址的内容有三种方法:第一种,getResponseBody,该方法返回的是目标的二进制的byte流;第二种,getResponseBodyAsString,这个方法返回的是String类型,值得注意的是该方法返回的String的编码是根据系统默认的编码方式,所以返回的String值可能编码类型有误,在本文的"字符编码"部分中将对此做详细介绍;第三种,getResponseBodyAsStream,这个方法对于目标地址中有大量数据需要传输是最佳的。在这里我们使用了最简单的getResponseBody方法。 byte[] responseBody = method.getResponseBody();
 


•释放连接。无论执行方法是否成功,都必须释放连接。 method.releaseConnection();
 


•处理内容。在这一步中根据你的需要处理内容,在例子中只是简单的将内容打印到控制台。 System.out.println(new String(responseBody));
 


下面是程序的完整代码,这些代码也可在附件中的test.GetSample中找到。


package test;
import java.io.IOException;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
public class GetSample{
  public static void main(String[] args) {
  //构造HttpClient的实例
  HttpClient httpClient = new HttpClient();
  //创建GET方法的实例
  GetMethod getMethod = new GetMethod("https://id:8443/keytest/list");
  //使用系统提供的默认的恢复策略
  getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
    new DefaultHttpMethodRetryHandler());
  try {
   //执行getMethod
   int statusCode = httpClient.executeMethod(getMethod);
   if (statusCode != HttpStatus.SC_OK) {
    System.err.println("Method failed: "
      + getMethod.getStatusLine());
   }
   //读取内容 
   byte[] responseBody = getMethod.getResponseBody();
   //处理内容
   System.out.println(new String(responseBody));
  } catch (HttpException e) {
   //发生致命的异常,可能是协议不对或者返回的内容有问题
   System.out.println("Please check your provided http address!");
   e.printStackTrace();
  } catch (IOException e) {
   //发生网络异常
   e.printStackTrace();
  } finally {
   //释放连接
   getMethod.releaseConnection();
  }
 }
}
 


POST方法

根据RFC2616,对POST的解释如下:POST方法用来向目的服务器发出请求,要求它接受被附在请求后的实体,并把它当作请求队列(Request-Line)中请求URI所指定资源的附加新子项。POST被设计成用统一的方法实现下列功能:

•对现有资源的注释(Annotation of existing resources)
•向电子公告栏、新闻组,邮件列表或类似讨论组发送消息
•提交数据块,如将表单的结果提交给数据处理过程
•通过附加操作来扩展数据库
调用HttpClient中的PostMethod与GetMethod类似,除了设置PostMethod的实例与GetMethod有些不同之外,剩下的步骤都差不多。在下面的例子中,省去了与GetMethod相同的步骤,只说明与上面不同的地方,并以登录清华大学BBS为例子进行说明。

•构造PostMethod之前的步骤都相同,与GetMethod一样,构造PostMethod也需要一个URI参数,在本例中,登录的地址是http://www.newsmth.net/bbslogin2.php。在创建了PostMethod的实例之后,需要给method实例填充表单的值,在BBS的登录表单中需要有两个域,第一个是用户名(域名叫id),第二个是密码(域名叫passwd)。表单中的域用类NameValuePair来表示,该类的构造函数第一个参数是域名,第二参数是该域的值;将表单所有的值设置到PostMethod中用方法setRequestBody。另外由于BBS登录成功后会转向另外一个页面,但是HttpClient对于要求接受后继服务的请求,比如POST和PUT,不支持自动转发,因此需要自己对页面转向做处理。具体的页面转向处理请参见下面的"自动转向"部分。代码如下: String url = "https://id:8443/keytest/add";
PostMethod postMethod = new PostMethod(url);
// 填入各个表单域的值
NameValuePair[] data = { new NameValuePair("id", "youUserName"),
new NameValuePair("passwd", "yourPwd") };
// 将表单的值放入postMethod中
postMethod.setRequestBody(data);
// 执行postMethod
int statusCode = httpClient.executeMethod(postMethod);
// HttpClient对于要求接受后继服务的请求,象POST和PUT等不能自动处理转发
// 301或者302
if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY || 
statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
    // 从头中取出转向的地址
    Header locationHeader = postMethod.getResponseHeader("location");
    String location = null;
    if (locationHeader != null) {
     location = locationHeader.getValue();
     System.out.println("The page was redirected to:" + location);
    } else {
     System.err.println("Location field value is null.");
    }
    return;
}


如有什么疑问大家可以联系我邮箱(meiyx89@163.com)
谢谢来次浏览的牛人,望大家有什么不错技术或想法能拿出来分享!











分享到:
评论

相关推荐

    java开源包8

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包1

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包11

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包2

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包3

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包6

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包5

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包10

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包4

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包7

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包9

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    java开源包101

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    Java资源包01

    使用简便和直截了当,用户只需要加载的图片和调整帧您想要的,如位置,时间显示和处理方法前帧。 Java的PList类库 Blister Blister是一个用于操作苹果二进制PList文件格式的Java开源类库(可用于发送数据给iOS应用...

    JAVA上百实例源码以及开源项目源代码

    显示出当前时间及年份,还可以选择年份及月份和日期 Java编写的HTML浏览器 一个目标文件 摘要:Java源码,网络相关,浏览器 Java编写的HTML浏览器源代码,一个很简单甚至不算是浏览器的HTML浏览器,使用方法: 可直接...

Global site tag (gtag.js) - Google Analytics