没有 XML 的 Java Spring 拦截器

Posted

技术标签:

【中文标题】没有 XML 的 Java Spring 拦截器【英文标题】:Java Spring Interceptor with no XML 【发布时间】:2017-03-21 06:24:12 【问题描述】:

我了解可以配置一个 Spring 应用程序without the use of XML config files,并已提交此方法。但是,我不确定如何以这种方式声明HTTP interceptors。我正在使用this tutorial,它声明了以下 XML。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/welcome.htm">welcomeController</prop>
            </props>
        </property>
        <property name="interceptors">
            <list>
                <ref bean="maintenanceInterceptor" />
                <ref bean="executeTimeInterceptor" />
            </list>
        </property>
    </bean>

    <bean
    class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping">
        <property name="interceptors">
            <list>
                <ref bean="executeTimeInterceptor" />
            </list>
        </property>
    </bean>

    <bean id="welcomeController"
                  class="com.mkyong.common.controller.WelcomeController" />
    <bean class="com.mkyong.common.controller.MaintenanceController" />

    <bean id="executeTimeInterceptor"
                 class="com.mkyong.common.interceptor.ExecuteTimeInterceptor" />

    <bean id="maintenanceInterceptor"
                class="com.mkyong.common.interceptor.MaintenanceInterceptor">
        <property name="maintenanceStartTime" value="23" />
        <property name="maintenanceEndTime" value="24" />
        <property name="maintenanceMapping" value="/SpringMVC/maintenance.htm" />
    </bean>

    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix">
            <value>/WEB-INF/pages/</value>
        </property>
        <property name="suffix">
            <value>.jsp</value>
        </property>
    </bean>

</beans>

如何在 Java 中做到这一点?没有@Interceptor注解。

SpringApplication.java

@SuppressWarnings("WeakerAccess")
@SpringBootApplication
@PropertySources(value = @PropertySource("classpath:/application.properties"))

public class SpringbackendApplication 

    @Autowired
    Environment env;

    public static void main(String[] args) 
        SpringApplication.run(SpringbackendApplication.class, args);
        initializeFirebase();
    

    @Bean
    public ViewResolver getViewResolver() 
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    

    @Bean
    public UserController userController() 
        UserController userController = new UserController(getUserDAO(), getYodleeDAO());
        userController.setCobrandSession(cobrandSession());
        userController.setUserSessionManager(userSessionManager());
        userController.setAccountsService(accountsService());
        userController.setTransactionsService(transactionsService());
        return userController;
    

    @Bean
    public TestController testController() 
        TestController testController = new TestController();
        testController.setCobrandSession(cobrandSession());
        testController.setUserSessionManager(userSessionManager());
        testController.setAccountsService(accountsService());
        testController.setTransactionsService(transactionsService());
        return testController;
    

    @Bean
    public CobrandSession cobrandSession() 
        CobrandSession cobrandSession = new CobrandSession();
        cobrandSession.setApiBase(this.env.getProperty("API_BASE"));
        cobrandSession.setLogin(this.env.getProperty("LOGIN"));
        cobrandSession.setPassword(this.env.getProperty("PASSWORD"));
        cobrandSession.setLocale(this.env.getProperty("LOCALE"));
        cobrandSession.setRestTemplate(restTemplate());
        cobrandSession.setGson(gson());
        return cobrandSession;
    

    @Bean
    public AccountsService accountsService() 
        AccountsService accountsService = new AccountsService();
        accountsService.setApiBase(this.env.getProperty("API_BASE"));
        accountsService.setRestTemplate(restTemplate());
        accountsService.setGson(gson());
        return accountsService;
    

    @Bean
    public RestTemplate restTemplate() 
        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
        factory.setOutputStreaming(false); // If we don't turn this off, we may get HttpRetryException on 401's.
        return new RestTemplate(factory);
    

    @Bean
    public Gson gson() 
        return new Gson();
    


【问题讨论】:

您可以在您的应用程序类上添加@EnableAutoConfiguration,然后创建另一个扩展WebMvcConfigurerAdapter 的类。然后覆盖它的addInterceptors() 方法 将扩展WebMvcConfigurerAdapter 确保addInterceptors() 运行,还是我必须从任何地方调用它? 它应该 :) 当你用 @EnableAutoConfiguration 或类似的注释(来自配置“family”)标记你的主类(使用 @SpringBootApplication )时,你告诉 spring 搜索配置类 - 他们用例如注释@Configuration 注释。您可以使用@ComponentScan 来告知应针对配置类扫描哪个打包。请参考docs.spring.io/autorepo/docs/spring-boot/current/reference/html/… 【参考方案1】:

要将 XML 文件中定义的 Spring bean 移动到配置类(标有 @Configuration),您需要以下内容:

@Configuration
public class MyConfig 
    @Bean(name="executeTimeInterceptor")
    public ExecuteTimeInterceptor getExecuteTimeInterceptor() 
        return new com.mkyong.common.interceptor.ExecuteTimeInterceptor();
    

    @Bean(name="maintenanceInterceptor")
    public MaintenanceInterceptor getMaintenanceInterceptor(@Value("$properties.maintenanceStartTime") int maintenanceStartTime,
                                                            @Value("$properties.maintenanceEndTime") int maintenanceEndTime,
                                                            @Value("$properties.maintenanceMapping") String maintenanceMapping) 

        MaintenanceInterceptor myInt = new MaintenanceInterceptor();
        myInt.setMaintenanceStartTime(maintenanceStartTime);
        myInt.setmMaintenanceEndTime(maintenanceEndTime);
        myInt.setMaintenanceMapping(maintenanceMapping);
        return myInt;
    

...然后在类路径上的一些propertiesFile.properties 中添加这些...

properties.maintenanceStartTime=23
properties.maintenanceEndTime=24
properties.maintenanceMapping=/SpringMVC/maintenance.htm

编辑

我看到你正在从Environment 中获取你的道具,所以不要使用@Value 注入,而是使用你现在在代码中的方式。

【讨论】:

【参考方案2】:

你必须重写 WebMvcConfigurerAdapter.addInterceptors() 方法并添加你的拦截器:

@Override
public void addInterceptors(InterceptorRegistry registry) 
    registry.addInterceptor(new CustomInterceptor());
 

别忘了用@Configuration标记你的班级

【讨论】:

我目前有一个应用程序类,我在其中声明了我所有的@Bean。我想这是我要覆盖的类? 你能粘贴你的代码吗?你在用弹簧靴吗? 发布了我的主要课程

以上是关于没有 XML 的 Java Spring 拦截器的主要内容,如果未能解决你的问题,请参考以下文章

AngularJS 和 Spring MVC 安全性

java filter 拦截器 怎么设置为在Spring框架的DispatcherServlet之前执行?

SpringBoot_拦截器

P1020 导弹拦截

Spring Security XML 配置与 Java 配置

SpringMVC的AJAX请求报406错误