Geomesa Accumulo无需用户账户的字段级可见性Java编程实现求助
GeoMesa字段级可见性Java实现方案
一、Schema定义阶段配置字段默认可见性
在创建SimpleFeatureType时,通过用户数据为每个字段绑定默认可见性标签,适用于固定权限规则的场景:
import org.geotools.feature.simple.SimpleFeatureTypeBuilder; import org.opengis.feature.simple.SimpleFeatureType; // 构建FeatureType SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder(); builder.setName("myFeature"); builder.setNamespaceURI("http://geomesa.org"); // 几何字段+默认可见性"public" builder.add("geom", org.locationtech.jts.geom.Point.class); builder.userData().put("geomesa.visibility.field.geom", "public"); // 属性字段1+默认可见性"internal" builder.add("attr1", String.class); builder.userData().put("geomesa.visibility.field.attr1", "internal"); // 属性字段2+默认可见性"admin" builder.add("attr2", Integer.class); builder.userData().put("geomesa.visibility.field.attr2", "admin"); SimpleFeatureType sft = builder.buildFeatureType(); // 注册到数据存储 dataStore.createSchema(sft);
二、写入阶段动态设置字段可见性
针对API后端多因素权限的需求,可在写入Feature时根据请求上下文(如用户角色、业务规则)动态分配可见性:
import org.geotools.feature.simple.SimpleFeatureBuilder; import org.locationtech.geomesa.security.VisibilityUtils; import org.opengis.feature.simple.SimpleFeature; SimpleFeatureBuilder featureBuilder = new SimpleFeatureBuilder(sft); featureBuilder.set("geom", targetGeometry); featureBuilder.set("attr1", "sampleValue"); featureBuilder.set("attr2", 456); SimpleFeature feature = featureBuilder.buildFeature("fid-001"); // 动态获取可见性标签(示例:从API上下文提取权限) String geomVis = getGeomVisibilityFromContext(); // 如返回"public" String attr1Vis = getAttr1VisibilityFromContext(); // 如返回"internal" String attr2Vis = getAttr2VisibilityFromContext(); // 如返回"admin" // 为字段绑定可见性 VisibilityUtils.setFieldVisibility(feature, "geom", geomVis); VisibilityUtils.setFieldVisibility(feature, "attr1", attr1Vis); VisibilityUtils.setFieldVisibility(feature, "attr2", attr2Vis); // 写入数据 dataStore.addFeature(feature);
三、查询阶段过滤可见性字段
查询时通过允许的可见性标签集合,筛选出用户有权限访问的字段:
import org.geotools.data.Query; import org.geotools.filter.text.ecql.ECQL; import org.locationtech.geomesa.security.VisibilityFilter; import org.opengis.filter.Filter; // 基础空间过滤条件 Filter baseFilter = ECQL.toFilter("BBOX(geom, -180, -90, 180, 90)"); // 从API上下文获取用户允许的可见性标签 Set<String> allowedVisTags = getAllowedVisibilityTags(); // 如{"public", "internal"} // 构建可见性过滤规则 Filter visibilityFilter = VisibilityFilter.fieldVisibilityFilter(allowedVisTags); // 组合过滤条件 Filter combinedFilter = ECQL.toFilter(ECQL.toCQL(baseFilter) + " AND " + ECQL.toCQL(visibilityFilter)); // 构建查询,可手动指定返回字段(可选,自动过滤不可见字段) Query query = new Query(sft.getTypeName(), combinedFilter); // 可选:只返回有权限的字段 List<String> visibleFields = getVisibleFields(allowedVisTags, sft); query.setPropertyNames(visibleFields.toArray(new String[0])); // 执行查询 try (SimpleFeatureIterator iterator = dataStore.getFeatureReader(query, Transaction.AUTO_COMMIT)) { while (iterator.hasNext()) { SimpleFeature feature = iterator.next(); // 处理结果:不可见字段会被置为null或直接过滤 System.out.println("返回Feature: " + feature); } }
四、排查"配置后无数据返回"问题
如果配置可见性后查不到数据,优先检查以下几点:
- 查询时传入的
allowedVisTags是否与写入时设置的可见性标签完全匹配(注意大小写)。 - 查看Schema的用户数据,确认
geomesa.visibility.field.*键值对是否正确注册:dataStore.getSchema(sft.getTypeName()).getUserData()。 - 确认使用的GeoMesa版本≥2.0(字段级可见性从该版本开始支持)。
- 检查写入时是否正确调用
VisibilityUtils.setFieldVisibility,未设置的字段会继承Schema默认可见性,若默认标签不在查询允许集合中也会被过滤。
内容的提问来源于stack exchange,提问作者keith
相关产品推荐
相关产品推荐

