Openlayers WFS基于java与C#的跨域代理

原文地址:http://blog.csdn.net/freeland1/article/details/41204485

通常web项目于gis服务器不在同一域下,这就涉及到了wfs跨域问题。

一 几种常见的wfs跨域比较:

1.1 基于openlayers自带的proxy.cgi
缺陷:正常可以,但部署麻烦,要装python,还要配置iis,tomcat。。。并且在wfs参数中,比如viewparam中有',\字符的话,cgi的python代理会报错。
1.2 基于esri的proxy
缺陷:在浏览器输入wfs请求可以通过,但是在程序里请求wfs参数,一般url会被自动转码,然后代理识别不了,一模一样的转码后就可以通过。个人猜测esri代理的转码部分没有通用解析。有高人可指导。
1.3 使用后台自定义代理
1.3.1 使用ashx
[csharp]  view plain copy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Web;  
  5. using System.Net;  
  6. using System.IO;  
  7.   
  8. namespace WebApplication1  
  9. {  
  10.     /// <summary>  
  11.     /// OpenlayerProxy 的摘要说明  
  12.     /// </summary>  
  13.     public class OpenlayerProxy : IHttpHandler  
  14.     {  
  15.         public void ProcessRequest(HttpContext context)  
  16.         {  
  17.             if (string.IsNullOrEmpty(context.Request["URL"])) return;  
  18.             HttpWebRequest request = (HttpWebRequest)WebRequest.Create(context.Request["URL"]);  
  19.             request.UserAgent = context.Request.UserAgent;  
  20.             request.ContentType = context.Request.ContentType;  
  21.             request.Method = context.Request.HttpMethod;  
  22.   
  23.             byte[] trans = new byte[1024];  
  24.             int offset = 0;  
  25.             int offcnt = 0;  
  26.   
  27.             if (request.Method.ToUpper() == "POST")  
  28.             {  
  29.                 Stream nstream = request.GetRequestStream();  
  30.                 while (offset < context.Request.ContentLength)  
  31.                 {  
  32.                     offcnt = context.Request.InputStream.Read(trans, offset, 1024);  
  33.                     if (offcnt > 0)  
  34.                     {  
  35.                         nstream.Write(trans, 0, offcnt);  
  36.                         offset += offcnt;  
  37.                     }  
  38.                 }  
  39.                 nstream.Close();  
  40.             }  
  41.             HttpWebResponse response = (HttpWebResponse)request.GetResponse();  
  42.             //Encoding enc = Encoding.GetEncoding(65001);  
  43.             context.Response.ContentType = response.ContentType;  
  44.             StreamReader loResponseStream = new StreamReader(response.GetResponseStream());  
  45.             string lcHtml = loResponseStream.ReadToEnd();  
  46.             context.Response.Write(lcHtml);  
  47.             response.Close();  
  48.             loResponseStream.Close();  
  49.   
  50.         }  
  51.   
  52.         public bool IsReusable  
  53.         {  
  54.             get  
  55.             {  
  56.                 return false;  
  57.             }  
  58.         }  
  59.   
  60.     }  
  61. }  
