You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:04:19