Geometry型別自定義型別轉換器
WebGIS處理避免不了會用到wkt 字串傳入java後臺轉成Geometry的需求,但是我們以往的作法是後臺直接接受一個字串然後認為進行轉換工作。其實Spring MVC 字串自動對映成物件的處理方便相當方便,但是對於這種Geometry複雜型別是不支援的。其實要其支援也挺簡單的,只要想法辦讓它知道如何進行轉換即可。轉換的思路有兩種一種就是屬性編輯器方式(PropertyEditor),另一種就是轉換器方式(ConversionService)。這兩種方式各有千秋:
PropertyEditor方式,是控制器級別的。ConversionService是全域性性的。
一、使用註解式控制器註冊PropertyEditor(針對具體的controller類處理)
1、使用WebDataBinder進行控制器級別的註冊PropertyEditor(控制器獨享)
1)定義屬性編輯器GeometryEditor
package com.geoway.plan.core.support.propertyeditors;
import java.beans.PropertyEditorSupport;
import org.geotools.geometry.jts.JTSFactoryFinder;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class GeometryEditor extends PropertyEditorSupport {
static GeometryFactory geometryFactory = JTSFactoryFinder
.getGeometryFactory(null);
@Override
public void setAsText(String text) throws IllegalArgumentException {
WKTReader reader = new WKTReader(geometryFactory);
Geometry geom = null;
try {
geom = reader.read(text);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
setValue(geom);
}
}
2)在需要用到Geometry轉換的控制器加入如下程式碼
@InitBinder
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Geometry.class, (PropertyEditor) new GeometryEditor());
}
這樣就可以使實現轉換了
二、通過ConversionService、Converter實現型別轉換(系統全域性轉換器)
1)定義GeometryConversionService轉換服務
package com.geoway.plan.core.support.convert;
import java.util.Set;
import javax.annotation.PostConstruct;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConverterFactory;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.core.convert.support.GenericConversionService;
import com.vividsolutions.jts.geom.GeometryFactory;
public class GeometryConversionService implements ConversionService {
static GeometryFactory geometryFactory = JTSFactoryFinder
.getGeometryFactory(null);
@Autowired
private GenericConversionService conversionService;
private Set<?> converters;
@PostConstruct
public void afterPropertiesSet() {
if (converters != null) {
for (Object converter : converters) {
if (converter instanceof Converter<?, ?>) {
conversionService.addConverter((Converter<?, ?>)converter);
} else if (converter instanceof ConverterFactory<?, ?>) {
conversionService.addConverterFactory((ConverterFactory<?, ?>)converter);
} else if (converter instanceof GenericConverter) {
conversionService.addConverter((GenericConverter)converter);
}
}
}
}
@Override
public boolean canConvert(Class<?> sourceType, Class<?> targetType) {
return conversionService.canConvert(sourceType, targetType);
}
@Override
public boolean canConvert(TypeDescriptor sourceType,
TypeDescriptor targetType) {
return conversionService.canConvert(sourceType, targetType);
}
@Override
public <T> T convert(Object source, Class<T> targetType) {
return conversionService.convert(source, targetType);
}
@Override
public Object convert(Object source, TypeDescriptor sourceType,
TypeDescriptor targetType) {
return conversionService.convert(source, sourceType, targetType);
}
public Set<?> getConverters() {
return converters;
}
public void setConverters(Set<?> converters) {
this.converters = converters;
}
}
2)定義GeometryConverter轉換器
package com.geoway.plan.core.support.convert;
import org.geotools.geometry.jts.JTSFactoryFinder;
import org.springframework.core.convert.converter.Converter;
import org.springframework.util.Assert;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
public class GeometryConverter implements Converter<String, Geometry> {
static GeometryFactory geometryFactory = JTSFactoryFinder
.getGeometryFactory(null);
@Override
public Geometry convert(String source) {
if (source == null || "".equals(source))
return null;
String wkt = source;
WKTReader reader = new WKTReader(geometryFactory);
Geometry geom = null;
try {
geom = reader.read(wkt);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return geom;
}
}
3)配置spring-mvc.xml檔案
<!-- ①註冊自定義ConversionService -->
<mvc:annotation-driven conversion-service="conversionService" />
<!-- 未註冊時,請註冊 genericConversionService-->
<!-- <bean id="genericConversionService" class="org.springframework.core.convert.support.GenericConversionService"/>-->
<bean id="conversionService" class="com.geoway.plan.core.support.convert.GeometryConversionService">
<property name="converters">
<set>
<bean class="com.geoway.plan.core.support.convert.GeometryConverter"/>
</set>
</property>
</bean>
三、controller中部分程式碼
@RequestMapping(value = "/doConflictCheck.do", method = { RequestMethod.POST }, produces = { "application/json;charset=UTF-8" })
@ResponseBody
public BaseResponse doConflictCheck(HttpServletResponse httpResponse,
HttpServletRequest request,
@ModelAttribute PlanConflictcheckTask task) {
BaseObjectResponse response = new BaseObjectResponse();
try {
Object userId = PlanRequestUtil.getLoginUser(request);
task.setUserId(userId != null ? userId.toString() : null);
PlanConflictcheckTask taskResult = conflictcheckService
.saveConflictcheckTask(task);
response.setData(taskResult.getId());// 返回任務ID
} catch (Exception ex) {
ex.printStackTrace();
response.setMessage(ex.getMessage());
response.setStatus(CommonConstants.RESPONSE_STATUS_FAILURE);
logger.error(ex.getStackTrace());
}
return response;
}
@RequestMapping(value = "/postGeometry.do", method = { RequestMethod.POST }, produces = { "application/json;charset=UTF-8" })
@ResponseBody
public BaseResponse postGeometry(HttpServletResponse httpResponse,
HttpServletRequest request,
@RequestParam("geom") Geometry geom) {
……
這兩種方法都適合doConflictCheck方法中的型別轉換需求(PlanConflictcheckTask 中有個欄位Geometry型別欄位);但是postGeometry方法的對於控制器方式會報錯。
前段傳遞的引數
doConflictCheck
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”area”
12
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”proId”
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”projectTYPE”
城市公共服務設施專案
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”landType”
綠地與廣場用地
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”businessType”
能源
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”checkType”
1
——WebKitFormBoundaryNHeZScYVf03Da6Mv
Content-Disposition: form-data; name=”geometry”
POLYGON((109.8640243053 24.586129461128,109.87846004989 24.47064350446,109.98638442606 24.450021012198,110.04069032235 24.509138823349,110.04687707003 24.58475462831,109.99188375733 24.615688366703,109.8640243053 24.586129461128))
——WebKitFormBoundaryNHeZScYVf03Da6Mv–
postGeometry
——WebKitFormBoundaryde1cujNHB5HFMjAa
Content-Disposition: form-data; name=”geom”
POLYGON((109.8640243053 24.586129461128,109.87846004989 24.47064350446,109.98638442606 24.450021012198,110.04069032235 24.509138823349,110.04687707003 24.58475462831,109.99188375733 24.615688366703,109.8640243053 24.586129461128))
——WebKitFormBoundaryde1cujNHB5HFMjAa–