单点登录(超级详细)

单机模式示例

//读取数据库中的数据

ServerResponse<User> response=iUserService.login(username,passward);
if (response.isSuccess()){
    session.setAttribute(Const.CURRENT_USER,response.getData());
}
return response;

//判断是否登录

User user = (User)session.getAttribute(Const.CURRENT_USER);

 

单点登录实现思路

1,读取数据库中的用户信息

2,获取session中的sessionId(我们称他为token

3,token放入cookie中(注意cookie存放的位置)

4,token作为键,序列化的用户信息作为值,存储到redis

5,判断是否登录只要先从cookie中获取token,然后从redis中根据token查询用户信息

6,在拦截器中重置redis中的超时时间

那么我们开始吧

1,首先要写redis工具类,cookie工具类,slf4j工具类,序列化工具类。

Cookie
import org.apache.commons.lang3.StringUtils;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class CookieUtil {
    private final static String Coodoman="localhost" ;
    private final static String Cooname="login_name" ;
    public static void writetoken(HttpServletResponse response,String token){
        Cookie ck=new Cookie(Cooname,token);
        ck.setDomain(Coodoman);
        ck.setPath("/");

ck.setHttpOnly(true);
        ck.setMaxAge(60*60*24*365);
        pr.pr(ck.getName()+":"+ck.getValue());
        response.addCookie(ck);
    }
    public static String readoken(HttpServletRequest request){
        Cookie[] cks=request.getCookies();
        if(cks!=null){
            for (Cookie ck:
                    cks ) {
                pr.pr(ck.getName()+"read:"+ck.getValue());
                if(StringUtils.equals(ck.getName(),Cooname)){
                    pr.pr("readsuccess");
                    return ck.getValue();
                }
            }
        }
       return null;
    }
    public static void del(HttpServletRequest request,HttpServletResponse response){
        Cookie[] cks=request.getCookies();
        if(cks!=null){
            for (Cookie ck:
                    cks ) {
                pr.pr(ck.getName()+"read:"+ck.getValue());
                if(StringUtils.equals(ck.getName(),Cooname)){
                    ck.setDomain(Coodoman);
                    ck.setPath("/");
                    ck.setMaxAge(0);
                    pr.pr("delsuccess");
                    response.addCookie(ck);
                    return;
                }
            }
        }
    }

}

Redis

<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.6.0</version>
</dependency>

为了更加灵活,redis的一些配置我们放到resource目录下的xxx.properties

redis.max.total=20;
redis.max.idel
=10;
redis.min.idel
=2;
redis.test.borrow
=true;
redis.test.return
=true;

其次建立实体类然后把

public class RedisPool {
    private static JedisPool pool;  //jedis连接池
    
private static Integer maxTotal;//最大连接数
    
private static Integer maxIdle;//最大空闲状态
    
private static Integer minIdle;
    private static Boolean textonBorrow; //Borrow是否验证
    
private static Boolean textonReturn; //Return是否验证
}

Common类

public class RedisPool {
    private static JedisPool pool;  //jedis连接池
    
private static Integer maxTotal= Integer.parseInt(PropertiesUtil.getProperty("redis.max.total","20"));//最大连接数
    
private static Integer maxIdle=Integer.parseInt(PropertiesUtil.getProperty("redis.max.idel","10"));//最大空闲状态
    
private static Integer minIdle=Integer.parseInt(PropertiesUtil.getProperty("redis.min.idel","2"));
    private static Boolean textonBorrow=Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow","true")); //Borrow是否验证
    
private static Boolean textonReturn=Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return","true")); //Return是否验证
    
public static void initpool(){
        JedisPoolConfig config=new JedisPoolConfig();
        config.setMaxTotal(maxTotal);
        config.setMaxIdle(maxIdle);
        config.setMinIdle(minIdle);
        config.setTestOnBorrow(textonBorrow);
        config.setTestOnReturn(textonReturn);
        pool=new JedisPool(config,"106.14.13.61",6379,1000*2);
    }

    static {
        System.out.println("static");
        initpool();
    }
    public static Jedis getjedis(){
        return pool.getResource();
    }
    public static void returnbrokenresource(Jedis jedis){
        pool.returnBrokenResource(jedis);
    }

    public static void returnresource(Jedis jedis){
        pool.returnResource(jedis);
    }
    public static void main(String [] args){
//        Jedis jedis=pool.getResource();
//        jedis.set("kk","vv");
//        returnresource(jedis);
//        pool.destroy();
//        System.out.println("6");
        
System.out.println(RedispoolUtil.setex("kk",1000,"ss"));
    }
}

JedisUtil类

package com.mmall.util;

import com.mmall.common.RedisPool;
import redis.clients.jedis.Jedis;

public class RedispoolUtil {
    /*
    * key有效期
    * */
    
public static Long expire(String key,int extime){
        Jedis jedis=null;
        Long result=null;
        try{
            jedis= RedisPool.getjedis();
            result=jedis.expire(key,extime);
        }catch (Exception e){
            System.out.println("weong");
            RedisPool.returnbrokenresource(jedis);
            return result;
        }
        RedisPool.returnresource(jedis);
        return result;
    }
     /*
     增加数据
     * */
    
public static String setex(String key,int extime,String value){
        Jedis jedis=null;
        String result=null;
        try{
        jedis= RedisPool.getjedis();
        result=jedis.setex(key,extime,value);
        }catch (Exception e){
        System.out.println("weong");
        RedisPool.returnbrokenresource(jedis);
        return result;
        }
        RedisPool.returnresource(jedis);
        return result;
    }
    /*
得到数据
* */
    
public static String get(String key){
        Jedis jedis=null;
        String result=null;
        try{
            jedis= RedisPool.getjedis();
            result=jedis.get(key);
        }catch (Exception e){
            System.out.println("weong");
            RedisPool.returnbrokenresource(jedis);
            return result;
        }
        RedisPool.returnresource(jedis);
        return result;
    }
    /*
   删除数据
   * */
    
public static Long del(String key){
        Jedis jedis=null;
        Long result=null;
        try{
            jedis= RedisPool.getjedis();
            result=jedis.del(key);
        }catch (Exception e){
            System.out.println("weong");
            RedisPool.returnbrokenresource(jedis);
            return result;
        }
        RedisPool.returnresource(jedis);
        return result;
    }
}

 

 

slf4j读取配置文件
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Properties;
/**
 * 加载配置
 */
public class PropertiesUtil {
    private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class);
    private static Properties props;
    static {
        String fileName = "mmall.properties";
        props = new Properties();
        try {
            props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8"));
        } catch (IOException e) {
            logger.error("配置文件读取异常",e);
        }
    }

    public static String getProperty(String key){
        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            return null;
        }
        return value.trim();
    }
    public static String getProperty(String key,String defaultValue){
        String value = props.getProperty(key.trim());
        if(StringUtils.isBlank(value)){
            value = defaultValue;
        }
        return value.trim();
    }
}

 

