Google Maps API を SSL で使えるようにしてみる Java版

httpsのサイトでgoogleMapを使う際にIEだと毎回警告エラーが出るので、なんか回避方法があるか調べていたらPHPを使ってProxy経由でやっている例がありました。
Google Maps API を SSL で使えるようにしてみる。 -tonextone.com/type/-

んで、Javaでコレとおんなじ機能を作る機会があったのでメモしときます。

GoogleMapProxyServlet
package servlet;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GoogleMapProxyServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;
  private String[] patternArray = {
      "\"http://[^.]+.google.com\"",
      "\"http://maps.google.com/intl/en_ALL/mapfiles/[0-9a-z]+/maps2\"",
      "\"http://(kh|mt)[0-9]+.google.com[^\"]+\"",
      "\"http://[^/.]+.google.com/intl/en_ALL/mapfiles/\""
  };
  
  protected void doGet(HttpServletRequest request,
             HttpServletResponse response) 
    throws ServletException,IOException { 
    
    StringBuffer scriptSb = new StringBuffer();
    StringBuffer sb = new StringBuffer();
    URL url;
    url = new URL("http://maps.google.com/maps?file=api&v=2&key=" + "Googel Map Apiで取得したキー");
    URLConnection con = url.openConnection();
    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String line;
    while ((line = in.readLine()) != null) {
      scriptSb.append(line);
    }
    String script = scriptSb.toString();
    for (String regex : patternArray) {
      Pattern pattern = Pattern.compile(regex);
      Matcher matcher = pattern.matcher(script);
      while (matcher.find()) {
        String urlStr = script.substring(matcher.start() + 1, matcher.end() -1);
        matcher.appendReplacement(sb,  "\"" + request.getContextPath() 
				                          + "/proxy?" 
				                          + urlStr.replaceAll("\\\\", "\\\\\\\\") + "\"");
      }
      matcher.appendTail(sb);
      script = sb.toString();
      sb = new StringBuffer();
    }
    response.getWriter().println(script);
    in.close();
    response.getWriter().close();
  }
}
ProxyServlet
package servlet;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.URL;
import java.net.URLConnection;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ProxyServlet extends HttpServlet {
  
  protected void doGet(HttpServletRequest request,
       HttpServletResponse response) 
    throws ServletException,IOException {
    
    URL url = new URL(request.getQueryString());
    URLConnection con = url.openConnection();
    response.setContentType(con.getContentType());
    InputStream in = con.getInputStream();
    if (con.getContentType().startsWith("image")) {
      OutputStream out = response.getOutputStream();
      String formatName = con.getContentType().split("/")[1];
      if (formatName.equals("png")) {
        // pngの場合はタイル表示時に遅延が発生して、正しく画面表示できない
        // ケースがあるのでImageIOを使って表示。
        // ただし、ImageIOだと内部でflashされレスポンスがコミットされるので
        // Exceptionが発生するが、基本的に無視。
        BufferedImage bi = ImageIO.read(in) ;
        OutputStream dummyOut = out;
        ImageIO.write(bi, formatName, dummyOut);
      } else {
        byte[] inputBytes = new byte[in.available()];
        in.read(inputBytes);
        out.write(inputBytes);
      }
    } else {
      BufferedReader br = new BufferedReader(new InputStreamReader(in));
      PrintWriter out = response.getWriter();
      String line;
      while ((line = br.readLine()) != null) {
        out.println(line);
      }
      br.close();
    }
    in.close();
  }  
}
web.xml

web.xmlに次の記述を追加

  <servlet>
    <servlet-name>GoogleMapProxyServlet</servlet-name>
    <servlet-class>servlet.GoogleMapProxyServlet</servlet-class>
  </servlet>
  
  <servlet>
    <servlet-name>ProxyServlet</servlet-name>
    <servlet-class>servlet.ProxyServlet</servlet-class>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>GoogleMapProxyServlet</servlet-name>
    <url-pattern>/googleMapServlet</url-pattern>
  </servlet-mapping>
  
  <servlet-mapping>
    <servlet-name>ProxyServlet</servlet-name>
    <url-pattern>/proxyServlet</url-pattern>
  </servlet-mapping>
jsp

あとはjspのヘッダにサーブレット経由でスクリプトを記述するように書いてあげればOKです。

<script src="/googleMapServlet" type="text/javascript"></script>