最近需要在Android上通过HTTPS协议访问Tomcat服务器,这里做一下记录,备忘用。
一、Tomcat上的配置
1.生成keystore文件
在JDK_HOME/bin目录下有一个keytool工具,可用来生成一个存放服务器私钥和自签名证书的文件。使用如下命令来生成这个文件,
keytool -v -genkey -alias cyber_space -keyalg RSA -keystore /home/cyber_space/KEYS/cyber_space.keystore -validity 36500
其中,validity是有效时间,这里定成了100年。其他的参数意思都可以从英文单词中直接得出。
接下来按下图步骤进行操作。
2.配置TOMCAT_HOME/conf目录下的server.xml文件
在配置文件中添加如下的内容,或将注释部分去掉修改为如下。
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="/home/cyber_space/KEYS/cyber_space.keystore" keystorePass="密码"/>
3.重新启动Tomcat,使用浏览器访问https://IP:8843
看是否可以访问Tomcat,这里可能会遇到证书不受信任问题,只要让浏览器信任证书,就可以访问了。4.修改工程目录下的web.xml文件
如果要让HTTP访问自动转换为HTTPS访问,则在相应的工程目录下修改web.xml文件,增加如下配置。
<security-constraint>
<web-resource-collection>
<web-resource-name>SSL</web-resource-name>
<url-pattern>/TestServlet</url-pattern>
</web-resource-collection>
<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
其中UrlPattern即是你想要自动转换为HTTPS请求的地址。
二、Android端代码
下面代码的写法表示Android应用程序信任所有证书。
package com.example.justyoung.logintest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* Created by justyoung on 15/6/25.
*/
public class HttpsConnection {
public void httpsRequestThread(String url) {
new HttpsRequestThread(url).start();
}
/**
* 发起HTTPS请求,并返回结果
*
* @param url https连接
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
* @throws IOException
* @return 返回服务器输出结果
*/
private static String httpsRequest(String url) throws NoSuchAlgorithmException, KeyManagementException, IOException {
StringBuilder stringBuilder = new StringBuilder();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new MyTrustManager()}, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new MyHostnameVerifier());
HttpsURLConnection connection = (HttpsURLConnection) new URL(url).openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setConnectTimeout(10000);
connection.connect();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
String result = stringBuilder.toString();
System.out.println(result);
return result;
}
private static class MyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
private static class MyTrustManager implements 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;
}
}
private class HttpsRequestThread extends Thread {
private String url;
public HttpsRequestThread(String url) {
this.url = url;
}
@Override
public void run() {
try {
httpsRequest(this.url);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyManagementException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}