实体 getter setter 生成问题,页面通过指令取值为空的情况

 

 

项目中使用springboot2.x + enjoy4.2 渲染界面时发现 由于 实体首字母小写,生成的gettersetter方法问题 导致在页面上取值为空的情况。

 

如:实体类

package com.jfinal.template;
 
public class Proceeding {
        
         private   String fName ;
         private   String fDepartmentId ;
        
         public   String getfName() {
                  return   fName;
         }
         public   void setfName(String fName) {
                  this.fName   = fName;
         }
         public   String getfDepartmentId() {
                  return   fDepartmentId;
         }
         public   void setfDepartmentId(String fDepartmentId) {
                  this.fDepartmentId   = fDepartmentId;
         }
        
}


 

外部使用enjoy

package com.jfinal.template;
 
import java.util.HashMap;
import java.util.Map;
 
import org.junit.Test;
 
public class PrintTest {
 
         @Test         public   void query() {
                  Proceeding   proceeding = new Proceeding();
                  proceeding.setfName("固定资产投资项目节能审查");
                  proceeding.setfDepartmentId("ACCF99B7-ACBD-AC92-47D9-CE6698469C58");
                 
                  Map<String,   Object> data = new HashMap<String, Object>();
                  data.put("proceeding",   proceeding);
                 
             Engine engine =   Engine.create("myEngine2");
             engine.setDevMode(true);
             engine.setToClassPathSourceFactory();
             Template template =   engine.getTemplate("p.txt");
             String wxAppMsg =   template.renderToString(data);
            
             System.out.println(wxAppMsg);
         }
}


 

页面:

#(proceeding)
 
<tr>
      <td>事项名称<span>*</span></td>
      <td><span>#(proceeding.fName??"暂无")</span></td>
      <td>事项编码</td>
      <td>#(proceeding.fDepartmentId??"暂无")</td>
</tr>


 

渲染结果:

com.jfinal.template.Proceeding@4b952a2d
 
<tr>
      <td>事项名称<span>*</span></td>
      <td><span>暂无</span></td>
      <td>事项编码</td>
      <td>暂无</td>
</tr>


 

跟踪源码发现enjoy在取值时通过 get + 表达式字段组装出(首字母做大大写转换)get方法名” 去匹配 实体中的getter方法来取值。

public FieldGetter takeOver(Class<?> targetClass, String fieldName) {
            if (MethodKit.isForbiddenClass(targetClass)) {
                throw new RuntimeException("Forbidden class: " + targetClass.getName());
            }
            
            String getterName = "get" + StrKit.firstCharToUpperCase(fieldName);
            java.lang.reflect.Method[] methodArray = targetClass.getMethods();
            for (java.lang.reflect.Method method : methodArray) {
                if (method.getName().equals(getterName) && method.getParameterTypes().length == 0) {
                    // if (MethodKit.isForbiddenMethod(getterName)) {
                        // throw new RuntimeException("Forbidden method: " + getterName);
                    // }
                    
                    return new GetterMethodFieldGetter(method);
                }
            }
            
            return null;
        }

 其中:

String getterName = "get" + StrKit.firstCharToUpperCase(fieldName);


 

如我的实体中 enjoy 组装出来的 get方法分别为 getFName 而实体中生成的为 getfName 这样就匹配不上了,值也就取不到了。

 

虽然在返回页面前先把实体转map可以解决问题,但本人涉及的项目实体较多都是这种情况。是否有其他的解决办法嗯?


另外尝试过修改enjoy源码为下所示,能够取值,波总这种方式是否可行嗯?

public FieldGetter takeOver(Class<?> targetClass, String fieldName) {
            if (MethodKit.isForbiddenClass(targetClass)) {
                throw new RuntimeException("Forbidden class: " + targetClass.getName());
            }
            
            String getterName = "get" + StrKit.firstCharToUpperCase(fieldName);
            java.lang.reflect.Method[] methodArray = targetClass.getMethods();
            for (java.lang.reflect.Method method : methodArray) {
                if ((method.getName().equals(getterName) && method.getParameterTypes().length == 0)
                    || (method.getName().equals("get"+fieldName) && method.getParameterTypes().length == 0)) {
                    // if (MethodKit.isForbiddenMethod(getterName)) {
                        // throw new RuntimeException("Forbidden method: " + getterName);
                    // }
                    
                    return new GetterMethodFieldGetter(method);
                } 
            }
            
            return null;
        }



评论区

JFinal

2019-06-19 17:38

这个问题最简单的办法就是扩展 FieldGetter ,做一个 MyFieldGetter,大至如下:
public class MyFieldGetter extends FieldGetters.GetterMethodFieldGetter {
...
}

然后在里头填上你自己改进过的 takeOver 方法,最后配置一下:
Engine.addFieldGetter(1, new MyFieldGetter());

注意添加的时候,第一个参数很重要,这个关系到优先级,你的 MyFieldGetter 优先级要高于 GetterMethodFieldGetter,对于 jfinal 4.2 来说传入 1 即可,因为优先级最高的 0 为:RealFieldGetter

你的这个 MyFieldGetter 要配置在 RealFieldGetter 之后最合适,相关源码在 : com.jfinal.template.expr.ast.FieldGetters.java 中,建议看一看

JFinal

2019-06-19 17:39

当然,你也可以不用继承 FieldGetters.GetterMethodFieldGetter,而是继承 FieldGetter,稍多一点代码,不仅要实现 public FieldGetter takeOver(Class targetClass, String fieldName) 方法

还要实现 public Object get(Object target, String fieldName) 方法

JFinal

2019-06-19 17:41

jfinal enjoy 引擎功能极其强大,提供了各种扩展通道,稍微了解一点点代码,解决各类需求极其便利,用不着改代码,用扩展来实现最优雅

寻真宁

2019-06-19 18:27

收到,谢谢 波总,各种扩展 ,很灵活,各类需求确实迎刃而解,非常赞

热门反馈

扫码入社