PlayFramework 2.5 - 使用反射

时间:2016-07-29 09:17:36

标签: java reflection playframework orm ebean


我正在开发一个使用Play框架2.5和Ebean作为ORM的内联编辑器的网站,我有一个新闻部分,管理员可以编辑每一条新闻(内联编辑字段,如标题,内容等)。登记/> 为了做到这一点,我设置了每个可以用id等于新闻模型字段修改的html元素(例如,映射字段标题的html元素将具有id =" title"),然后当我从客户端接收数据,我使用控制器上的反射来映射每个内容和正确的新闻字段。

以下是代码(EditContent是一个对象,其中包含每个修改内容的id和htmlContent等信息):

News news = News.find.byId(newsId);

for(EditContent content : pageContents.contents) {
    Field field = news.getClass().getField(content.cssId);
    field.setAccessible(true);
    field.set(news, content.htmlContent);
}

news.update();

问题是似乎执行了更新,但实际上没有在db上更新值。使用调试器,我检查了对象新闻,我可以看到字段被正确修改,但是更新对db没有影响。
另外,我注意到使用相同的代码:

News news = new News()
...
//reflection to save modifed contents in the new object
...
news.save()

按预期工作,在数据库中保存一个新行。

有什么想法吗?

提前感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

您正在设置字段值,而不是调用setter方法。

因此对于update()... Ebean不知道哪些属性已被更改 - 它认为没有更改。

播放通过增强功能将字段调用修改为方法调用。因此,这可能是您认为这些反射字段集值可能有效的原因。

答案 1 :(得分:0)

基本上,就像@Rob Bygrave所说的那样......应该在这里调用setter方法,而不是直接设置字段值,因为如果直接将值设置为相应字段,ebean将忽略新值。似乎遵循Java bean约定的play框架,所以基本上我们可以猜出集合名称的名称。 以下是动态更新用户信息的示例代码:

private final String[] userUpdatableNames = { "name", "password", "allowGPS" };

...

        JsonNode dateForm = request().body().asJson();
        Field field;
        Class<?> type;
        Method method;      
        for (int i = 0; i < userUpdatableNames.length; i++) {
            if (isArgs[i]) {
                        try {
                            field = target.getClass().getDeclaredField(userUpdatableNames[i]);
                            type = field.getType();
                            Method method = target.getClass().getMethod("set" + initialUpperize(userUpdatableNames[i]), type);
                            method.invoke(target, convert(type,dateForm.findValue(userUpdatableNames[i]).textValue()));
                            }catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException
| NoSuchMethodException | InvocationTargetException e) {
                            return internalServerError(Json.toJson("Invoke exception"));
                           }
            } 
      }

...

public String initialUpperize(String str) {
    return str.substring(0, 1).toUpperCase() + str.substring(1);
}

...

private Object convert(Class<?> targetType, String text) {
    PropertyEditor editor = PropertyEditorManager.findEditor(targetType);
    editor.setAsText(text);
    return editor.getValue();
}

其中isArgs是一个布尔数组,用于标记该字段是否在Json体中...

谢谢