1.3.2 基于java的servlet
[java]  view plain copy
  1. package com.nkstar.action;  
  2.   
  3. import javax.servlet.http.HttpServlet;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.io.OutputStream;  
  7. import java.net.HttpURLConnection;  
  8. import java.net.URL;  
  9.   
  10. import javax.servlet.ServletException;  
  11. import javax.servlet.http.HttpServlet;  
  12. import javax.servlet.http.HttpServletRequest;  
  13. import javax.servlet.http.HttpServletResponse;  
  14.   
  15. /** 
  16.  * This is a transparent HTTP proxy written in Java that is similar to the proxy 
  17.  * in the OpenLayers examples, which is written in Python. These proxies are 
  18.  * used to circumvent browser restrictions on cross-domain requests with 
  19.  * Javascript. 
  20.  * </p> 
  21.  * <p> 
  22.  * To use the proxy you need to 1) configure the proxy servlet in your web.xml 
  23.  * and 2) use OpenLayers.setProxyHost to set the url-path to the proxy. If the 
  24.  * proxy is configured to listen to the url-pattern '/gwtOpenLayersProxy/*' then 
  25.  * the proxy host should be set to 'gwtOpenLayersProxy?targetURL='. 
  26.  * </p> 
  27.  * Initial code for this proxy is based upon <a href= 
  28.  * "http://trac.openlayers.org/changeset/8099/sandbox?format=diff&new=8099">the 
  29.  * following code</a><br /> 
  30.  * see also <a href= 
  31.  * "http://java.sun.com/docs/books/tutorial/networking/urls/readingWriting.html" 
  32.  * title="this networking tutorial">this networking tutorial</a> 
  33.  * <p> 
  34.  */  
  35. @SuppressWarnings("serial")  
  36. public class OpenLayersProxyServlet extends HttpServlet {  
  37.   
  38.     protected void doGet(HttpServletRequest request,  
  39.             HttpServletResponse response) throws ServletException, IOException {  
  40.         processRequest(request, response);  
  41.     }  
  42.   
  43.     protected void doPost(HttpServletRequest request,  
  44.             HttpServletResponse response) throws ServletException, IOException {  
  45.         processRequest(request, response);  
  46.     }  
  47.   
  48.     private void processRequest(HttpServletRequest request,  
  49.             HttpServletResponse response) throws ServletException, IOException {  
  50.   
  51.         HttpURLConnection connection = null;  
  52.         InputStream istream = null// input to proxy  
  53.         OutputStream ostream = null// output from proxy  
  54.         InputStream connectionIstream = null// output for the target is  
  55.         // input for the connection  
  56.         OutputStream connectionOstream = null// input for the target is  
  57.         // output for the connection  
  58.   
  59.         String remoteHost = request.getRemoteHost(); // get host address of  
  60.         // client - for checking  
  61.         // allowedHosts  
  62.         boolean allowedHost = isAllowedHost(remoteHost); // The allowedHosts  
  63.         // are the hosts  
  64.         // that are allowed  
  65.         // to use the Open  
  66.         // Proxy.  
  67.         try {  
  68.             // easy way to ignore case of param?  
  69.             if (request.getParameter("targetURL") != null  
  70.                     && request.getParameter("targetURL") != "" && allowedHost) {  
  71.   
  72.                 // HTTPUrlConnection looks at http.proxyHost and http.proxyPort  
  73.                 // system properties.  
  74.                 // Make sure these properties are set these if you are behind a  
  75.                 // proxy.  
  76.   
  77.                 // step 1: initialize  
  78.                 String requestMethod = request.getMethod();  
  79.   
  80.                 URL targetURL = new URL(request.getParameter("targetURL"));  
  81.                 connection = (HttpURLConnection) targetURL.openConnection();  
  82.                 connection.setRequestMethod(requestMethod);  
  83.                 transferHTTPRequestHeaders(connection, request);  
  84.   
  85.                 // step 2: proxy requests  
  86.                 if (requestMethod.equals("GET")) {  
  87.                     // default for setDoInput is true  
  88.                     connectionIstream = connection.getInputStream();  
  89.                 }  
  90.                 ;  
  91.                 if (requestMethod.equals("POST")) {  
  92.                     transferHTTPRequestHeadersForPOST(connection, request);  
  93.                     int clength = request.getContentLength();// clength is  
  94.                     // for checking  
  95.                     // if there is a  
  96.                     // POST body. Is  
  97.                     // that  
  98.                     // sufficient?  
  99.   
  100.                     if (clength > 0) {  
  101.                         istream = request.getInputStream();  
  102.                         connection.setDoOutput(true);// for POST we need to  
  103.                         // write to connection  
  104.                         connection.setRequestProperty("Content-Length", Integer  
  105.                                 .toString(clength)); // only valid for POST  
  106.                         // request  
  107.                         connectionOstream = connection.getOutputStream();  
  108.                         // copy the request body to remote outputStream  
  109.                         copy(istream, connectionOstream);  
  110.                     }  
  111.                     connectionIstream = connection.getInputStream();  
  112.                 }  
  113.   
  114.                 // step 3: return output  
  115.                 // can output be the same for GET/POST? or different return  
  116.                 // headers?  
  117.                 // servlet may return 3 things: status code, response headers,  
  118.                 // response body  
  119.                 // status code and headers have to be set before response body  
  120.                 response.setContentType(connection.getContentType());  
  121.                 ostream = response.getOutputStream();  
  122.                 copy(connectionIstream, ostream);  
  123.             }  
  124.             // if not targetURL send page that targetURL is required param  
  125.         } catch (Exception e) {  
  126.             response.setStatus(500); // what will user get? default page for  
  127.             // response code  
  128.             // WMS/WFS have specific responses to errors  
  129.             // response.getWriter();//will writing custom result help  
  130.             e.printStackTrace();  
  131.         } finally {  
  132.             if (istream != null) {  
  133.                 istream.close();  
  134.             }  
  135.             if (ostream != null) {  
  136.                 ostream.close();  
  137.             }  
  138.             if (connectionIstream != null) {  
  139.                 connectionIstream.close();  
  140.             }  
  141.             if (connectionOstream != null) {  
  142.                 connectionOstream.close();  
  143.             }  
  144.         }  
  145.   
  146.     }  
  147.   
  148.     private void copy(InputStream istream, OutputStream ostream)  
  149.             throws Exception {  
  150.         int bufferSize = 4 * 4 * 1024;// same buffer size as in Jetty utils  
  151.         // (2*8192)  
  152.         byte[] buffer = new byte[bufferSize];  
  153.         int read;  
  154.         while ((read = istream.read(buffer)) != -1) {  
  155.             ostream.write(buffer, 0, read);  
  156.         }  
  157.     }  
  158.   
  159.     private void transferHTTPRequestHeaders(HttpURLConnection connection,  
  160.             HttpServletRequest request) {  
  161.         // TODO make sure all headers are copied to target, see for HTTP headers  
  162.         // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html  
  163.         // Do request.getProperties to get request properties  
  164.         if (request.getHeader("Accept") != null) {  
  165.             connection  
  166.                     .setRequestProperty("Accept", request.getHeader("Accept"));  
  167.         }  
  168.         if (request.getHeader("Accept-Charset") != null) {  
  169.             connection.setRequestProperty("Accept-Charset", request  
  170.                     .getHeader("Accept-Charset"));  
  171.         }  
  172.         if (request.getHeader("Accept-Encoding") != null) {  
  173.             // TODO browsers accept gzipped, should proxy accept gzip and how to  
  174.             // handle it?  
  175.             // connection.setRequestProperty("Accept-Encoding",  
  176.             // request.getHeader("Accept-Encoding"));  
  177.         }  
  178.         if (request.getHeader("Authorization") != null) {  
  179.             connection.setRequestProperty("Authorization", request  
  180.                     .getHeader("Authorization"));  
  181.         }  
  182.         if (request.getHeader("Connection") != null) {  
  183.             // TODO HTTP/1.1 proxies MUST parse the Connection header field  
  184.             // before a message is forwarded and, for each connection-token in  
  185.             // this field, remove any header field(s) from the message with the  
  186.             // same name as the connection-token.  
  187.             // connection.setRequestProperty("Connection",  
  188.             // request.getHeader("Connection"));  
  189.         }  
  190.   
  191.         // set de-facto standard proxy headers (x-forwarded-for, others?s)  
  192.         if (request.getHeader("X-Forwarded-For") != null) {  
  193.             connection.setRequestProperty("X-Forwarded-For", request  
  194.                     .getHeader("X-Forwarded-For"));// TODO append IP proxy  
  195.         } else {  
  196.             connection.setRequestProperty("X-Forwarded-For", request  
  197.                     .getRemoteAddr());// TODO append IP proxy  
  198.         }  
  199.     }  
  200.   
  201.     private void transferHTTPRequestHeadersForPOST(  
  202.             HttpURLConnection connection, HttpServletRequest request) {  
  203.         if (request.getHeader("Content-Type") != null) {  
  204.             connection.setRequestProperty("Content-Type", request  
  205.                     .getContentType());  
  206.         } else {  
  207.             // throw exception?  
  208.         }  
  209.     }  
  210.   
  211.     private boolean isAllowedHost(String remoteHost) {  
  212.         // TODO checking of host  
  213.         return true;  
  214.     }  
  215.   
  216. }  
