受 Deadbolt“限制”注释影响的 Jackson 解串器
Posted
技术标签:
【中文标题】受 Deadbolt“限制”注释影响的 Jackson 解串器【英文标题】:Jackson deserialiser affected by the Deadbolt "restrict" annotation 【发布时间】:2019-05-20 07:56:41 【问题描述】:当我尝试在带有 @Restrict 注释的路由操作内将 JSON 反序列化为 Map<String, MyClass>
时,我在使用 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
。如果删除此注释,一切正常。
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")
【问题讨论】:
类加载器中的问题。如果使用 @Restrict 注释,它会被覆盖。为什么? Ebean throwjava.util.concurrent.CompletionException
for Ebean.findNative(clazz, hql).findCount()
和其他类似的 Ebean 请求在有限制的控制器操作中
【参考方案1】:
我有一个临时解决方案。我将当前线程的类加载器从 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")
【讨论】:
以上是关于受 Deadbolt“限制”注释影响的 Jackson 解串器的主要内容,如果未能解决你的问题,请参考以下文章
Play Framework中的Silhouette和Deadbolt 2有啥区别