我在带有DeadBolt(2.6.3和2.7.0)的play 2.7服务器上收到异常Could not resolve type id 'path.to.MyClass' as a subtype of [simple type, class java.lang.Object]: no such class found
时,当我尝试在带有@Restrict注释的路由操作中将JSON反序列化为Map<String, MyClass>
时。如果删除此注释,一切正常。
MyClass.java
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, property = "class")
public class MyClass implements Serializable {
public String name;
public Integer age;
public MyClass(){}
public MyClass(String name, Integer age){
this.name = name;
this.age = age;
}
}
序列化Map<String, MyClass>
Map<String, MyClass> value = new HashMap<>();
value.put("first", new MyClass("Bob",10));
value.put("second", new MyClass("Rob",20));
ObjectMapper mapper = Json.newDefaultMapper();
mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, "class");
String json = null;
try {
json = mapper.writeValueAsString(value);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
输出
{
"first":{
"class":"path.to.MyClass",
"name":"Bob",
"age":10
},
"second":{
"class":"path.to.MyClass",
"name":"Rob",
"age":20
}
}
JSON格式之所以如此,是因为它与使用旧FlexJson的旧服务器向后兼容。
反序列化
@Restrict({@Group({"Admin"})})
public CompletionStage<Result> action(long id) {
String json = getJsonFromStorage();
Map<String, MyClass> result = new HashMap<>();
try {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, "class");
JsonFactory factory = mapper.getFactory();
JsonParser parser = factory.createParser(new ByteArrayInputStream(json.getBytes(Charset.forName("UTF-8"))));
JavaType type = mapper.getTypeFactory().constructType(result.getClass());
t = mapper.readValue(parser, type);
} catch (IOException e) {
e.printStackTrace();
}
return ok("ok")
}
答案 0 :(得分:0)
我有一个临时解决方案。我将当前线程的class loader覆盖为play.Environment
public class MyController extends Controller {
@Inject
private Environment environment;
@Restrict({@Group({"Admin"})})
public CompletionStage<Result> action(long id) {
Thread.currentThread().setContextClassLoader(environment.classLoader());
String json = getJsonFromStorage();
Map<String, MyClass> result = new HashMap<>();
try {
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTypingAsProperty(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE, "class");
JsonFactory factory = mapper.getFactory();
JsonParser parser = factory.createParser(new ByteArrayInputStream(json.getBytes(Charset.forName("UTF-8"))));
JavaType type = mapper.getTypeFactory().constructType(result.getClass());
t = mapper.readValue(parser, type);
} catch (IOException e) {
e.printStackTrace();
}
return ok("ok")
}
}