序列化(对象to json以便存在value中)

<dependency>
  <groupId>org.codehaus.jackson</groupId>
  <artifactId>jackson-mapper-asl</artifactId>
  <version>1.9.12</version>
</dependency>

序列化utils
import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import org.codehaus.jackson.type.TypeReference;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.logging.Logger;

public class JsonUtil {
    private static ObjectMapper objectMapper=new ObjectMapper();
    static {

        //对象所有字段转入
        objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.ALWAYS);
        //取消timestamps
        objectMapper.configure(SerializationConfig.Feature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false);
        //忽略空bean
        objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS,false);

        objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));
         //忽略在json中存在,但是java对象不存在
        objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES,false);
    }

        public static <T> String objstring(T obj){
                if(obj==null){
                    return null;
                }
                try {
                    return obj instanceof String? (String) obj:objectMapper.writeValueAsString(obj);
                }catch (Exception e){
                 return null;
                }
        }
        public static <T> String objstringorety(T obj){
        if(obj==null){
            return null;
        }
        try {
            return obj instanceof String? (String) obj:objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        }catch (Exception e){
            return null;
        }
        }
        public static <T> T strtoobj(String str,Class<T> clazz){
        if(StringUtils.isEmpty(str)){
        return null;
        }
            try {
                return clazz.equals(String.class)? (T) str :objectMapper.readValue(str,clazz);
            } catch (Exception e) {
                return null;
            }
        }

        public static <T> T strtoobj(String str, TypeReference<T> typeReference){
            if(StringUtils.isEmpty(str)||typeReference==null){
                return null;
            }
            try {
                return typeReference.getType().equals(String.class)? (T) str : (T) objectMapper.readValue(str, typeReference);
            } catch (Exception e) {
                return null;
            }
        }
        public static void main(String [] args){
            User u1=new User();
            u1.setId(1);
            u1.setUsername("wpp");
            User u2=new User();
            u2.setId(1);
            u2.setUsername("wpp");
            List<User> ul= Lists.newArrayList();
            ul.add(u1);
            ul.add(u1);
           System.out.println(JsonUtil.strtoobj(JsonUtil.objstring(ul), new TypeReference<List<User>>() {
           }));
        }
}

2,实现登录

     ServerResponse<User> response=iUserService.login(username,passward);
        if (response.isSuccess()){
            CookieUtil.writetoken(resp,session.getId());
            
RedispoolUtil.setex(session.getId(),                    1800,JsonUtil.objstring(response.getData()));
        }

 

3,实现验证

@RequestMapping(value = "us.do",method = RequestMethod.GET)
@ResponseBody
public ServerResponse<User> de(String username, String passward , HttpSession session, HttpServletResponse resp, HttpServletRequest request){
    String to=CookieUtil.readoken(request);
    if(StringUtils.isEmpty(to)){
        return ServerResponse.createByErrorCodeMessage(8,"nosession");
    }
    String json=RedispoolUtil.get(to);
    User us=JsonUtil.strtoobj(json,User.class);
      if(us!=null){
          pr.pr(us.getUsername()+us.getPhone());
          return ServerResponse.createBySuccess(us);
      }
    return ServerResponse.createByErrorCodeMessage(8,"noredis");
}

 

4,Session重置有效期

public class FILTER implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpServletRequest=(HttpServletRequest)servletRequest;
        String tok=CookieUtil.readoken(httpServletRequest);
        if(StringUtils.isNotEmpty(tok)){
            String jsons= RedispoolUtil.get(tok);
            User user=JsonUtil.strtoobj(jsons,User.class);
            if(user!=null){
                RedispoolUtil.expire(tok,60*30);
            }
        }
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
<filter>
  <filter-name>filtersession</filter-name>
  <filter-class>com.mmall.controller.COMMON.FILTER</filter-class>
</filter>
<filter-mapping>
  <filter-name>filtersession</filter-name>
  <url-pattern>*.do</url-pattern>
</filter-mapping>

 

发布了55 篇原创文章 · 获赞 11 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/AAA17864308253/article/details/79551232