在Spring MVC GET请求中将Json属性名称转换为实体属性名称
嗨我有一个应用程序正在使用SpringDataNeo4j,Spring MVC ... 我有以下类作为示例。一个是实体,另一个是JSON对象。在Spring MVC GET请求中将Json属性名称转换为实体属性名称
@NodeEntity(label="MyBean")
public class MyBean() {
@Property(name = "my_name")
String my_name;
@Property(name = "last_modified_by")
String last_modified_by;
//setter & getters
}
。
@JsonRootName("myBean")
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class MyBeanData {
String myName;
String lastModifiedBy;
//setter getters
}
这是我的Spring MVC控制器的请求处理程序:
@RequestMapping(value = "/test", method = RequestMethod.GET)
public List<MyBeanData> getMyBeans(@RequestParam(name = "sortDir", required = false) String sortDir,
@RequestParam(name = "sortProp", required = false) String sortProp){
//execute the Custom query to get all mybeans sorted by sortProp
}
现在我的问题是,在“sortProp”所用的属性名称是JSON对象属性的名称,例如“lastModifiedBy”。 ..排序查询不适用于json属性名称,只有在使用实体属性名称时才起作用。在执行查询之前,是否有简单的&干净的方式将单个json属性NAME转换为对应的实体属性NAME?我不想在下面的转换器方法中添加如此多的实体。
public String converter(String sortProp){
if("lastModifiedBy".equals(sortPro)){
return "last_modified_by"
}
}
首先,你并不需要使用很多,如果/别人的,即使你要反复比较字符串,就可以对字符串进行切换:
switch (sortPro) {
case "lastModifiedBy": return "last_modified_by";
// ...
}
然而,最简单的方法存储映射和执行转换是使用Map<String, String>
:
private static final Map<String, String> SORT_FIELD_MAP;
static {
Map<String, String> sortFieldMap = new HashMap<>();
sortFieldMap.put("lastModifiedBy", "last_modified_by");
// ...
SORT_FIELD_MAP = Collections.unmodifiableMap(sortFieldMap);
}
public String converter(String sortProp) {
return SORT_FIELD_MAP.get(sortProp);
}
(获自Guava或等效或者使用不可改变的集合)
我发布这个答案只是弗兰克建议的替代实现。
因此,这里是我做的步骤: 使用Reflection library在这里,我创建了一个地图,其中的:
- 关键是 - >使用@Property注释的所有字段的名称
- 价值是 - >所有属性的属性值
BeanPackage是我们要扫描的类的包路径。
@PostConstruct
private void init() {
List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(
new SubTypesScanner(false /* don't exclude Object.class */),
new ResourcesScanner(),
new FieldAnnotationsScanner())
.setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
.filterInputsBy(new FilterBuilder().include(FilterBuilder.prefix(beanPackage))));
Set<Field> fields = reflections.getFieldsAnnotatedWith(Property.class);
fields.forEach(field -> jsonToEntityMap.put(field.getName(), field.getAnnotation(Property.class).name()));
由于您有一个'Map
我没有碰撞,属性名称始终是由'_'版本的json属性分隔的降低的情况。所以即使在重复的情况下,他们也会有正确的映射。但是,如果发生碰撞,您的选择就是解决方案。 – Lina
有什么办法可以用这个杰克逊呢?只是好奇......我已经有了实体和JSON对象..所以我想也许我们已经实现了一个解决方案。我有这么多的班级,所以我不想完成所有的课程并添加转换器... – Lina
我不明白,杰克逊不关心将DTO映射到实体。然而,您可以使用自己的一套注释开发自己的解决方案来注册映射:注释DTO的字段,使用转换服务注册这些类,转换服务将反省它们并存储每个类的映射(映射图) ,然后只需使用类和排序属性的名称来调用服务。我不知道已经有这样做的解决方案。 –
谢谢@Frank。我将使用您建议的实现 – Lina