よい子がまねしちゃいけない、HttpClient-4.0の使い方(SSL編)
ちょっと前の話ですが、commons-HttpClientがApache-HttpComponentsの一部となりました。バージョンも3から4に上がり、クラス構成も変わったみたいです。3.0のころのHttpClientは割とネットに情報が多く、何をやるにも困りませんでした。でも4.0以降になるとあんまりないんです。
今回、「サーバの証明書なしに、HttpClientでSSLを使う」ということをやってみました。これもHttpClient-3.0だとググれば情報がありますが、4.0系だとそのままは使えないようで、コピペ厨にとっては問題です。
まずはSSLSocketFactoryに手を加えたもの。
import java.io.IOException; import java.net.Socket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; 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.scheme.HostNameResolver; import org.apache.http.conn.ssl.SSLSocketFactory; public class NoneSSLVerifierSSLSocketFactory extends SSLSocketFactory { private final SSLContext sslcontext; public NoneSSLVerifierSSLSocketFactory(final SSLContext sslContext, final HostNameResolver nameResolver) { super(sslContext, nameResolver); sslcontext = sslContext; } public static NoneSSLVerifierSSLSocketFactory create() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, new TrustManager[] { 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; } } }, null); return new NoneSSLVerifierSSLSocketFactory(sslContext, null); } @Override public Socket createSocket() throws IOException { return sslcontext.getSocketFactory().createSocket(); } }
そして、手を加えたSSLSocketFactoryを使用する、HttpClient。
import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import org.apache.http.client.params.ClientPNames; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.ClientConnectionManagerFactory; import org.apache.http.conn.scheme.PlainSocketFactory; 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; import org.apache.http.impl.conn.SingleClientConnManager; import org.apache.http.params.HttpParams; public class NoneSSLVerifierHttpClient extends DefaultHttpClient { @Override protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register(new Scheme("http", PlainSocketFactory .getSocketFactory(), 80)); SSLSocketFactory sslSocketFactory = null; try { sslSocketFactory = NoneSSLVerifierSSLSocketFactory.create(); } catch (KeyManagementException e) { throw new RuntimeException(e); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } sslSocketFactory.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); registry.register(new Scheme("https", sslSocketFactory, 443)); ClientConnectionManager connManager = null; HttpParams params = getParams(); ClientConnectionManagerFactory factory = null; String className = (String) params .getParameter(ClientPNames.CONNECTION_MANAGER_FACTORY_CLASS_NAME); if (className != null) { try { Class<?> clazz = Class.forName(className); factory = (ClientConnectionManagerFactory) clazz.newInstance(); } catch (ClassNotFoundException ex) { throw new IllegalStateException("Invalid class name: " + className); } catch (IllegalAccessException ex) { throw new IllegalAccessError(ex.getMessage()); } catch (InstantiationException ex) { throw new InstantiationError(ex.getMessage()); } } if (factory != null) { connManager = factory.newInstance(params, registry); } else { connManager = new SingleClientConnManager(getParams(), registry); } return connManager; } }
あとはNoneSSLVerifierHttpClient を使うだけ。でもこれ。どう考えても危険なので、インターネット上のアプリケーションには使用しないことをおすすめします。痛い目見る可能性有りです。
よい子はちゃんとkeytoolを使って、証明書を登録してやりましょう。
久しぶりにClickを触る
2.1.0-RC1-incubatingをさわってみました。新機能を全部試した訳じゃないけど、まぁぽろぽろと。
最近、個人で開発するときは必ずMaven2で管理してんだけど、今回もClickさんのpom、ちょっとおかしいです。
click-nodepsをpom.xmlに組み込んだらvelocityがダウンロードされない。結局こんなことをやった。
<dependency> <groupId>org.apache.click</groupId> <artifactId>click-nodeps</artifactId> <version>2.1.0-RC1-incubating</version> <exclusions> <exclusion> <groupId>velocity</groupId> <artifactId>velocity</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.6.2</version> </dependency>
ちなみにClick使ってるのにClickIDEを使ってません。使いたい気持ちは山々なんだけど、Clickみたいに軽く作れるフレームワークにWTPみたいな思苦しいもん使いたくないわけです。Clickを使うときは超軽くしたい。軽快さを追求して、開発時はServletコンテナもWinstoneとか使ってます。うまく作ればHotDeployとかなくても、割とさくさく作れるし。
つーか、安西先生。WTPに依存しないClickIDEがほしいです。
最近のSX-DbUtils
のんびりと作ってたSX-DbUtilsも、1.0系(commons-dbutils-1.1対応)と、1.2系(commons-dbutils-1.2対応)をリリースしてからずいぶん経つわけです。
http://sourceforge.jp/projects/sx-dbutils/
ダウンロード数とか全然伸びないけど。つーか、jarよりソースのほうがダウンロードされてたりw。
sx-dbutils-tiger(Java5対応版)も出してるんだけど、通常版の方がダウンロード数が多い。tiger版に入れたtemplateパッケージ(Dao作る元みたいなの)はかなり便利になるようにがんばったんだけど、やはり『昔作ったシステムに機能追加したいんだけど、普通のDbUtilsは何とかしてほしい』という要望が多いのかもしれない。まぁ俺がモロにその状況だったんだけど・・・
とはいえ今後、自分でこれを使うことはあまりないかもしれん。仕事じゃ当分使わないし、たとえ何か別の案件に関わったとしても、俺自身 新規案件ならS2JDBCかDBFluteを押すだろうしw
あ、でも最近、SX-DbUtilsを導入してる現場があるって話を聞いた。新規案件らしい。元がApacheのライブラリってのは、けっこう強いのかもしれない。
SpringとClickの連携
ちょっと前にClick-2.1.0-RC1が出たんだけど、今日初めてこのバージョンのexampleを見てたわけです。
ありゃ?
Springの対応が強化されてる。CLK-534か。spring2.5対応だ。component-scanとか使ってるし。以前、ClickとSpring2.5の連携について書いたことがあったけど、今じゃまったく意味なしか。
http://d.hatena.ne.jp/chinpeinet/20080317
クラス名の取得にBeanNameGeneratorの独自実装を提供せず、SpringClickServletでなんとかしてしまった訳ですね。ScopeMetadataResolverは実装を提供。
最近はS2Clickとかあるから日本じゃあんまりClick+Springって組み合わせはないのかもしれないんだけど、個人的にはSpringも好き。今回の対応は割とうれしかったです。
札幌にいる
先月後半から札幌にいます。
札幌はすずしいねー。夜は寒いくらい。
札幌来たとき、実家から連絡が入って
「お父さん、体調悪い原因は癌だった」
って。先週は大分の実家までお見舞い行ったりした。
いろいろ大変ですよ。