在 Play Framework 中,开启 memcached 后,一些自定义类型的数据可能无法保存到 Cache 中。比如下面的 Java Bean:
public class PermissionBean {
public Boolean allOperation = true; // 完全权限
public Boolean readOperation; // 可读
public Boolean additionOperation; // 可添加
public Boolean editOperation; // 可修改
public Boolean deletionOperation; // 可删除
}
如果将这个 Java Bean 保存到 Cache 中:
PermissionBean permission = new PermissionBean();
Cache.set("permission", permission);
将会出现以下错误:
Cannot cache a non-serializable value of type util.bean.PermissionBean
play.exceptions.CacheException: Cannot cache a non-serializable value of type util.bean.PermissionBean
at play.cache.Cache.checkSerializable(Cache.java:259)
at play.cache.Cache.set(Cache.java:92)
at controllers.SecureAndReady.checkAccessAndReady(SecureAndReady.java:50)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:518)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:511)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:480)
at play.mvc.ActionInvoker.handleBefores(ActionInvoker.java:338)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:143)
at Invocation.HTTP Request(Play!)
Caused by: java.io.NotSerializableException: util.bean.PermissionBean
... 9 more
如果保存包含该 JavaBean 的集合,比如“Map<String, PermissionBean>”、“List<PermissionBean”等,则会报告另外的错误:
NullPointerException occurred : null
play.exceptions.JavaExecutionException
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:229)
at Invocation.HTTP Request(Play!)
Caused by: java.lang.NullPointerException
at net.spy.memcached.transcoders.SerializingTranscoder.encode(SerializingTranscoder.java:166)
at net.spy.memcached.MemcachedClient.asyncStore(MemcachedClient.java:304)
at net.spy.memcached.MemcachedClient.set(MemcachedClient.java:892)
at play.cache.MemcachedImpl.set(MemcachedImpl.java:229)
at play.cache.Cache.set(Cache.java:93)
at util.service.UserService.getPermissions(UserService.java:207)
at controllers.SecureAndReady.checkAccessAndReady(SecureAndReady.java:101)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:518)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:511)
at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:480)
at play.mvc.ActionInvoker.handleBefores(ActionInvoker.java:338)
at play.mvc.ActionInvoker.invoke(ActionInvoker.java:143)
... 1 more
使用 Serializable 进行序列化可解决这类问题:
import java.io.Serializable;
public class PermissionBean implements Serializable {
public Boolean allOperation = true; // 完全权限
public Boolean readOperation; // 可读
public Boolean additionOperation; // 可添加
public Boolean editOperation; // 可修改
public Boolean deletionOperation; // 可删除
}