SpringBoot用户登陆拦截以及解决页面重定向问题

   SpringBoot的默认启动时,对资源拦截的控制台信息如下:

2018-04-13 10:02:30.090  INFO 78908 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-04-13 10:02:30.090  INFO 78908 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-04-13 10:02:30.157  INFO 78908 --- [  restartedMain] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
其中Spring Boot 默认将 /** 所有访问映射到以下目录:
classpath:/static
classpath:/public
classpath:/resources
classpath:/META-INF/resources
其中默认配置的 /webjars/** 映射到 classpath:/META-INF/resources/webjars/ 

那么当我们自己来实现对静态资源进行拦截控制的时候,就需要在控制类中进行@Configuration注解的配置,与此同时增加@EnableWebMvc,增加该注解之后,默认的WebMvcAutoConfiguration中配置就不会生效,就需要自己完成每一项的控制。当然如果你要更加细粒度以及控制的更精确,那肯定是要对WebMvcAutoConfiguration类了解的更加深入。

控制类代码如下:

@Configuration
@EnableWebMvc //这个注解使得默认配置失效
public class DefineAdapter extends WebMvcConfigurerAdapter implements ApplicationContextAware {
	
	private static final Log logger = LogFactory.getLog(DefineAdapter.class);
    
	private ApplicationContext applicationContext;
	
	public DefineAdapter(){
		super();
	}

	@Bean
        public ViewResolver viewResolver() { 
	    logger.info("ViewResolver"); 
	    InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); 
	    viewResolver.setPrefix("/WEB-INF/views/"); 
	    viewResolver.setSuffix(".jsp"); 
	    return viewResolver; 
       } 
	
	@Override
	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
		 System.out.println("setApplicationContext方法");
	     this.applicationContext = applicationContext;
	}  
	//这里是实现用户拦截的具体操作,类LoginInterceptor是用户登录拦截器
	@Override
        public void addInterceptors(InterceptorRegistry registry) {
             System.out.println("addInterceptors方法"); 
             /*
	  	 *  多个拦截器组成一个拦截器链
		 *  excludePathPatterns 用户排除拦截
		 *  addPathPatterns 用于添加拦截规则 
		 *  拦截规则:除了"/show/getLogin" 其他都拦截
	    * */ 		
           registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/**").excludePathPatterns("/show/getLogin");//多个排除拦截的话,只需要用逗号隔开即可
           //这边还可以加好几个拦截器组成拦截器链
          super.addInterceptors(registry);
       }
	//可以方便的将一个请求映射成视图,无需书写控制器,addViewCOntroller("请求路径").setViewName("请求页面文件路径")
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/show/getLogin").setViewName("login");
	}
	
	//自定义资源拦截路径可以和springBoot默认的资源拦截一起使用,但是我们如果自己定义的路径与默认的拦截重复,那么我们该方法定义的就会覆盖默认配置
        @Override
        public void addResourceHandlers(ResourceHandlerRegistry registry) {
          //这里也可以采用ResourceUtils.CLASSPATH_URL_PREFIX 它是:classpath:
          registry.addResourceHandler("/images/**").addResourceLocations("classpath:/WEB-INF/resources/images/");
          registry.addResourceHandler("/js/**").addResourceLocations("classpath:./WEB-INF/resources/js/");
          registry.addResourceHandler("/css/**").addResourceLocations("classpath:/WEB-INF/resources/css/"); 
          super.addResourceHandlers(registry);  
        }
}

用户登录拦截器:LoginInterceptor

@Service
public class LoginInterceptor extends HandlerInterceptorAdapter{

    protected static final Log logger = LogFactory.getLog(LoginInterceptor.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException{
    	logger.info("------preHandle------");
        //获取session
        HttpSession session = request.getSession(true);
        //判断用户Name是否存在,不存在就跳转到登录界面
        if(request.getParameter("userName") == null){
        	//System.out.println("这是路径地址:"+request.getRequestURI());
        	response.sendRedirect("/show/getLogin");
            return false;
        }else{
        	 session.setAttribute("userName", session.getAttribute("name"));
             return true;
        }
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println(">>>LoginInterceptor>>>>>>>请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println(">>>LoginInterceptor>>>>>>>在整个请求结束之后被调用,也就是在DispatcherServlet 渲染了对应的视图之后执行(主要是用于进行资源清理工作)");
    }
}

界面访问的控制器:PageController

@Controller
@RequestMapping(value = "/show")
public class PageController {
	
    @RequestMapping("/getEditJsp")
    public String editJsp(ModelMap map) {
        return "editUser";
    }
	
    @RequestMapping(value = "/getLogin")
    public String loginJsp(ModelMap map) {
        return "login";
    }
}

当我输入localhost:端口号/show/getEditJsp时候会被拦截,进行判断Session中的内容是否为空,空就跳转到登录界面,此时这边还涉及到了重定向带来的js,css等静态资源无法显示的问题:

配置文件中请如下配置:

  resources:
    #静态资源扫描
    static-locations: classpath:/WEB-INF/resources/ 

当然这个要和原本DefineAdapter中的静态资源拦截一起配合使用,这是我的项目界面和静态资源存放目录:


那么界面中静态资源的引用如下:

  <script src="../js/jquery/jquery-2.1.3.min.js"></script>
   <script src="../js/bootstrap/bootstrap.js"></script>
   <script src="../js/bootstrap/bootstrap.min.js"></script>
   <link rel="stylesheet" type="text/css" href="../css/bootstrap.min.css"/>

   <script type="text/javascript" src="../js/hello.js"></script>

    那好,用户拦截以及重定向静态资源都已解决,但是如果你看我上一章搭配BootStrap使用会发现,原本我使用bootStarp和jquery都是使用maven进行版本管理的,为何现在是手动将js,css文件放置在文件夹下。这个问题是这样的,原本我采用maven进行管理的时候,当用户被拦截重定向到登陆界面之后,我的静态资源一直无法正常显示,试了很多方式,但是好像都没有很好的解决方式,我也不知道怎么解决,如果哪位同志能很好的解决这个问题,欢迎在下面评论以及私聊。

springBoot管理的bootStrap和jquery默认放在resources文件夹下的static的webjars文件夹中,在界面的引用如下:

<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/bootstrap/js/bootstrap.min.js"></script>

<link rel="stylesheet" href="/webjars/bootstrap/css/bootstrap.min.css"/>

我在DefineAdapter中的静态资源拦截是如下配置:

registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/static/webjars/"); 

在application.yml中,我也尝试了资源的路径配置,也尝试过没去配置,反正都没有显示,试了两天了也没出效果,所以在此集思广益

<think>嗯,用户想了解Spring Boot自动配置的例子,我需要先回忆一下Spring Boot自动配置的基本概念。Spring Boot的自动配置是通过条件注解实现的,比如@ConditionalOnClass、@ConditionalOnProperty这些,根据类路径、配置文件等条件自动配置Bean。 我应该找一个典型的例子,比如DataSource的自动配置。用户可能对数据库连接比较熟悉,这个例子比较常见。首先,Spring Boot会根据类路径中是否存在DataSource类,比如HikariCP或者Tomcat JDBC,来自动配置数据源。 然后,用户可能在配置文件中设置了spring.datasource相关的属性,比如URL、用户名、密码,这时候Spring Boot会自动读取这些配置并创建DataSource Bean。如果没有配置,可能会使用内嵌数据库,比如H2,但需要引入对应的依赖。 另外,还可以提到自动配置的开关,比如使用@EnableAutoConfiguration或者排除某些配置。可能还需要解释自动配置的原理,比如spring-boot-autoconfigure模块中的META-INF/spring.factories文件,里面列出了所有的自动配置类。 用户可能想知道具体的代码示例,比如如何查看自动配置的条件评估报告,通过设置debug=true来查看哪些配置类被应用或排除。这可以帮助用户理解自动配置的过程,方便调试。 还要注意结构清晰,分步骤说明,比如先介绍自动配置的基本原理,再举DataSource的例子,然后提到如何自定义和排除配置,最后给出调试方法。这样用户能逐步理解,并且能够实际应用这些知识。 可能需要检查是否有其他常见的自动配置例子,比如Spring MVC的自动配置,比如自动配置ViewResolver、静态资源处理等。但可能例子太多,选DataSource比较典型,用户容易理解。 另外,要确保使用正确的中文术语,比如“条件注解”、“类路径”、“Bean”等,保持技术准确性。同时避免使用过于复杂的术语,让初学者也能明白。 总结一下,回答的结构应该是:先解释自动配置的概念,然后以DataSource为例详细说明,接着讲如何自定义和排除,最后给出调试方法。这样用户能有一个全面的了解,并且知道如何实际操作和验证。</think>Spring Boot的自动配置(Auto-Configuration)是其核心特性之一,它通过条件化配置简化了开发流程。以下是一个逐步解析的示例: --- ### 1. 自动配置的基本原理 Spring Boot通过`@Conditional`系列注解(如`@ConditionalOnClass`、`@ConditionalOnMissingBean`)动态判断是否需要创建某个Bean。例如: ```java @Configuration @ConditionalOnClass(DataSource.class) // 当类路径存在DataSource类时生效 public class DataSourceAutoConfiguration { @Bean @ConditionalOnMissingBean // 当容器中没有DataSource Bean时创建 public DataSource dataSource() { // 根据配置自动生成DataSource } } ``` --- ### 2. 典型示例:数据源(DataSource)自动配置 **步骤1:引入依赖** ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>runtime</scope> </dependency> ``` **步骤2:添加配置** 在`application.properties`中: ```properties spring.datasource.url=jdbc:h2:mem:testdb spring.datasource.username=sa spring.datasource.password= ``` **步骤3:自动生效** Spring Boot会: 1. 检测到类路径存在`DataSource`和H2驱动 2. 读取配置的数据库连接信息 3. 自动创建`DataSource` Bean并注入到应用 --- ### 3. 自定义自动配置覆盖 如果需覆盖默认配置,手动定义Bean即可: ```java @Configuration public class CustomDataSourceConfig { @Bean public DataSource myDataSource() { // 自定义数据源逻辑 return new HikariDataSource(); } } ``` Spring Boot检测到用户自定义Bean后,会跳过自动配置。 --- ### 4. 查看自动配置生效情况 在`application.properties`中添加: ```properties debug=true ``` 启动应用后,控制台会输出: ``` ========================= AUTO-CONFIGURATION REPORT ========================= Positive matches: DataSourceAutoConfiguration matched - @ConditionalOnClass found required classes 'javax.sql.DataSource' Negative matches: RedisAutoConfiguration did not match - @ConditionalOnClass missing required classes 'redis.clients.jedis.Jedis' ``` --- ### 5. 禁用特定自动配置 通过注解排除: ```java @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) ``` 或在配置文件中: ```properties spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration ``` --- ### 总结 Spring Boot自动配置的核心逻辑: 1. 基于**类路径**和**配置文件**动态判断 2. 通过`spring-boot-autoconfigure`模块的`META-INF/spring.factories`定义配置类 3. 开发者可通过自定义Bean或配置灵活覆盖默认行为 这种机制显著减少了样板代码,同时保留了高度可定制性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值