Spring控制器:如何在@RequestMapping中使用属性$ {..}? [英] Spring controller: How to use property ${..} in @RequestMapping?
问题描述
我已经找到了带有答案的问题,但对我没有帮助.
I already found questions with answers but they don't help me.
我有一个Web servlet项目,其中使用了Spring Controller(4.2.5)和Spring Security(4.0.2).我不使用Spring Boot.
I have a web servlet project where I use a Spring Controller (4.2.5) and Spring Security (4.0.2). I don't use Spring Boot.
我的项目运行正常.
但是现在我的任务是:
使@RequestMapping(value={"auth/**"}
可配置(用${dm.filterPattern}
替换"auth/**"
)
But now my task is this:
Make @RequestMapping(value={"auth/**"}
configurable (replace "auth/**"
with ${dm.filterPattern}
)
问题:尽管处理了@PropertySource,但仍未解决@RequestMapping
${dm.filterPattern}
中的问题.
Problem: in @RequestMapping
${dm.filterPattern}
isn't resolved, although @PropertySource is processed.
这是dmConfig.properties中的条目dm.filterPattern
:
This is the entry dm.filterPattern
in dmConfig.properties:
dm.filterPattern=/auth/*
这是一些必不可少的代码,带有所有Spring注释.
Here is some essential code, with all Spring annotations.
方法init()
的输出显示@PropertySource
已正确处理. env.getProperty("...")
返回正确的值.
The output of the method init()
shows me that @PropertySource
is processed correctly. env.getProperty("...")
returns correct values.
@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();
}
}
推荐答案
PropertySourcesPlaceholderConfigurer
可能在Spring上下文中的初始化时间比您的控制器晚,因此无法解析这些值.尝试在如下所示的根配置文件之一中为PropertySourcesPlaceholderConfigurer
添加显式Bean定义;
There is a possibility that PropertySourcesPlaceholderConfigurer
is being initialised later in the spring context than your controller and hence the values are not resolved. try adding explicit bean definition for PropertySourcesPlaceholderConfigurer
in one of the root configuration file as below;
@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()
方法中正确看到这些值,是因为在包括PropertySourcesPlaceholderConfigurer
在内的所有bean都初始化之后,将调用该值.
The reason you can see the values properly in your init()
method is because it is called after all the beans are initialised including PropertySourcesPlaceholderConfigurer
.
这篇关于Spring控制器:如何在@RequestMapping中使用属性$ {..}?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!