利用HttpClient使得Openlayers3能够访问跨域访问arcgis for server

最近做一个WebGIS的项目,使用的是Openlayers3 v3.17.1的版本,需要用到ajax调用ArcGIS for Server 10.2发布的WMS服务,业务应用于GIS服务不在一个域内,需要解决跨域的问题。

1、(不是最终解决方案,可略过)网上有一篇关于跨域的解决办法,讲的比较明白:http://www.cnblogs.com/dojo-lzz/p/4265637.html

几种解决办法,基本都要更改GIS服务器端的内容,暂时决定采用JSONP的方式来解决该问题,这时需要解决的另外一个问题出现了,那就是修改WMS的查询结果的格式。

2、(不是最终解决方案,可略过)查询ArcGIS for Server的帮助文档,看到其可以自定义 WMS GetFeatureInfo 响应,以为发现了神器,结果不知道是参数传递的问题,还是其他原因,不成功。

有一段话,特别重要。

使用 xslt_template 参数时,XSLT 模板不必遵循与默认模板相同的命名约定,但它需要经由 URL 提供。指定本地路径或 UNC 路径会导致请求失败。

从ArcGIS for Server的安装目录ArcGIS\Server\Styles\WMS中拷贝一个XSLT的模板出来,发布出来,保证可以正常访问。

将我的WMS的GetFeatureInfo的请求地址放到这里,还请大家能够看看有没有问题,将无论version是1.1.1和1.3.0都不行,

http://192.168.1.125:6080/arcgis/services/ymfb/ymfb/MapServer/WMSServer?service=WMS&version=1.3.0&request=GetFeatureInfo&layers=10&query_layers=10&INFO_FORMAT=text/plain&I=21&J=59&WIDTH=256&HEIGHT=256&SRS=EPSG:4326&CRS=EPSG:4326&STYLES=&BBOX=33.75,109.6875,36.5625,112.5&xsl_template=http://localhost:8081/ymgis/data/featureinfo_application_geojson.xsl

3、(终极解决方案)这时候,突然想起来以前用过httpclient,能不能用这个来实现呢?

httpclient的项目的地址:http://hc.apache.org/

使用异步请求插件HttpAsyncClient 4.1.2,官方包里有简单的应用例子,可以参照下。

需要强调的是,httpclient的ajax请求,只能是get,不能用post,这主要是由于ArcGIS for Server决定的,和httpclient本身无关。通过这种方式,最终拿到了wms的返回结果。

4、部分代码,自定义的中转跨域请求的代码,proxyData变量作为返回到前台的变量,本项目用的Struts2,应用原理都是一样的。 

4.1用来中转请求的Action代码

public static String Inputstr2Str_Reader(InputStream in, String encode)  
	   {  
	         
	       String str = "";  
	       try  
	       {  
	           if (encode == null || encode.equals(""))  
	           {  
	               // 默认以utf-8形式  
	               encode = "utf-8";  
	           }  
	           BufferedReader reader = new BufferedReader(new InputStreamReader(in, encode));  
	           StringBuffer sb = new StringBuffer();  
	             
	           while ((str = reader.readLine()) != null)  
	           {  
	               sb.append(str).append("\n");  
	           }  
	           return sb.toString();  
	       }  
	       catch (UnsupportedEncodingException e1)  
	       {  
	           e1.printStackTrace();  
	       }  
	       catch (IOException e)  
	       {  
	           e.printStackTrace();  
	       }  
	         
	       return str;  
	   }  
	
	public String proxyAjax() throws ExecutionException, IOException, InterruptedException {
		HttpServletRequest request = ServletActionContext.getRequest();
		String url = request.getParameter("url");
		CloseableHttpAsyncClient httpClient = HttpAsyncClients.createDefault();
		try {
			// Start the client
			httpClient.start();
			// One most likely would want to use a callback for operation result
			final CountDownLatch latch1 = new CountDownLatch(1);//线程辅助类,官方例子
			final HttpGet request2 = new HttpGet(url);//wms服务, arcgis只能用get调用
			httpClient.execute(request2, new FutureCallback() {

				@Override
				public void completed(final HttpResponse response2) {
					latch1.countDown();
					InputStream inputStream;
					try {
						inputStream = response2.getEntity().getContent();
						proxyData=Inputstr2Str_Reader(inputStream, "UTF-8");
					} catch (UnsupportedOperationException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}

				@Override
				public void failed(final Exception ex) {
					latch1.countDown();
					System.out.println(request2.getRequestLine() + "->" + ex);
				}

				@Override
				public void cancelled() {
					latch1.countDown();
					System.out.println(request2.getRequestLine() + " cancelled");
				}

			});
			latch1.await();
		} finally {
			httpClient.close();
		}
//		this.proxyData = url;
		return ActionSupport.SUCCESS;
	}

 4.2前台JS代码

function(e) {
	var viewResolution = map.getView().getResolution();
	var url = wmsSource.getGetFeatureInfoUrl(e.coordinate,iewResolution,"EPSG:4326",{
                INFO_FORMAT : "text/plain"
		});
	var ajaxUrl="http://localhost:8081/ymgis/proxyAjax.action?url="+encodeURIComponent(url);
	$.ajax({url:ajaxUrl,success:function(data){
		alert(data);
		}});
}

 

 

你可能感兴趣的:(java)