后两种都避免了一和二的缺陷,通用可行,直接可以放在web项目当中部署,简单操作。

使用说明
OpenLayer2代理使用,只需在程序开头或init方法第一句写上proxyhost即可。
[javascript]  view plain copy
  1. OpenLayers.ProxyHost = '/OpenlayerProxy.ashx?URL=';  
  2.   
  3.   var url = 'http://localhost:8090/geoserver/wfs?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&OUTPUTFORMAT=GML2&TYPENAME=pgrouting:Mypgrouting&viewparams=' + viewparams;  
  4.         var request = OpenLayers.Request.POST({  
  5.             url: url,  
  6.             callback: onComplete  
  7.         });  

OpenLayer3 代理使用
[javascript]  view plain copy
  1. queryButton.addEventListener('click'function (event) {  
  2.        var viewparams = "ARRAY[[" + locatearr.join("],[") + "]]";  
  3.        viewparams = stringReg(viewparams);  
  4.        viewparams = "destinationarr:" + viewparams;  
  5.        var url ='http://localhost:8090/geoserver/wfs?SERVICE=WFS&VERSION=1.1.0&REQUEST=GetFeature&OUTPUTFORMAT=json&TYPENAME=pgrouting:Mypgrouting&viewparams=' + viewparams;  
  6.        url = '/OpenlayerProxy.ashx?URL=' + encodeURIComponent(url);  
  7.        $.ajax({  
  8.            type: "POST",  
  9.            url: url,  
  10.            dataType:"text",  
  11.            success: onComplete  
  12.        });  
  13.    });  

需要对url进行编码,否则代理进去丢失参数。

你可能感兴趣的:(Webgis)