【问题标题】:Spring controller: How to use property ${..} in @RequestMapping?Spring 控制器:如何在 @RequestMapping 中使用属性 ${..}?
【发布时间】:2017-01-20 14:24:05
【问题描述】:

我已经找到了有答案的问题,但它们对我没有帮助。

我有一个使用 Spring Controller (4.2.5) 和 Spring Security (4.0.2) 的 web servlet 项目。我不使用 Spring Boot。

我的项目运行良好。

但现在我的任务是:
使@RequestMapping(value={"auth/**"} 可配置(将"auth/**" 替换为${dm.filterPattern}

问题:@RequestMapping ${dm.filterPattern} 未解决,尽管 @PropertySource 已处理。

这是 dmConfig.properties 中的 dm.filterPattern 条目:

dm.filterPattern=/auth/*

这是一些基本代码,包含所有 Spring 注释。

控制器:

init() 方法的输出显示 @PropertySource 已正确处理。 env.getProperty("...") 返回正确的值。

@Controller
@PropertySource("classpath:/dmConfig.properties")
@RequestMapping(value ={ "${dm.filterPattern}"})
public class DmProxyController implements ApplicationContextAware
{
    private Environment env;

    @Autowired
    public DmProxyController(Environment env)
    {
        this.env = env;
    }

    @RequestMapping(path={"${dm.filterPattern}"} ,method = RequestMethod.POST)
    protected void doPost(HttpServletRequest customerRequest, HttpServletResponse response)
            throws ServletException, IOException, DmException
    {
           // code for POST request
    }

    @RequestMapping(path={"${dm.filterPattern}"} ,method = RequestMethod.GET)
    protected void doGet(HttpServletRequest customerRequest, HttpServletResponse response)
            throws ServletException, IOException, DmException
    {
           // code for GET request
    }

    @PostConstruct
    public void init() throws ServletException
    {
        RequestMappingHandlerMapping requestMapping=
                (RequestMappingHandlerMapping) appContext.getBean("requestMappingHandlerMapping");

        Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMapping.getHandlerMethods();
        logger.debug("RequestMapping via dm.filterPattern: {}",
                env.getProperty("dm.filterPattern"));
                logger.debug("Handler Methods: {}", handlerMethods.size());

        for (RequestMappingInfo mapInfo : handlerMethods.keySet())
        {
            logger.debug(" Mappinginfo: {} --> {}", mapInfo, handlerMethods.get(mapInfo));
        }
    }
}

带有 bean 定义的类

@Configuration
@PropertySource("classpath:/dmConfig.properties")
@ComponentScan(basePackages = "com.dm.filter, com.dm.controller")
@EnableTransactionManagement(mode = AdviceMode.PROXY, proxyTargetClass = false)
@Import({DmSecurityConfigurer.class, DmWebConfigurer.class})
public class DmRoot
{

}

DispatcherServletInitializer

public class DmDispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
    @Override
    protected Class<?>[] getRootConfigClasses()
    { return new Class[]{DmRoot.class};  }

    @Override
    protected Class<?>[] getServletConfigClasses()
    { return null; }

    @Override
    protected String[] getServletMappings()
    { return new String[]{"/"}; }

    @Override
    protected String getServletName()
    {  return "dmDispatcherServlet";  }

    @Override
    protected void customizeRegistration(ServletRegistration.Dynamic registration)
    {
        super.customizeRegistration(registration);
        registration.setLoadOnStartup(1);
    }
}

WebConfigurer

public class DmWebConfigurer extends WebMvcConfigurerAdapter
{
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry)
    {
        super.addResourceHandlers(registry);
        registry.addResourceHandler("/index.html").addResourceLocations("/");
        registry.setOrder(Integer.MAX_VALUE-5);
    }
}

SecurityWebApplicationInitializer

public class DmSecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer
{
    public DmSecurityWebApplicationInitializer()
    {
        // some logging
    }

    @Override
    protected void beforeSpringSecurityFilterChain(ServletContext servletContext)
    {     // adding own filters   }

    @Override
    protected void afterSpringSecurityFilterChain(ServletContext servletContext)
    {     // adding own filters   }
}

安全配置器

@EnableWebMvc
@EnableWebSecurity
@PropertySource("classpath:dmConfig.properties")
public class DmSecurityConfigurer extends WebSecurityConfigurerAdapter
{

    private static Logger logger = LogManager.getLogger(DmSecurityConfigurer.class.getName());

    @Autowired
    private Environment env;

    @Autowired
    private UserDetailsService dmUserDetailsService;

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception
    {
        String urlPattern = env.getProperty("dm.springSecurityPattern");
        String realmName = env.getProperty("dm.springSecurityRealm");

        httpSecurity.httpBasic().realmName(realmName)
                .and().userDetailsService(dmUserDetailsService)
                .authorizeRequests()
                .antMatchers(urlPattern).authenticated()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable();
    }

}

【问题讨论】:

    标签: java spring-mvc request-mapping


    【解决方案1】:

    PropertySourcesPlaceholderConfigurer 有可能在 spring 上下文中被初始化得比你的控制器晚,因此这些值没有被解析。尝试在下面的根配置文件之一中为 PropertySourcesPlaceholderConfigurer 添加显式 bean 定义;

    @PropertySource("classpath:/dmConfig.properties")
    public class DmWebConfigurer extends WebMvcConfigurerAdapter
    {
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry)
        {
            super.addResourceHandlers(registry);
            registry.addResourceHandler("/index.html").addResourceLocations("/");
            registry.setOrder(Integer.MAX_VALUE-5);
        }
    
        @Bean
        public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            return new PropertySourcesPlaceholderConfigurer();
        }
    }
    

    您可以在 init() 方法中正确查看值的原因是因为在初始化所有 bean 之后调用它,包括 PropertySourcesPlaceholderConfigurer

    【讨论】:

    • 是的,它按照您的描述工作。我已经将 bean 和注释都放到了我定义其他 bean 的类(我的问题中是 DmRoot)。
    猜你喜欢
    • 2012-09-20
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-21
    相关资源
    最近更新 更多