JAVA怎样调用https类型的webservice

Python020

JAVA怎样调用https类型的webservice,第1张

第一步按照Axis生成本地访问客户端,完成正常的webservice调用的开发,这里的细节我就不再描述,重点说明和http不同的地方-证书的生成和使用。这里假设需要访问的网址是https://www.abc.com ,那么就需要生成网址的安全证书设置到系统属性中,并且需要在调用代码前。如下图

第二步就是介绍怎样生成证书,先写一个InstallCert.java类放到自己电脑的D盘根目录下,(注意这个类是没有包名的)类中代码如下:

/**

*

*/

import java.io.BufferedReader

import java.io.File

import java.io.FileInputStream

import java.io.FileOutputStream

import java.io.InputStream

import java.io.InputStreamReader

import java.io.OutputStream

import java.security.KeyStore

import java.security.MessageDigest

import java.security.cert.CertificateException

import java.security.cert.X509Certificate

import javax.net.ssl.SSLContext

import javax.net.ssl.SSLException

import javax.net.ssl.SSLSocket

import javax.net.ssl.SSLSocketFactory

import javax.net.ssl.TrustManager

import javax.net.ssl.TrustManagerFactory

import javax.net.ssl.X509TrustManager

public class InstallCert {

public static void main(String[] args) throws Exception {

String host

int port

char[] passphrase

if ((args.length == 1) || (args.length == 2)) {

String[] c = args[0].split(":")

host = c[0]

port = (c.length == 1) ? 443 : Integer.parseInt(c[1])

String p = (args.length == 1) ? "changeit" : args[1]

passphrase = p.toCharArray()

} else {

System.out

.println("Usage: java InstallCert <host>[:port] [passphrase]")

return

}

File file = new File("jssecacerts")

if (file.isFile() == false) {

char SEP = File.separatorChar

File dir = new File(System.getProperty("java.home") + SEP + "lib"

+ SEP + "security")

file = new File(dir, "jssecacerts")

if (file.isFile() == false) {

file = new File(dir, "cacerts")

}

}

System.out.println("Loading KeyStore " + file + "...")

InputStream in = new FileInputStream(file)

KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType())

ks.load(in, passphrase)

in.close()

SSLContext context = SSLContext.getInstance("TLS")

TrustManagerFactory tmf = TrustManagerFactory

.getInstance(TrustManagerFactory.getDefaultAlgorithm())

tmf.init(ks)

X509TrustManager defaultTrustManager = (X509TrustManager) tmf

.getTrustManagers()[0]

SavingTrustManager tm = new SavingTrustManager(defaultTrustManager)

context.init(null, new TrustManager[] { tm }, null)

SSLSocketFactory factory = context.getSocketFactory()

System.out

.println("Opening connection to " + host + ":" + port + "...")

SSLSocket socket = (SSLSocket) factory.createSocket(host, port)

socket.setSoTimeout(10000)

try {

System.out.println("Starting SSL handshake...")

socket.startHandshake()

socket.close()

System.out.println()

System.out.println("No errors, certificate is already trusted")

} catch (SSLException e) {

System.out.println()

e.printStackTrace(System.out)

}

X509Certificate[] chain = tm.chain

if (chain == null) {

System.out.println("Could not obtain server certificate chain")

return

}

BufferedReader reader = new BufferedReader(new InputStreamReader(

System.in))

System.out.println()

System.out.println("Server sent " + chain.length + " certificate(s):")

System.out.println()

MessageDigest sha1 = MessageDigest.getInstance("SHA1")

MessageDigest md5 = MessageDigest.getInstance("MD5")

for (int i = 0i <chain.lengthi++) {

X509Certificate cert = chain[i]

System.out.println(" " + (i + 1) + " Subject "

+ cert.getSubjectDN())

System.out.println(" Issuer " + cert.getIssuerDN())

sha1.update(cert.getEncoded())

System.out.println(" sha1" + toHexString(sha1.digest()))

md5.update(cert.getEncoded())

System.out.println(" md5 " + toHexString(md5.digest()))

System.out.println()

}

System.out

.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]")

String line = reader.readLine().trim()

int k

try {

k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1

} catch (NumberFormatException e) {

System.out.println("KeyStore not changed")

return

}

X509Certificate cert = chain[k]

String alias = host + "-" + (k + 1)

ks.setCertificateEntry(alias, cert)

OutputStream out = new FileOutputStream("jssecacerts")

ks.store(out, passphrase)

out.close()

System.out.println()

System.out.println(cert)

System.out.println()

System.out

.println("Added certificate to keystore 'jssecacerts' using alias '"

+ alias + "'")

}

private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray()

private static String toHexString(byte[] bytes) {

StringBuilder sb = new StringBuilder(bytes.length * 3)

for (int b : bytes) {

b &= 0xff

sb.append(HEXDIGITS[b >>4])

sb.append(HEXDIGITS[b &15])

sb.append(' ')

}

return sb.toString()

}

