在SSM项目中使用自定义拦截器来检测用户是否登录。

本文介绍了一种基于Spring MVC的登录拦截器设计方案,通过自定义拦截器验证用户登录状态,未登录用户将被重定向至登录页面,并携带返回地址参数确保登录后能回到原页面。

淘淘商城笔记

1.场景

    凡是和钱有关的操作必须验证用户是否已经登录。以结算为例:当用户选完商品放入购物车后点击去结算这时要验证用户是否已经登录。如果用户已经登录则进入创建订单的页面。如果用户没有登录则跳转到登录页面,登录完成后,返回之前的购物车页面。(京东则是)

2.拦截器

    2.1Service

    先写验证用户是否登录的业务逻辑。其实就是根据cookie去redis中查询用户信息。

package com.taotao.portal.service.impl;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.taotao.common.utils.CookieUtils;
import com.taotao.common.utils.HttpClientUtil;
import com.taotao.common.utils.TaotaoResult;
import com.taotao.pojo.TbUser;
import com.taotao.portal.service.UserService;

/**
 * 用户管理Service(给拦截器调用的) 判断用户是否登录
 * 
 * @author tb 
 * 
 * 由于是在拦截器中调用的,防止抛出异常导致系统崩溃,这里要捕获异常, try catch下整个处理流程
 * 
 */
public class UserServiceImpl implements UserService {

	@Value("${SSO_BASE_URL}")
	private String SSO_BASE_URL;

	@Value("${SSO_USER_TOKEN_SERVICE}")
	private String SSO_USER_TOKEN_SERVICE;

	@Override
	public TbUser getUserByToken(HttpServletRequest request,
			HttpServletResponse response) {
		try {

			// 从cookie中取token
			String token = CookieUtils.getCookieValue(request, "Token");
			// 判断token是否有值
			if (StringUtils.isBlank(token)) {
				return null;
			}
			// 调用sso的服务查询用户信息
			String json = HttpClientUtil.doGet(SSO_BASE_URL
					+ SSO_USER_TOKEN_SERVICE + token);
			TaotaoResult result = TaotaoResult.format(json);
			// 判断状态码查看返回的状态码如果不是200说明没值
			if (result.getStatus() != 200) {
				return null;
			}
			// 把json字符串转换成java对象
			result = TaotaoResult.formatToPojo(json, TbUser.class);
			TbUser user = (TbUser) result.getData();
			return user;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}

        自定义一个拦截器类LoginInterceptor,要实现org.springframework.web.servlet.HandlerInterceptor接口。

package com.taotao.portal.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.taotao.pojo.TbUser;
import com.taotao.portal.service.UserService;

/**
 * 用户登录拦截器
 * 
 * @author tb
 *  这里注意:拦截器是运行在springmvc,是由子容器springmvc管理,而属性文件是由父容器spring管理所以如果要在拦截器中注入属性文件,
 *  需要在子容器springmvc的配置文件中再扫描一遍属性文件。
 *
 */
public class LoginInterceptor implements HandlerInterceptor {

	@Autowired
	private UserService userService;

	@Value("${SSO_LOGIN_URL}")
	private String SSO_LOGIN_URL;

	/**
	 * 执行时机:Handler执行之前执行该方法 返回值:true(放行)/false(拦截)
	 */
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object arg2) throws Exception {
		TbUser user = userService.getUserByToken(request, response);
		if (user == null) {
			/*
			 * 用户没登录,跳转到登录页面(使用重定向,因为这里跨系统了也就是不是在一个工程内部)
			 * 要携带参数:redirectURL。(上一个页面的url,也就是发出当前Request请求的url,
			 * 用于登录完成后返回之前的页面继续操作。)
			 */

			response.sendRedirect(SSO_LOGIN_URL + "?redirectURL="
					+ request.getRequestURI());
			return false;// 拦截用户,不可执行该Handler
		}
		// 用户已经登录,放行。
		return true;
	}

	/**
	 * 执行时机:在Handler返回之后,但是在Handler返回ModelAndView之前 Handler已经执行完了也没什么拦截不拦截的了
	 */
	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object arg2, ModelAndView arg3)
			throws Exception {
		// TODO Auto-generated method stub

	}

	/**
	 * 执行时机:完全完成Handler处理,已经返回ModelAndView
	 */
	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object arg2, Exception arg3)
			throws Exception {
		// TODO Auto-generated method stub

	}

}

       如果用户没有登录将会跳转到登录页面。并且把当前页面的url传入登录页面,以便完成登录后直接返回当前页面(由登录页面的js完成)。

@RequestMapping("/page/login")
    public String showLogin(String redirectURL,Model model) {
		//上一个页面的url传递给登录页面,当登录页面成功登录后,由登录页面跳转到redirectURL指向的页面(js完成)
		model.addAttribute("redirect",redirectURL);
		return "login";
	}

         将这个自定义拦截器加入到springmvc中

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    
    <!-- 为了能够在拦截器中注入properties文件内容,springmvc也要配置扫描 -->
	<context:property-placeholder location="classpath:properties/*.properties" />
	<!-- 配置包扫描器 在web层中,这个会配置到springmvc容器中 -->
	<context:component-scan base-package="com.taotao.portal.controller"></context:component-scan>
	<!-- 配置注解驱动 -->
	<mvc:annotation-driven />
	<!-- 视图解析器 -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<!-- 拦截器 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<!-- 需要拦截的url路径 :/order/**  这个是订单系统的url格式 -->
			<mvc:mapping path="/order/**" />
			<bean class="com.taotao.portal.interceptor.LoginInterceptor"></bean>
		</mvc:interceptor>
	</mvc:interceptors>
</beans>        






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值