Spring控制器:如何在@RequestMapping中使用属性${..}?
Spring controller: How to use property ${..} in @RequestMapping?
我已经找到了有答案的问题,但它们对我没有帮助。
我有一个 web servlet 项目,我在其中使用 Spring 控制器 (4.2.5) 和 Spring 安全 (4.0.2)。我不使用 Spring Boot.
我的项目运行良好。
但现在我的任务是:
使 @RequestMapping(value={"auth/**"}
可配置(将 "auth/**"
替换为 ${dm.filterPattern}
)
问题:在 @RequestMapping
${dm.filterPattern}
中未解决,尽管 @PropertySource 已处理。
这是 dmConfig.properties 中的条目 dm.filterPattern
:
dm.filterPattern=/auth/*
这是一些基本代码,带有所有 Spring 注释。
控制器:
方法 init()
的输出显示 @PropertySource
已正确处理。 env.getProperty("...")
returns 正确的值。
@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));
}
}
}
Class 带有 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();
}
}
有可能 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
.
我已经找到了有答案的问题,但它们对我没有帮助。
我有一个 web servlet 项目,我在其中使用 Spring 控制器 (4.2.5) 和 Spring 安全 (4.0.2)。我不使用 Spring Boot.
我的项目运行良好。
但现在我的任务是:
使 @RequestMapping(value={"auth/**"}
可配置(将 "auth/**"
替换为 ${dm.filterPattern}
)
问题:在 @RequestMapping
${dm.filterPattern}
中未解决,尽管 @PropertySource 已处理。
这是 dmConfig.properties 中的条目 dm.filterPattern
:
dm.filterPattern=/auth/*
这是一些基本代码,带有所有 Spring 注释。
控制器:
方法 init()
的输出显示 @PropertySource
已正确处理。 env.getProperty("...")
returns 正确的值。
@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));
}
}
}
Class 带有 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();
}
}
有可能 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
.