private static class SavingTrustManager implements X509TrustManager {

private final X509TrustManager tm

private X509Certificate[] chain

SavingTrustManager(X509TrustManager tm) {

this.tm = tm

}

public X509Certificate[] getAcceptedIssuers() {

throw new UnsupportedOperationException()

}

public void checkClientTrusted(X509Certificate[] chain, String authType)

throws CertificateException {

throw new UnsupportedOperationException()

}

public void checkServerTrusted(X509Certificate[] chain, String authType)

throws CertificateException {

this.chain = chain

tm.checkServerTrusted(chain, authType)

}

}

}

将上面的InstallCert.java编译成InstallCert.class文件放到自己电脑的D盘根目录下。这是正常的情况下D盘根目录下会有3个文件,如下图:

打开cmd进入到d盘开始执行生成证书命令,我这里不便于那我的网址测试我用支付宝的网址来测试的,输入:java InstallCert www.alipay.com 如下图

当出现了:Enter certificate to add to trusted keystore or 'q' to quit: [1]

这行代码时,输入1,回车。正常执行完后在D盘根目录下就会出现证书“jssecacerts”文件,具体如下图:

6

得到证书后将证书拷贝到$JAVA_HOME/jre/lib/security目录下,我这里是win7系统,在尝试的过程中需要将证书重命名为:cacerts 放进去才会有用。(这个步骤在不同的环境和操作系统下有点不同,需要注意)

使用httpClient可以发送,具体的可以参考下面的代码

SSLClient类,继承至HttpClient

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.conn.ClientConnectionManager

import org.apache.http.conn.scheme.Scheme

import org.apache.http.conn.scheme.SchemeRegistry

import org.apache.http.conn.ssl.SSLSocketFactory

import org.apache.http.impl.client.DefaultHttpClient

//用于进行Https请求的HttpClient

public class SSLClient extends DefaultHttpClient{

public SSLClient() throws Exception{

        super()

        SSLContext ctx = SSLContext.getInstance("TLS")

        X509TrustManager tm = new X509TrustManager() {

                @Override

                public void checkClientTrusted(X509Certificate[] chain,

                        String authType) throws CertificateException {

                }

                @Override

                public void checkServerTrusted(X509Certificate[] chain,

                        String authType) throws CertificateException {

                }

                @Override

                public X509Certificate[] getAcceptedIssuers() {

                    return null

                }

        }

        ctx.init(null, new TrustManager[]{tm}, null)

        SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER)

        ClientConnectionManager ccm = this.getConnectionManager()

        SchemeRegistry sr = ccm.getSchemeRegistry()

        sr.register(new Scheme("https", 443, ssf))

    }

}

HttpClient发送post请求的类

import java.util.ArrayList

import java.util.Iterator

import java.util.List

import java.util.Map

import java.util.Map.Entry

import org.apache.http.HttpEntity

import org.apache.http.HttpResponse

import org.apache.http.NameValuePair

import org.apache.http.client.HttpClient

import org.apache.http.client.entity.UrlEncodedFormEntity

import org.apache.http.client.methods.HttpPost

import org.apache.http.message.BasicNameValuePair

import org.apache.http.util.EntityUtils

/*

 * 利用HttpClient进行post请求的工具类

 */

public class HttpClientUtil {

public String doPost(String url,Map<String,String> map,String charset){

HttpClient httpClient = null

HttpPost httpPost = null

String result = null

try{

httpClient = new SSLClient()

httpPost = new HttpPost(url)

//设置参数

List<NameValuePair> list = new ArrayList<NameValuePair>()

Iterator iterator = map.entrySet().iterator()

while(iterator.hasNext()){

Entry<String,String> elem = (Entry<String, String>) iterator.next()

list.add(new BasicNameValuePair(elem.getKey(),elem.getValue()))

}

if(list.size() > 0){

UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list,charset)

httpPost.setEntity(entity)

}

HttpResponse response = httpClient.execute(httpPost)

if(response != null){

HttpEntity resEntity = response.getEntity()

if(resEntity != null){

result = EntityUtils.toString(resEntity,charset)

}

}

}catch(Exception ex){

ex.printStackTrace()

}

return result

}

}

测试代码

import java.util.HashMap

import java.util.Map

//对接口进行测试

public class TestMain {

private String url = "https://192.168.1.101/"

private String charset = "utf-8"

private HttpClientUtil httpClientUtil = null

public TestMain(){

httpClientUtil = new HttpClientUtil()

}

public void test(){

String httpOrgCreateTest = url + "httpOrg/create"

Map<String,String> createMap = new HashMap<String,String>()

createMap.put("authuser","*****")

createMap.put("authpass","*****")

createMap.put("orgkey","****")

createMap.put("orgname","****")

String httpOrgCreateTestRtn = httpClientUtil.doPost(httpOrgCreateTest,createMap,charset)

System.out.println("result:"+httpOrgCreateTestRtn)

}

public static void main(String[] args){

TestMain main = new TestMain()

main.test()

}

}