如何让FreeMarker仅调用带自定义注解的POJO方法?(Spring MVC环境)
如何通过自定义注解限制FreeMarker可调用的POJO方法
当然可以实现!在Spring MVC集成FreeMarker的场景下,你可以通过自定义MemberAccessPolicy(FreeMarker用于控制成员访问权限的核心组件)来过滤只有带指定注解的方法才能被模板调用,完美解决继承导致的方法可见性无法通过私有修饰符限制的问题。
下面是具体的实现步骤和代码示例:
1. 确认自定义注解定义
首先确保你的@CustomAnnotationOnValidMethods注解是运行时可识别的(如果还没定义,参考以下代码):
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface CustomAnnotationOnValidMethods { }
2. 实现自定义MemberAccessPolicy
创建一个自定义的MemberAccessPolicy,重写方法访问检查逻辑,只允许带有目标注解的方法被FreeMarker调用:
import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.MemberAccessPolicy; import java.lang.reflect.Method; public class AnnotationBasedMemberAccessPolicy implements MemberAccessPolicy { @Override public boolean isMethodAccessible(Method method, BeansWrapper wrapper) { // 仅允许带有@CustomAnnotationOnValidMethods注解的方法被访问 return method.isAnnotationPresent(CustomAnnotationOnValidMethods.class); } @Override public boolean isFieldAccessible(java.lang.reflect.Field field, BeansWrapper wrapper) { // 若不需要限制字段访问,直接返回true;如需限制可自定义逻辑 return true; } }
3. 配置Spring的FreeMarkerConfigurer
在Spring配置类中,定制FreeMarker的ObjectWrapper,将我们的自定义MemberAccessPolicy注入进去:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import freemarker.ext.beans.BeansWrapperBuilder; import freemarker.template.Configuration; import java.util.Map; @Configuration public class FreeMarkerConfig { @Bean public FreeMarkerConfigurer freeMarkerConfigurer() { FreeMarkerConfigurer configurer = new FreeMarkerConfigurer(); configurer.setTemplateLoaderPath("/WEB-INF/templates/"); // 构建自定义BeansWrapper并设置权限策略 BeansWrapperBuilder wrapperBuilder = new BeansWrapperBuilder(Configuration.VERSION_2_3_32); wrapperBuilder.setMemberAccessPolicy(new AnnotationBasedMemberAccessPolicy()); configurer.setFreemarkerSettings(Map.of( Configuration.OBJECT_WRAPPER, wrapperBuilder.build() )); return configurer; } }
注意:请根据项目依赖的FreeMarker版本调整
Configuration.VERSION_XXX参数,确保版本匹配。
4. 验证效果
配置完成后,你的模板会出现以下效果:
${view.valid_value}可以正常调用,因为getValid_value()带有@CustomAnnotationOnValidMethods注解${view.invalid_value}会触发访问权限异常(或根据FreeMarker错误配置返回空值),因为该方法没有目标注解
补充说明
- 如果需要允许父类中带注解的方法被访问,可以在
isMethodAccessible中额外检查父类方法的注解逻辑;当前配置已满足你只允许子类带注解方法调用的需求。 - 若使用Spring Boot,配置逻辑一致,也可以通过
application.properties配合自定义Bean完成配置。
内容的提问来源于stack exchange,提问作者Gábor DANI
相关产品推荐
相关产品推荐

