Spring控制器:如何在@RequestMapping中使用属性$ {..}?

时间:2017-01-20 14:24:05

标签: java spring-mvc request-mapping

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

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

我的项目运作正常。

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

问题:@RequestMapping ${dm.filterPattern}尚未解决,但处理了@PropertySource。

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

dm.filterPattern=/auth/*

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

控制器:

方法init()的输出显示我正确处理了@PropertySourceenv.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   }
}

SecurityConfigurer

@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();
    }

}

1 个答案:

答案 0 :(得分:1)

在弹簧上下文中,PropertySourcesPlaceholderConfigurer可能会比控制器稍后初始化,因此值不会被解析。尝试在其中一个根配置文件中添加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之后)调用它。