서울땅콩의 취미생활

문제점

GIS개발을 진행할 때 클라이언트에서 GeoServer로 다이렉트로 연결하지 못하는 경우가 있다.

통상적으로는 GeoServer로 다이렉트로 연결하여 요청 및 응답을 받는게 맞지만 보안상 불가능한 경우가 있다.

WAS를 통해서 우회하게 된다면 약간?의 트래픽이 더 발생할 수 있고 WAS의 부하가 발생할 수 있지만 큰 문제는 없을 것으로 보인다. 다만, 관리 포인트가 하나 더 늘어나게 된다는 문제점이 있다.

해결

우회하여 GeoServer를 이용해야 하는데 WAS의 proxy소스를 이용하여 우회하도록 처리하여야 한다. 결국 요청은 클라이언트 -> WAS -> GeoServer형태로 이루어져야 하고, 응답은 GeoServer -> WAS -> 클라이언트로 이루어지게 된다.

물론, WAS까지 도달하지 않고 특정 URL 요청시 WEB 서버의 프록시에서 GeoServer로 연결할 수 있지만 이번에는 WAS를 통해서 GeoServer로 요청 및 응답할 수 있도록 구현하였다.

 

WAS에서 구현한 proxy 소스를 첨부한다.

아래 소스는 /proxy.do를 호출하면 GeoServer로 요청하고 응답을 받아 결과를 내려준다.

소스

/**
 * 프록시
 */
@RequestMapping(value = "/proxy.do")
public void proxy(HttpServletRequest request, HttpServletResponse response, ModelMap model) {
	CommonVO vo = new CommonVO(request);
	String result = "";

	try {
	String geoServerUrl = GEOSERVER_URL;
	String geoUrl = geoServerUrl + vo.get("geoServerUrl").toString();
	URL url = new URL(geoUrl); 

        URLConnection urlConn = url.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "UTF-8"));
        String inputLine;
        StringBuffer sb = new StringBuffer();

        while ((inputLine = in.readLine()) != null) { 
            sb.append(inputLine);
        }
        in.close();
        
        result = sb.toString();
        response.setContentType("application/json");
        response.getOutputStream().write(result.getBytes("UTF-8"));

	} catch (Exception e) {
		e.printStackTrace();
	}
}

 

웹 브라우져에서 WAS로 /proxy.do 호출하게 되면 관련 정보를 안고 GeoServer로 call을 하게 되며 응답을 받게 된다.

WFS만 사용하기에는 위 소스도 문제는 없으나 WMS도 함께 사용하기 위해서 소스를 추가 수정하였다.

아래의 소스는 WFS, WMS 2가지 타입으로 요청 및 응답할 수 있도록 추가 수정 및 개발하였다.

	/**
	 * GeoServer Proxy WFS/WMS
	 */
	@RequestMapping(value = "/proxy.do")
	public void proxy(HttpServletRequest request, HttpServletResponse response) throws Exception{
		CommonVO vo = new CommonVO(request);
		String service = vo.get("service").toString();
		String geoServerUrl = GEOSERVER_URL;
		
		if(service.equals("WFS")){
			BufferedReader in = null;
			try{
				
				geoServerUrl += "/ows?service=WFS&version=1.0.0&request=GetFeature&outputFormat=application/json&srsName=EPSG:5179";
				geoServerUrl += "&";
				geoServerUrl += "typeName="+vo.get("typeName").toString();
				geoServerUrl += "&";
				geoServerUrl += vo.get("viewParams").toString();
				String geoUrl = geoServerUrl; 
				
				URL url = new URL(geoUrl); 
		        URLConnection urlConn = url.openConnection();
		        in = new BufferedReader(new InputStreamReader(urlConn.getInputStream(), "UTF-8"));
		        
		        String inputLine;
		        StringBuffer sb = new StringBuffer();
	
		        while ((inputLine = in.readLine()) != null) {
		            sb.append(inputLine);
		        }
		        response.setContentType("application/json");
		        response.getOutputStream().write((sb.toString()).getBytes("UTF-8"));
		        response.getOutputStream().close();
		        
			}catch(NullPointerException | MemoryLimitException | IllegalArgumentException e){
				LOGGER.error(e.toString());
			}finally{
				if(in != null)
					in.close();
			}
		
		}else if(service.equals("WMS")){
			String geoUrl = geoServerUrl+"/wms?";
			
			if(vo.get("service") != null) 		geoUrl += "service="+vo.get("service").toString();
			if(vo.get("version") != null) 		geoUrl += "&version="+vo.get("version").toString();
			if(vo.get("request") != null) 		geoUrl += "&request="+vo.get("request").toString();
			if(vo.get("layers") != null) 		geoUrl += "&layers="+vo.get("layers").toString();
			if(vo.get("bbox") != null) 			geoUrl += "&bbox="+vo.get("bbox").toString();
			if(vo.get("width") != null) 		geoUrl += "&width="+vo.get("width").toString();
			if(vo.get("height") != null) 		geoUrl += "&height="+vo.get("height").toString();
			if(vo.get("srs") != null) 			geoUrl += "&srs="+vo.get("srs").toString();
			if(vo.get("format") != null) 		geoUrl += "&format="+vo.get("format").toString();
			if(vo.get("transparent") != null) 	geoUrl += "&TRANSPARENT="+vo.get("transparent").toString();
			if(vo.get("sld_body") != null) 	geoUrl += "&sld_body="+vo.get("sld_body").toString();
			if(vo.get("viewparams") != null) 	geoUrl += "&viewparams="+vo.get("viewparams").toString();
			
			RestTemplate rt = new RestTemplate();
			
			DefaultUriTemplateHandler uriTemplateHandler = (DefaultUriTemplateHandler) rt.getUriTemplateHandler();
			uriTemplateHandler.setStrictEncoding(true);
			rt.setUriTemplateHandler(uriTemplateHandler);
			
			byte[] result = rt.getForObject(geoUrl, byte[].class);

			response.setContentType("image/png");
			response.getOutputStream().write(result);
			response.getOutputStream().close();
		}
			
	}

결국 클라이언트에서 파라미터로 담아서 요청하는 service 값에 따라서 WFS 혹은 WMS 요청이 이루어 진다.

 

 

 

 

 

 

 

공유하기

facebook twitter kakaoTalk kakaostory naver band