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中,我也尝试了资源的路径配置,也尝试过没去配置,反正都没有显示,试了两天了也没出效果,所以在此集思广益

  • 6
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,关于你的问题,我可以给你一些思路和代码示例。 首先,拦截器可以通过实现`HandlerInterceptor`接口来定义。具体实现如下: ```java @Component public class UserInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 在请求处理之前进行拦截,可以在这里获取用户信息 User user = (User) request.getSession().getAttribute("user"); // 假设用户信息存在session中 if (user == null) { response.sendRedirect("/login"); // 如果用户未登录,则跳转到登录页面 return false; } return true; } // 其他方法省略 } ``` 以上代码中,我们通过实现`preHandle`方法,在请求处理之前进行拦截。在这个方法中,我们可以通过`HttpServletRequest`对象获取到当前请求的信息,比如请求头、请求参数、Session等信息。如果我们在登录时将用户信息存储在Session中,那么我们可以通过`request.getSession().getAttribute("user")`来获取当前登录用户的信息。 接下来,我们需要将拦截器注册到Spring Boot中。这可以通过在配置类中添加`@Bean`注解来完成。具体实现如下: ```java @Configuration public class InterceptorConfig implements WebMvcConfigurer { @Autowired private UserInterceptor userInterceptor; @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(userInterceptor).addPathPatterns("/**").excludePathPatterns("/login", "/register"); // 设置拦截的路径 } } ``` 以上代码中,我们通过实现`WebMvcConfigurer`接口,将拦截器注册到Spring Boot中。我们使用`addInterceptors`方法来添加拦截器,并通过`addPathPatterns`方法来指定需要拦截的路径。在这里,我们设置拦截所有路径,但是排除了登录和注册页面,因为这些页面不需要用户登录即可访问。 最后,需要注意的是,我们在拦截器中获取用户信息时,需要确保用户已经登录。如果用户未登录,则需要将请求重定向到登录页面

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值