SSO单点登录

本文介绍了一套SSO单点登录系统的实现方案,包括系统架构、关键组件如EasyUIResult、SysResult等类的设计,以及用户注册、登录等功能的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. EasyUIResult.java
    package com.jt.common.vo;
    
    import java.util.List;
    
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    public class EasyUIResult {
    
        // 定义jackson对象
        private static final ObjectMapper MAPPER = new ObjectMapper();
    
        private Integer total;
    
        private List<?> rows;
    
        public EasyUIResult() {
        }
    
        public EasyUIResult(Integer total, List<?> rows) {
            this.total = total;
            this.rows = rows;
        }
    
        public EasyUIResult(Long total, List<?> rows) {
            this.total = total.intValue();
            this.rows = rows;
        }
    
        public Integer getTotal() {
            return total;
        }
    
        public void setTotal(Integer total) {
            this.total = total;
        }
    
        public List<?> getRows() {
            return rows;
        }
    
        public void setRows(List<?> rows) {
            this.rows = rows;
        }
    
        /**
         * Object是集合转化
         * 
         * @param jsonData json数据
         * @param clazz 集合中的类型
         * @return
         */
        public static EasyUIResult formatToList(String jsonData, Class<?> clazz) {
            try {
                JsonNode jsonNode = MAPPER.readTree(jsonData);
                JsonNode data = jsonNode.get("rows");
                List<?> list = null;
                if (data.isArray() && data.size() > 0) {
                    list = MAPPER.readValue(data.traverse(),
                            MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
                }
                return new EasyUIResult(jsonNode.get("total").intValue(), list);
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
    }
    

     
  2. RedisService.java
    package com.jt.common.service;
    
    import org.apache.taglibs.standard.lang.jstl.test.beans.PublicInterface2;
    import org.aspectj.lang.annotation.Before;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import redis.clients.jedis.Jedis;
    import redis.clients.jedis.JedisSentinelPool;
    import redis.clients.jedis.ShardedJedis;
    import redis.clients.jedis.ShardedJedisPool;
    
    @Service
    public class RedisService {
    	
    	//如果spring容器中有该对象,则注入,如果没有该对象,则不管了
    	@Autowired(required=false)
    	private JedisSentinelPool jedisSentinelPool;
    	
    	public void  set(String key,String value){
    		Jedis jedis=jedisSentinelPool.getResource();
    		jedis.set(key, value);
    		
    		jedisSentinelPool.returnResource(jedis);
    	}
    	public String get(String key){
    		Jedis jedis=jedisSentinelPool.getResource();
    		String reString=jedis.get(key);
    		
    		jedisSentinelPool.returnResource(jedis);
    		return reString;
    	}
    	
    	
    	
    	
    	/*@Autowired
       private ShardedJedisPool  jedisPoll;
    
    	public void set(String key, String value){
    		ShardedJedis shardedJedis=jedisPoll.getResource();
    		shardedJedis.set(key, value);
    		
    		//将连接还回池中
    		jedisPoll.returnResource(shardedJedis);
    	}
    	
    	//定义get方法
    	public  String get(String key){
    		ShardedJedis shardedJedis=jedisPoll.getResource();
    		String value=shardedJedis.get(key);
    		jedisPoll.returnResource(shardedJedis);
    		return value;
    	}*/
    }
    

     
  3. 实体基类BasePojo.java
    package com.jt.common.po;
    
    import java.io.Serializable;
    import java.util.Date;
    
    //pojo基类,完成2个任务,2个日期,实现序列化
    public class BasePojo implements Serializable{
    	private Date created;
    	private Date updated;
    	public Date getCreated() {
    		return created;
    	}
    	public void setCreated(Date created) {
    		this.created = created;
    	}
    	public Date getUpdated() {
    		return updated;
    	}
    	public void setUpdated(Date updated) {
    		this.updated = updated;
    	}
    	
    }
    
  4. 通用mapper  SysMapper.java
    package com.jt.common.mapper;
    
    import java.util.List;
    
    import org.apache.ibatis.annotations.DeleteProvider;
    import org.apache.ibatis.annotations.InsertProvider;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.SelectProvider;
    import org.apache.ibatis.annotations.UpdateProvider;
    
    public interface SysMapper<T> {
    
        /**
         * 根据主键ID批量删除
         * 
         * @param key
         * @return
         */
        @DeleteProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int deleteByIDS(@Param("ids") Object[] key);
    
        /**
         * 根据实体类不为null的字段进行查询,条件全部使用=号and条件
         * 
         * @param record
         * @return
         */
        @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        List<T> select(T record);
    
        /**
         * 根据实体类不为null的字段查询总数,条件全部使用=号and条件
         * 
         * @param record
         * @return
         */
        @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int selectCount(T record);
    
        /**
         * 根据主键进行查询,必须保证结果唯一 单个字段做主键时,可以直接写主键的值 联合主键时,key可以是实体类,也可以是Map
         * 
         * @param key
         * @return
         */
        @SelectProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        T selectByPrimaryKey(Object key);
    
        /**
         * 插入一条数据 支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写) 优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长
         * 
         * @param record
         * @return
         */
        @InsertProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int insert(T record);
    
        /**
         * 插入一条数据,只插入不为null的字段,不会影响有默认值的字段 支持Oracle序列,UUID,类似Mysql的INDENTITY自动增长(自动回写)
         * 优先使用传入的参数值,参数值空时,才会使用序列、UUID,自动增长
         * 
         * @param record
         * @return
         */
        @InsertProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int insertSelective(T record);
    
        /**
         * 根据实体类中字段不为null的条件进行删除,条件全部使用=号and条件
         * 
         * @param key
         * @return
         */
        @DeleteProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int delete(T key);
    
        /**
         * 通过主键进行删除,这里最多只会删除一条数据 单个字段做主键时,可以直接写主键的值 联合主键时,key可以是实体类,也可以是Map
         * 
         * @param key
         * @return
         */
        @DeleteProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int deleteByPrimaryKey(Object key);
    
        /**
         * 根据主键进行更新,这里最多只会更新一条数据 参数为实体类
         * 
         * @param record
         * @return
         */
        @UpdateProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int updateByPrimaryKey(T record);
    
        /**
         * 根据主键进行更新 只会更新不是null的数据
         * 
         * @param record
         * @return
         */
        @UpdateProvider(type = SysMapperProvider.class, method = "dynamicSQL")
        int updateByPrimaryKeySelective(T record);
    
    }
    
  5. SysMapperProvider.java
    package com.jt.common.mapper;
    
    import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN;
    import static org.apache.ibatis.jdbc.SqlBuilder.DELETE_FROM;
    import static org.apache.ibatis.jdbc.SqlBuilder.SQL;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Set;
    
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
    import org.apache.ibatis.scripting.xmltags.MixedSqlNode;
    import org.apache.ibatis.scripting.xmltags.SqlNode;
    import org.apache.ibatis.scripting.xmltags.StaticTextSqlNode;
    
    import com.github.abel533.mapper.MapperProvider;
    import com.github.abel533.mapperhelper.EntityHelper;
    import com.github.abel533.mapperhelper.MapperHelper;
    
    public class SysMapperProvider extends MapperProvider {
    
        public SysMapperProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
            super(mapperClass, mapperHelper);
        }
    
        public SqlNode deleteByIDS(MappedStatement ms) {
            Class<?> entityClass = getSelectReturnType(ms);
            Set<EntityHelper.EntityColumn> entityColumns = EntityHelper.getPKColumns(entityClass);
            EntityHelper.EntityColumn column = null;
            for (EntityHelper.EntityColumn entityColumn : entityColumns) {
                column = entityColumn;
                break;
            }
            
            List<SqlNode> sqlNodes = new ArrayList<SqlNode>();
            // 开始拼sql
            BEGIN();
            // delete from table
            DELETE_FROM(tableName(entityClass));
            // 得到sql
            String sql = SQL();
            // 静态SQL部分
            sqlNodes.add(new StaticTextSqlNode(sql + " WHERE " + column.getColumn() + " IN "));
            // 构造foreach sql
            SqlNode foreach = new ForEachSqlNode(ms.getConfiguration(), new StaticTextSqlNode("#{"
                    + column.getProperty() + "}"), "ids", "index", column.getProperty(), "(", ")", ",");
            sqlNodes.add(foreach);
            return new MixedSqlNode(sqlNodes);
        }
    
    }
    

     
  6. 自定义返回类型SysResult.java
    package com.jt.common.vo;
    
    import java.io.Serializable;
    import java.util.List;
    
    import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
    import com.fasterxml.jackson.databind.JsonNode;
    import com.fasterxml.jackson.databind.ObjectMapper;
    
    /**
     * 京淘商城自定义响应结构
     */
    @JsonIgnoreProperties(ignoreUnknown=true)
    public class SysResult implements Serializable{
    	private static final long serialVersionUID = 1L;
    
    	// 定义jackson对象
        private static final ObjectMapper MAPPER = new ObjectMapper();
    
        // 响应业务状态
        /*
         * 200	成功
         * 201	错误
         * 400	参数错误
         */
        private Integer status;
    
        // 响应消息
        private String msg;
    
        // 响应中的数据
        private Object data;
    
        public static SysResult build(Integer status, String msg, Object data) {
            return new SysResult(status, msg, data);
        }
    
        public static SysResult oK(Object data) {
            return new SysResult(data);
        }
    
        public static SysResult oK() {
            return new SysResult(null);
        }
    
        public SysResult() {
    
        }
    
        public static SysResult build(Integer status, String msg) {
            return new SysResult(status, msg, null);
        }
    
        public SysResult(Integer status, String msg, Object data) {
            this.status = status;
            this.msg = msg;
            this.data = data;
        }
    
        public SysResult(Object data) {
            this.status = 200;
            this.msg = "OK";
            this.data = data;
        }
    
        
        public Boolean isOk() {
            return this.status == 200;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    
        /**
         * 将json结果集转化为SysResult对象
         * 
         * @param jsonData json数据
         * @param clazz SysResult中的object类型
         * @return
         */
        public static SysResult formatToPojo(String jsonData, Class<?> clazz) {
            try {
                if (clazz == null) {
                    return MAPPER.readValue(jsonData, SysResult.class);
                }
                JsonNode jsonNode = MAPPER.readTree(jsonData);
                JsonNode data = jsonNode.get("data");
                Object obj = null;
                if (clazz != null) {
                    if (data.isObject()) {
                        obj = MAPPER.readValue(data.traverse(), clazz);
                    } else if (data.isTextual()) {
                        obj = MAPPER.readValue(data.asText(), clazz);
                    }
                }
                return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
            } catch (Exception e) {
            	e.printStackTrace();
                return null;
            }
        }
    
        /**
         * 没有object对象的转化
         * 
         * @param json
         * @return
         */
        public static SysResult format(String json) {
            try {
                return MAPPER.readValue(json, SysResult.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * Object是集合转化
         * 
         * @param jsonData json数据
         * @param clazz 集合中的类型
         * @return
         */
        public static SysResult formatToList(String jsonData, Class<?> clazz) {
            try {
                JsonNode jsonNode = MAPPER.readTree(jsonData);
                JsonNode data = jsonNode.get("data");
                Object obj = null;
                if (data.isArray() && data.size() > 0) {
                    obj = MAPPER.readValue(data.traverse(),
                            MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
                }
                return build(jsonNode.get("status").intValue(), jsonNode.get("msg").asText(), obj);
            } catch (Exception e) {
            	e.printStackTrace();
                return null;
            }
        }
    
    }
    
  7. Cookie 工具类CookieUtils.java
    package com.jt.common.util;
    
    import java.io.UnsupportedEncodingException;
    import java.net.URLDecoder;
    import java.net.URLEncoder;
    
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * 
     * Cookie 工具类
     *
     */
    public final class CookieUtils {
    
        protected static final Logger logger = LoggerFactory.getLogger(CookieUtils.class);
    
        /**
         * 得到Cookie的值, 不编码
         * 
         * @param request
         * @param cookieName
         * @return
         */
        public static String getCookieValue(HttpServletRequest request, String cookieName) {
            return getCookieValue(request, cookieName, false);
        }
    
        /**
         * 得到Cookie的值,
         * 
         * @param request
         * @param cookieName
         * @return
         */
        public static String getCookieValue(HttpServletRequest request, String cookieName, boolean isDecoder) {
            Cookie[] cookieList = request.getCookies();
            if (cookieList == null || cookieName == null) {
                return null;
            }
            String retValue = null;
            try {
                for (int i = 0; i < cookieList.length; i++) {
                    if (cookieList[i].getName().equals(cookieName)) {
                        if (isDecoder) {
                            retValue = URLDecoder.decode(cookieList[i].getValue(), "UTF-8");
                        } else {
                            retValue = cookieList[i].getValue();
                        }
                        break;
                    }
                }
            } catch (UnsupportedEncodingException e) {
                logger.error("Cookie Decode Error.", e);
            }
            return retValue;
        }
    
        /**
         * 得到Cookie的值,
         * 
         * @param request
         * @param cookieName
         * @return
         */
        public static String getCookieValue(HttpServletRequest request, String cookieName, String encodeString) {
            Cookie[] cookieList = request.getCookies();
            if (cookieList == null || cookieName == null) {
                return null;
            }
            String retValue = null;
            try {
                for (int i = 0; i < cookieList.length; i++) {
                    if (cookieList[i].getName().equals(cookieName)) {
                        retValue = URLDecoder.decode(cookieList[i].getValue(), encodeString);
                        break;
                    }
                }
            } catch (UnsupportedEncodingException e) {
                logger.error("Cookie Decode Error.", e);
            }
            return retValue;
        }
    
        /**
         * 设置Cookie的值 不设置生效时间默认浏览器关闭即失效,也不编码
         */
        public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                String cookieValue) {
            setCookie(request, response, cookieName, cookieValue, -1);
        }
    
        /**
         * 设置Cookie的值 在指定时间内生效,但不编码
         */
        public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                String cookieValue, int cookieMaxage) {
            setCookie(request, response, cookieName, cookieValue, cookieMaxage, false);
        }
    
        /**
         * 设置Cookie的值 不设置生效时间,但编码
         */
        public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                String cookieValue, boolean isEncode) {
            setCookie(request, response, cookieName, cookieValue, -1, isEncode);
        }
    
        /**
         * 设置Cookie的值 在指定时间内生效, 编码参数
         */
        public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                String cookieValue, int cookieMaxage, boolean isEncode) {
            doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, isEncode);
        }
    
        /**
         * 设置Cookie的值 在指定时间内生效, 编码参数(指定编码)
         */
        public static void setCookie(HttpServletRequest request, HttpServletResponse response, String cookieName,
                String cookieValue, int cookieMaxage, String encodeString) {
            doSetCookie(request, response, cookieName, cookieValue, cookieMaxage, encodeString);
        }
    
        /**
         * 删除Cookie带cookie域名
         */
        public static void deleteCookie(HttpServletRequest request, HttpServletResponse response,
                String cookieName) {
            doSetCookie(request, response, cookieName, "", -1, false);
        }
    
        /**
         * 设置Cookie的值,并使其在指定时间内生效
         * 
         * @param cookieMaxage cookie生效的最大秒数
         */
        private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
                String cookieName, String cookieValue, int cookieMaxage, boolean isEncode) {
            try {
                if (cookieValue == null) {
                    cookieValue = "";
                } else if (isEncode) {
                    cookieValue = URLEncoder.encode(cookieValue, "utf-8");
                }
                Cookie cookie = new Cookie(cookieName, cookieValue);
                if (cookieMaxage > 0)
                    cookie.setMaxAge(cookieMaxage);
                if (null != request)// 设置域名的cookie
                    //cookie.setDomain(getDomainName(request));		引发无法设置cookie
                cookie.setPath("/");
                response.addCookie(cookie);
            } catch (Exception e) {
                logger.error("Cookie Encode Error.", e);
            }
        }
    
        /**
         * 设置Cookie的值,并使其在指定时间内生效
         * 
         * @param cookieMaxage cookie生效的最大秒数
         */
        private static final void doSetCookie(HttpServletRequest request, HttpServletResponse response,
                String cookieName, String cookieValue, int cookieMaxage, String encodeString) {
            try {
                if (cookieValue == null) {
                    cookieValue = "";
                } else {
                    cookieValue = URLEncoder.encode(cookieValue, encodeString);
                }
                Cookie cookie = new Cookie(cookieName, cookieValue);
                if (cookieMaxage > 0)
                    cookie.setMaxAge(cookieMaxage);
                if (null != request)// 设置域名的cookie
                    cookie.setDomain(getDomainName(request));
                cookie.setPath("/");
                response.addCookie(cookie);
            } catch (Exception e) {
                logger.error("Cookie Encode Error.", e);
            }
        }
    
        /**
         * 得到cookie的域名
         */
        private static final String getDomainName(HttpServletRequest request) {
            String domainName = null;
    
            String serverName = request.getRequestURL().toString();
            if (serverName == null || serverName.equals("")) {
                domainName = "";
            } else {
                serverName = serverName.toLowerCase();
                serverName = serverName.substring(7);
                final int end = serverName.indexOf("/");
                serverName = serverName.substring(0, end);
                final String[] domains = serverName.split("\\.");
                int len = domains.length;
                if (len > 3) {
                    // www.xxx.com.cn
                    domainName = "." + domains[len - 3] + "." + domains[len - 2] + "." + domains[len - 1];
                } else if (len <= 3 && len > 1) {
                    // xxx.com or xxx.cn
                    domainName = "." + domains[len - 2] + "." + domains[len - 1];
                } else {
                    domainName = serverName;
                }
            }
    
            if (domainName != null && domainName.indexOf(":") > 0) {
                String[] ary = domainName.split("\\:");
                domainName = ary[0];
            }
            return domainName;
        }
    
    }
    

     
  8. Controller代码
    package com.jt.sso.controller;
    
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.http.protocol.HTTP;
    import org.omg.CORBA.PUBLIC_MEMBER;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.converter.json.MappingJacksonValue;
    import org.springframework.stereotype.Controller;
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.jt.common.util.CookieUtils;
    import com.jt.common.vo.SysResult;
    import com.jt.sso.pojo.User;
    import com.jt.sso.service.UserService;
    
    import redis.clients.jedis.JedisCluster;
    
    @Controller
    @RequestMapping("/user")
    public class UserController {
    	@Autowired
          private  UserService userService;
    	@Autowired
    	private JedisCluster jedisCluster;
    	//url: http://sso.jt.com/user/check/sdfsdfsdfsdfsd/1?r=0.8407468782065235&callback=jsonp1517467518353&_=1517467523183 
    	@RequestMapping("/check/{param}/{type}")
    	@ResponseBody
    	public Object checkUser(@PathVariable String param,
    			@PathVariable Integer type,String callback){
    		try {
    			//根据传递的参数,判断数据是否存在,true表示已存在,false表示不存在
    			Boolean result=userService.findCheckUser(param,type);
    			//返回JSONP的数据
    			MappingJacksonValue  jacksonValue=new  MappingJacksonValue(SysResult.oK(result));
    			jacksonValue.setJsonpFunction(callback);
    			return  jacksonValue;
    		} catch (Exception e) {
    			e.printStackTrace();
    			return null;
    		}
    		
    	}
    	//用户的注册
    	//http://sso.jt.com/user/register
    	@RequestMapping("/register")
    	@ResponseBody
    	public SysResult saveUser(User user){
    		try {
    			//用户的新增
    			String username=userService.saveUser(user);
    			return SysResult.oK(username);
    		} catch (Exception e) {
    			e.printStackTrace();
    			return SysResult.build(201, "用户新增失败");
    		}
    	}
    	/**
    	 * @RequestParam("u") 注解作用:接受参数是用u关键字来接受,然后把获取的数据传给username
    	 * @param username    用户名
    	 * @param password    密码
    	 * @return
    	 * url: "http://sso.jt.com/user/login";
    	 * 如果ticket为null是,就成了 data="null"   是串而不是空
    	 */
    	@RequestMapping("/login")
    	@ResponseBody
    	public  SysResult findUserByUP(@RequestParam("u")String username,@RequestParam("p")String password){
    		if(StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
    			return SysResult.build(201, "用户名和密码为空");
    		}
    		String ticket=null;
    		try {
    			ticket=userService.findUserByUp(username,password);
    			if(ticket!=null) return SysResult.oK(ticket);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		  return SysResult.build(201, "用户不存在,登录失败");
    	}
    	/**
    	 * url : "http://sso.jt.com/user/query/" + _ticket,
    	 * @param callback    JSONP请求必须要接受的参数
    	 * @param ticket
    	 * @return
    	 */
    	@RequestMapping("/query/{ticket}")
    	@ResponseBody
    	   public Object findUsernameByTicket(String callback,@PathVariable String ticket){
    			String jString=jedisCluster.get(ticket);
    			//jsonp的返回方式:MappingJacksonValue
    			MappingJacksonValue jacksonValue=new MappingJacksonValue(SysResult.oK(jString));
    			jacksonValue.setJsonpFunction(callback);
    			return jacksonValue;
    	}
    	
    		
    }
    
  9. service接口
    package com.jt.sso.service;
    
    import com.jt.sso.pojo.User;
    
    public interface UserService {
        // 校验数据是否存在
    	Boolean findCheckUser(String param, Integer type);
        //用户新增
    	String saveUser(User user);
    	//根据用户名和密码查询是否正确
    	String findUserByUp(String username, String password);
    
    }
    
  10. service实现类
    package com.jt.sso.service;
    
    import java.io.IOException;
    import java.util.Date;
    
    import javax.swing.plaf.basic.BasicInternalFrameTitlePane.MaximizeAction;
    
    import org.apache.commons.codec.digest.DigestUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.util.StringUtils;
    
    import com.fasterxml.jackson.core.JsonParseException;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.JsonMappingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.jt.common.util.RedisCluster;
    import com.jt.sso.mapper.UserMapper;
    import com.jt.sso.pojo.User;
    
    import redis.clients.jedis.JedisCluster;
    import sun.security.util.DisabledAlgorithmConstraints;
    @Service
    public class UserServiceImpl implements UserService {
    	@Autowired
        private UserMapper userMapper;
    	
    	//注入集群redis    注入jedis对象
        @Autowired  
    	private JedisCluster  jedisCluster;
        
        private static ObjectMapper objectMapper=new ObjectMapper();
    	//Type为类型,可选参数1 username、2 phone、3 email
    	@Override
    	public Boolean findCheckUser(String param, Integer type) {
    		String cloumn=null;
    		switch (type) {
    		case 1: cloumn="username"; break;
    		case 2: cloumn="phone"; break;
    		case 3: cloumn="email"; break;
    		}
    		int count=userMapper.findCheckUser(param,cloumn);
    		return count==1 ? true : false;
    	}
    
    	@Override
    	public String saveUser(User user) {
    		//将数据准备完整     username  password  phone  email 
    		user.setCreated(new Date());
    		user.setUpdated(user.getCreated());
    		//将密码进行md5加密处理    apaqi 包下面的org.apache.commons.codec.digest
    		String md5Password= DigestUtils.md5Hex(user.getPassword());
    		user.setPassword(md5Password);
    		//修改bug  添补邮箱为null的现象
    		user.setEmail(user.getPhone());
    		userMapper.insert(user);
    		//应该返回username
    		return user.getUsername();
    	}
    	
    	
    	/**
    	 * 思路:
    	 * 1.验证用户名和密码是否正确 
    	 * 2.需要将用户的明文密码加密为密文密码
    	 * 3.如果用户信息校验通过,准备redis的缓存数据
    	 * 4.生产ticket=md5(“JT_TICKET_” + System.currentTime + username)
    	 * 5.将user对象转换为json数据
    	 * 6.将ticket和UserJSON数据存入redis
    	 * 7.return 返回ticket
    	 */
    	@Override
    	public String findUserByUp(String username, String password) {
    		//需要将用户的明文密码加密为密文密码
    		String md5password=DigestUtils.md5Hex(password);
    		//用户信息校验通过
    		User user=userMapper.findUserByUP(username,md5password);
    		//生产ticket
    		 String ticket=DigestUtils.md5Hex("JT_TICKET_"+System.currentTimeMillis()+username);
    		 String md5Ticket=DigestUtils.md5Hex(ticket);
    		 try {
    				 //将user对象转换为json数据
    				String juser=objectMapper.writeValueAsString(user);
    				//将ticket和UserJSON数据存入redis
    				jedisCluster.set(md5Ticket,juser);
    		 } catch (JsonProcessingException e) {
    				e.printStackTrace();
    			}
    	
    		return md5Ticket;
    	}
    
    }
    
  11. dao层接口
    package com.jt.sso.mapper;
    
    import org.apache.ibatis.annotations.Param;
    
    import com.jt.common.mapper.SysMapper;
    import com.jt.sso.pojo.User;
    
    public interface UserMapper extends SysMapper<User>{
        //查询数据是否存在  封装为map
    	int findCheckUser(@Param("param")String param, @Param("cloumn")String cloumn);
    
    	User findUserByUP(@Param("username")String username,@Param("password")String password);
    
    }
    
  12. entity实体类
    package com.jt.sso.pojo;
    
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import com.jt.common.po.BasePojo;
    @Table(name="tb_user")   //对应数据库表
    public class User extends BasePojo{    //继承父类中的时间属性
    	@Id  //表示主键信息
    	@GeneratedValue(strategy=GenerationType.IDENTITY)  //主键自增
        private Long  id;             //用户id
        private String username;      //用户名
        private String password;      //密码  采用MD5
        private String phone;         //电话
        private String email;         //邮箱
    	public Long getId() {
    		return id;
    	}
    	public void setId(Long id) {
    		this.id = id;
    	}
    	public String getUsername() {
    		return username;
    	}
    	public void setUsername(String username) {
    		this.username = username;
    	}
    	public String getPassword() {
    		return password;
    	}
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	public String getPhone() {
    		return phone;
    	}
    	public void setPhone(String phone) {
    		this.phone = phone;
    	}
    	public String getEmail() {
    		return email;
    	}
    	public void setEmail(String email) {
    		this.email = email;
    	}
        
    }
    
  13. 配置文件log4j.properties
    log4j.rootLogger=DEBUG,A1
    
    log4j.logger.java.sql.PreparedStatement=DEBUG
    
    log4j.appender.A1=org.apache.log4j.ConsoleAppender
    log4j.appender.A1.layout=org.apache.log4j.PatternLayout
    log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
    
  14. 配置文件jdbc.properties
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql:///jtdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    #jdbc.url=jdbc:mysql://192.168.161.136:8066/jtdb?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    jdbc.username=root
    jdbc.password=root
    
  15. 配置文件redis.properties
    #定义三台redis主机
    #redis.host1=192.168.126.135
    #redis.port2=6379
    #redis.host2=192.168.126.135
    #redis.port2=6380
    #redis.host3=192.168.126.135
    #redis.port3=6381
    
    
    #定义主节点名称
    #redis.sentinel.masterName=mymaster
    
    #定义第一个哨兵
    #redis.sentinel.host1=192.168.126.135
    #redis.sentinel.port1=26379
    
    #定义第二个哨兵
    #redis.sentinel.host2=192.168.126.135
    #redis.sentinel.port2=26380
    
    #定义第三个哨兵
    #redis.sentinel.host3=192.168.126.135
    #redis.sentinel.port3=26381
    
    
    #最小空闲数
    redis.minIdle=100
    #最大空闲数
    redis.maxIdle=300
    #最大连接数
    redis.maxTotal=1000
    #客户端超时时间单位是毫秒 
    redis.timeout=5000
    #最大建立连接等待时间  
    redis.maxWait=1000
    #是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
    redis.testOnBorrow=true
    
    
    #redis cluster
    redis.cluster0.host.port=192.168.161.137:7000
    redis.cluster1.host.port=192.168.161.137:7001
    redis.cluster2.host.port=192.168.161.137:7002
    redis.cluster3.host.port=192.168.161.137:7003
    redis.cluster4.host.port=192.168.161.137:7004
    redis.cluster5.host.port=192.168.161.137:7005
    redis.cluster6.host.port=192.168.161.137:7006
    redis.cluster7.host.port=192.168.161.137:7007
    redis.cluster8.host.port=192.168.161.137:7008
    
  16. 定义公共得redis   key的前缀message.properties
    #定义查询全部商品分类菜单的key
    ITEM_CAT_KEY=ITEM_CAT_ALL
    
  17. 定义redis 的公共key的前缀  跨系统访问的时候用itemKey.properties
    itemKey=ITEM_
  18. springMVC的配置文件springmvc.xml
    <?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: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">
         <!-- 1.开启springMVC的注解 -->
         <mvc:annotation-driven/>
         
         <!-- 2.开启包扫描controller -->
         <context:component-scan base-package="com.jt.sso.controller"></context:component-scan>
    
         <!-- 3.配置视图解析器  内部资源视图解析器 -->
         <bean id="internalResour" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!-- 配置前缀和后缀 -->
            <property name="prefix" value="/WEB-INF/views/"></property>
            <property name="suffix" value=".jsp"></property>
         </bean>
         
         <!-- 放行静态资源文件 -->
         <mvc:default-servlet-handler/>
         
         <!-- 4.添加文件上传视图解析器 ~~~~
                                       注意事项:id的名称必须叫multipartResolver -->
         <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 定义最大上传量  一般不会超过10M 1024*1024*10-->
            <property name="maxUploadSize" value="10485760"></property>
            <!-- 定义字符集编码 -->
            <property name="defaultEncoding" value="UTF-8"></property>
         </bean>
    </beans>
  19. spring的配置applicationContext.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:aop="http://www.springframework.org/schema/aop" 
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:util="http://www.springframework.org/schema/util"
    	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-4.0.xsd
    	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
    	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
        
        <!--1.开启包扫描  -->
    	<context:component-scan base-package="com.jt"></context:component-scan>
    	
    	<!--2.导入外部配置文件jdbc.properties  -->
    	<!-- 
    	    2.1方式一:通过标签导入property文件,location属性中引入文件路径
    	                 缺点:通过标签引入property时只能引入文件名开头相同的配置文件
    	                         lg:jdbc1.pr
    	                            jdbc2.pr
    	                            jdbc3.pr
    	                            jdbc4.pr   通配符:jdbc*.properties
    	                 作用:通过spring扫描配置文件,将jdbc中的数据导入spring中方便用户从容器中获取数据,
    	                            目的就是让配置变得松耦合
    	                            
    	     -->
    	<!-- <context:property-placeholder location="classpath:/property/jdbc*.properties"/> -->
    	<!-- 
    	    2.2方式二:通过PropertyPlaceholderConfigurer类来导入配置文件,可以配置多个不同的文件路径。
    	               作用:可以实现将任意的配置文件导入spring容器中
    	               属性:Resource[] locations  spring中数组需要用list value注入值
    	 -->
    	<bean id="propertyPlaceholder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    	    <property name="locations">
    	        <list>
    	            <value>classpath:/property/jdbc.properties</value>
    	            <!-- 添加redis配置文件 -->
    	            <value>classpath:/property/redis.properties</value>
    	            <!--  添加缓存key配置文件-->
    	            <value>classpath:/property/message.properties</value>
    	            <!--  添加商品查询前台和后台共享缓存key配置文件-->
    	            <value>classpath:/property/itemKey.properties</value>
    	            
    	        </list>
    	    </property>
    	</bean>
    	
    	
    	<!--3.配置数据源 通过使用dataSource  -->
    	<!-- 配置连接池 -->
    	<bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">
    		<!-- 数据库驱动 -->
    		<property name="driverClass" value="${jdbc.driver}" />
    		<!-- 相应驱动的jdbcUrl -->
    		<property name="jdbcUrl" value="${jdbc.url}" />
    		<!-- 数据库的用户名 -->
    		<property name="username" value="${jdbc.username}" />
    		<!-- 数据库的密码 -->
    		<property name="password" value="${jdbc.password}" />
    		<!-- 检查数据库连接池中空闲连接的间隔时间,单位是分,默认值:240,如果要取消则设置为0 -->
    		<property name="idleConnectionTestPeriod" value="60" />
    		<!-- 连接池中未使用的链接最大存活时间,单位是分,默认值:60,如果要永远存活设置为0 -->
    		<property name="idleMaxAge" value="30" />
    		<!-- 每个分区最大的连接数 -->
    		<property name="maxConnectionsPerPartition" value="150" />
    		<!-- 每个分区最小的连接数 -->
    		<property name="minConnectionsPerPartition" value="5" />
    	</bean>
    	
    	<!--4.配置声明式事务处理
    	作用:通过自定义的事务策略,描述某些方法需要事务,某些方法不需要事务则设置为只读状态。
    	步骤:
    	   1.定义事务管理器      属性dataSource
    	   2.自定义事务策略  & 配置事务通知
    	   3.生成事务切面
    	  -->
    	  <!-- 4.1定义事务管理器 -->
    	  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    	         <!-- 添加数据源 -->
    	         <property name="dataSource" ref="dataSource"></property>
    	  </bean>
    	  <!-- 4.2定义事务通知及策略 
    	        id:唯一标识通知
    	        transaction-manager默认的名称为transactionManager
    	  如果事物管理器的名称(id)为transactionManager则该配置可以省略不写
    	                  事务策略:
    	                            新增:insert ,save ,add
    	                           修改:update
    	                           删除:delete
    	                           查询:find,select,query 不需要事务
    	       自定义事物策略:
    	           <tx:method name="save*" propagation="REQUIRED"/>
    	           name:需要控制的方法一般以*号结尾标识通配。
    	           propagation:事务传播属性
    	               1.REQUIRED 必须添加事务
    	               2.SUPPORTS 表示事务支持的一般都这么配
    	                    
    	    -->
    	  <tx:advice id="txAdvice" transaction-manager="transactionManager">
    	      <tx:attributes>
    	         <tx:method name="save*" propagation="REQUIRED"/>
    	         <tx:method name="update*" propagation="REQUIRED"/>
    	         <tx:method name="delete*" propagation="REQUIRED"/>
    	         <tx:method name="find*" propagation="SUPPORTS"/>
    	         <tx:method name="select*" propagation="SUPPORTS"/>
    	         <!-- 其他方法 使用只读不允许更新数据库-->
    	         <tx:method name="*" read-only="true"/>
    	      </tx:attributes>
    	  </tx:advice>
    	  <!-- 4.3配置事务切面     通知+切入点=切面 
    	  execution(返回值类型 包名.类名.方法名(参数列表))
    	     注意:中间空格不能省略
    	  lg:
    	  execution(* com.jt.manage.service..*.*(..))
    	     拦截返回值任意的包名为com.jt.manage.service包下的全部类的任意方法的任意参数列表
    	     -->
    	  <aop:config>
    	      <aop:pointcut expression="execution(* com.jt.sso.service..*.*(..))" id="pc"/>
    	      <aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
    	  </aop:config>
    </beans>
  20. mybatis的配置文件applicationContext-mybaties.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:context="http://www.springframework.org/schema/context"
    	xmlns:aop="http://www.springframework.org/schema/aop" 
    	xmlns:tx="http://www.springframework.org/schema/tx"
    	xmlns:util="http://www.springframework.org/schema/util"
    	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-4.0.xsd
    	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
    	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
    	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
    	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
       
         <!-- 1.定义sqlSessionFactoryBean  mybaties 
          配置步骤:
          1.添加数据源  数据库dataSource
          2.加载核心配置文件 mybatis-config.xml
          3.添加映射文件
          4.配置别名包-->
         <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"/>
            <property name="configLocation" value="classpath:/mybatis/mybatis-config.xml"/>
            <property name="mapperLocations" value="classpath:/mybatis/mappers/*.xml"/>
            <property name="typeAliasesPackage" value="com.jt.sso.pojo"/>
         </bean>
         <!-- 2.为mapper接口生成代理对象
           作用:
           1.basePackage 会根据配置的包路径去扫描所有的mapper接口对象,并且为其创建代理对象(JDK代理),
                                                        交给spring容器管理 
          -->
         <bean  class="org.mybatis.spring.mapper.MapperScannerConfigurer">
             <!--定义接口包属性  -->
             <property name="basePackage" value="com.jt.sso.mapper"/>
         </bean>
    </beans>
  21. redis集群的配置文件applicationContext-redisCluster.xml
    <?xml version="1.0" encoding="UTF-8"?>  
    <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.xsd">  
        
        <!-- jedis 配置-->  
        <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >  
            <!--最大空闲数-->  
            <property name="maxIdle" value="${redis.maxIdle}" />  
            <!--最大建立连接等待时间-->  
            <property name="maxWaitMillis" value="${redis.maxWait}" />  
            <!--是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个-->  
            <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
            <property name="maxTotal" value="${redis.maxTotal}" />  
            <property name="minIdle" value="${redis.minIdle}" />  
        </bean>
        <!-- 操作集群的工具API -->
        <bean id="jedisCluster"  class="com.jt.common.util.RedisCluster" >  
            <!-- 引入集群的主机地址 -->
            <property name="addressConfig">
                <value>classpath:/property/redis.properties</value>  
            </property>  
            <!-- 当引入配置文件时,只会添加以redis.cluster开头的配置项 -->
            <property name="addressKeyPrefix" value="redis.cluster" />   <!--  属性文件里  key的前缀 -->  
            <property name="timeout" value="${redis.timeout}" />  
            <property name="maxRedirections" value="6" />  
            <property name="genericObjectPoolConfig" ref="poolConfig" />  
        </bean>  
    </beans>
    
  22. mybatis的核心配置文件mybatis-config.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
      PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    
    	<settings>
    		<!-- 开启驼峰自动映射 -->
    		<setting name="mapUnderscoreToCamelCase" value="true" />
    		<!-- 二级缓存的总开关,被redis替代 -->
    		<setting name="cacheEnabled" value="false" />
    	</settings>
    	
    	<plugins>
    		<!-- 分页插件:com.github.pagehelper为PageHelper类所在包名 -->
    		<plugin interceptor="com.github.pagehelper.PageHelper">
    			<!-- 方言 -->
    			<property name="dialect" value="mysql" />
    			<!-- 该参数默认为false -->
    			<!-- 设置为true时,使用RowBounds分页会进行count查询,查询数据总条数 -->
    			<property name="rowBoundsWithCount" value="true" />
    		</plugin>
    		
    		<!-- 通用Mapper插件 -->
    		<plugin interceptor="com.github.abel533.mapperhelper.MapperInterceptor">
    			<!--主键自增回写方法,默认值MYSQL,详细说明请看文档 -->
    			<property name="IDENTITY" value="MYSQL" />
    			<!--通用Mapper接口,多个通用接口用逗号隔开 -->
    			<property name="mappers" value="com.jt.common.mapper.SysMapper" />
    		</plugin>
    	</plugins>
    </configuration>
  23. mapper映射文件UserMapper.xml
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
      PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
      "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.jt.sso.mapper.UserMapper">
        <!-- 使用符号获取数据值时,
                           一般建议使用#号,因为有预编译的效用,
             $符使用时,只会出现在以列名为参数的应用。
                           能用#好不用$ 
             如果在列中用#号取值。相等于给字段加了“”号,所有这用$-->
    	<select id="findCheckUser" resultType="int">
    	select count(*) from tb_user where ${cloumn}=#{param}
    	</select>
    	<select id="findUserByUP" resultType="user">
    	select * from tb_user where username=#{username} and password=#{password}
    	</select>
    </mapper>
  24. webapp/WEB-INF/web.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xmlns="http://java.sun.com/xml/ns/javaee"
    	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    	id="jt-manage" version="2.5">
    	<display-name>jt-sso</display-name>
        <!-- spring和springMVC的总结
                           配置方式:
                   1.通过前端控制器直接扫描全部容器
                   2.通过监听器的方法启动spring容器
                           差别:
                   1.第一种:
                                             如果springMVC和spring的配置文件都是通过前端控制器扫描则容器的启动时懒加载的,
                                             只有浏览器发出请求之后,前端控制器才会加载启动spring容器和springMVC容器。
                                  弊端:如果是大型项目,用户如果访问时,这时后台的容器才会启动,这时用户等待的时间较长,
                                             耗费时间主要在等待容器启动。
                   2.第二种:
                                             通过监听器的方法启动spring容器
                                             当tomcat启动时,监听器就会监听是否需要spring容器,如果监听器检测到需要spring容器,
                                             则监听器会在后台启动spring容器。
                                             (tomcat启动时spring容器就会加载)
                                             当用户通过浏览器访问时,首先将请求发给springMVC,springMVC通过spring容器获取具体
                                             的对象直接完成业务调用,用户不需要等待spring容器的启动。
         -->
         <!-- 配置监听器启动spring容器 -->
         <listener>
             <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
         </listener>
         <context-param>
             <param-name>contextConfigLocation</param-name>
             <param-value>classpath:/spring/applicationContext*.xml</param-value>
         </context-param>
    	<!-- 1.配置前端控制器 -->
    	<servlet>
    	  <servlet-name>springmvc</servlet-name>
    	  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	  <!-- 加载配置Springmvc.xml -->
    	  <init-param>
    	       <param-name>contextConfigLocation</param-name>
    	       <param-value>classpath:/spring/springmvc.xml</param-value>
    	  </init-param>
    	</servlet>
    	<!--
    	    /规定:
    	       1.表示拦截全部的请求
    	       2.拦截所有静态资源文件js/css/image(这是他的一种默认机制),后期配置放行
    	       3.放行.jsp资源
    	   -->
    	<servlet-mapping>
    	  <servlet-name>springmvc</servlet-name>
    	  <url-pattern>/</url-pattern>
    	</servlet-mapping>
    	
    	
    	<!-- 配置全站乱码解决post乱码 -->
    	<filter>
    	   <filter-name>characterEncoding</filter-name>
    	   <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    	   <init-param>
    	     <!--定义默认字符集utf-8  -->
    	     <param-name>encoding</param-name>
    	     <param-value>UTF-8</param-value>
    	   </init-param>
    	</filter>
    	<filter-mapping>
    	  <filter-name>characterEncoding</filter-name>
    	  <url-pattern>/*</url-pattern>
    	</filter-mapping>
    	
    	
    	<welcome-file-list>
    		<welcome-file>index.jsp</welcome-file>
    	</welcome-file-list>
    </web-app>
  25. maven的pom.xml
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <artifactId>jt-sso</artifactId>
      <packaging>war</packaging>
      <name>jt-sso Maven Webapp</name>
      <url>http://maven.apache.org</url>
             
      <parent>
      	<groupId>com.jt</groupId>
      	<artifactId>jt-parent</artifactId>
      	<version>0.0.1-SNAPSHOT</version>
      </parent>
      <dependencies>
      	<dependency>
      		<groupId>com.jt</groupId>
      		<artifactId>jt-common</artifactId>
      		<version>0.0.1-SNAPSHOT</version>
      	</dependency>
      </dependencies>
       <build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.tomcat.maven</groupId>
    				<artifactId>tomcat7-maven-plugin</artifactId>
    				<version>2.2</version>
    				<configuration>
    					<port>8093</port>
    					<path>/</path>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>
    </project>
  26. index.jsp
    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>管理员登录</title>
    <jsp:include page="/commons/common-js.jsp"></jsp:include>
    </head>
    <body style="background-color: #F3F3F3">
        <div class="easyui-dialog" title="管理员登录" data-options="closable:false,draggable:false" style="width:400px;height:300px;padding:10px;">
           	<div style="margin-left: 50px;margin-top: 50px;">
           		<div style="margin-bottom:20px;">
    	            <div>
    	            	用户名: <input name="username" class="easyui-textbox" data-options="required:true" style="width:200px;height:32px" value="admin"/>
    	            </div>
    	        </div>
    	        <div style="margin-bottom:20px">
    	            <div>
    	            	密  码: <input name="password" class="easyui-textbox" type="password" style="width:200px;height:32px" data-options="" value="admin"/>
    	            </div>
    	        </div>
    	        <div>
    	            <a id="login" class="easyui-linkbutton" iconCls="icon-ok" style="width:100px;height:32px;margin-left: 50px">登录</a>
    	        </div>
           	</div>
        </div>
        
        <script type="text/javascript">
        	$("#login").click(function(){
        		var username = $("[name=username]").val();
        		var password = $("[name=password]").val();
        		
        		if(username!="admin" || password!="admin"){
        			$.messager.alert('错误',"用户名密码不正确!");
        			return ;
        		}
        		window.location.href="/page/index";  //页面跳转
        	});
        </script>
    </body>
    </html>
  27. 用户的页面 userList.jsp
    <%@ page language="java" import="java.util.*" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <html>
    	<head>
    	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
    		<title>用户列表页面</title>
    	</head>
    	<body>
    		<table width="60%" algin="center" border="1">
    			<tr align="center">
    				<td colspan="5"><h2>用户信息</h2></td>
    			</tr>
    			<tr align="center">
    				<td>序号</td>
    				<td>ID</td>
    				<td>姓名</td>
    				<td>年龄</td>
    				<td>性别</td>
    			</tr>
    			<c:forEach items="${userList}" var="user" varStatus="status">
    				<tr align="center">
    				<td>${status.index+1}</td>
    				<td>${user.id}</td>
    				<td>${user.name}</td>
    				<td>${user.age}</td>
    				<td>${user.sex}</td>
    			</tr>
    			</c:forEach>
    		</table>
    	</body>
    </html>

 

        parent  的pom.xml   和common的 pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.jt</groupId>
	<artifactId>jt-parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>

	<name>jt-parent</name>
	<url>http://maven.apache.org</url>
	<!-- 集中定义依赖版本号 -->
	<properties>
		<junit.version>4.10</junit.version>
		<spring.version>4.1.3.RELEASE</spring.version>
		<mybatis.version>3.2.8</mybatis.version>
		<mybatis.spring.version>1.2.2</mybatis.spring.version>
		<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
		<mysql.version>5.1.32</mysql.version>
		<bonecp-spring.version>0.8.0.RELEASE</bonecp-spring.version>
		<druid.version>1.0.29</druid.version>

		<mapper.version>2.3.2</mapper.version>
		<pagehelper.version>3.4.2</pagehelper.version>
		<jsqlparser.version>0.9.1</jsqlparser.version>

		<slf4j.version>1.6.4</slf4j.version>
		<jstl.version>1.2</jstl.version>
		<servlet-api.version>2.5</servlet-api.version>
		<jsp-api.version>2.0</jsp-api.version>
		<joda-time.version>2.5</joda-time.version>

		<commons-lang3.version>3.3.2</commons-lang3.version>
		<commons-io.version>2.4</commons-io.version>
		<commons-fileupload.version>1.3.1</commons-fileupload.version>

		<jackson.version>2.4.2</jackson.version>
		<httpclient.version>4.3.5</httpclient.version>
		<jedis.version>2.6.2</jedis.version>
	</properties>

	<dependencies>
		<!-- 单元测试 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- Spring -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>


		<!-- Mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>${mybatis.version}</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>${mybatis.spring.version}</version>
		</dependency>
		<dependency>
			<groupId>com.github.miemiedev</groupId>
			<artifactId>mybatis-paginator</artifactId>
			<version>${mybatis.paginator.version}</version>
		</dependency>



		<!-- MySql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>${mysql.version}</version>
		</dependency>
		<!-- druid数据库连接 -->
        <dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>${druid.version}</version>
		</dependency>
		<!-- 通用Mapper -->
		<dependency>
			<groupId>com.github.abel533</groupId>
			<artifactId>mapper</artifactId>
			<version>${mapper.version}</version>
		</dependency>

		<!-- 分页插件 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>${pagehelper.version}</version>
		</dependency>
		<dependency>
			<groupId>com.github.jsqlparser</groupId>
			<artifactId>jsqlparser</artifactId>
			<version>${jsqlparser.version}</version>
		</dependency>

		<!-- 连接池 -->
		<dependency>
			<groupId>com.jolbox</groupId>
			<artifactId>bonecp-spring</artifactId>
			<version>${bonecp-spring.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<!-- Jackson Json处理工具包 -->
		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>${jackson.version}</version>
		</dependency>

		<!-- httpclient -->
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>${httpclient.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpmime</artifactId>
			<version>4.3.1</version>
		</dependency>

		<!-- 消息队列 -->
		<dependency>
			<groupId>com.rabbitmq</groupId>
			<artifactId>amqp-client</artifactId>
			<version>3.5.1</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.amqp</groupId>
			<artifactId>spring-rabbit</artifactId>
			<version>1.4.0.RELEASE</version>
		</dependency>

		<!-- JSP相关 -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>${servlet-api.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>${jsp-api.version}</version>
			<scope>provided</scope>
		</dependency>

		<!-- 时间操作组件 -->
		<dependency>
			<groupId>joda-time</groupId>
			<artifactId>joda-time</artifactId>
			<version>${joda-time.version}</version>
		</dependency>

		<!-- Apache工具组件 -->
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>${commons-lang3.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-io</artifactId>
			<version>${commons-io.version}</version>
		</dependency>

		<!-- 文件上传组件 -->
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>${commons-fileupload.version}</version>
		</dependency>

		<!-- jedis -->
		<dependency>
			<groupId>redis.clients</groupId>
			<artifactId>jedis</artifactId>
			<version>${jedis.version}</version>
		</dependency>

		<!--添加spring-datajar包 -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-redis</artifactId>
			<version>1.4.1.RELEASE</version>
		</dependency>

		<!-- 字符加密、解密 -->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.9</version>
		</dependency>

		<!-- 数据校验 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>5.1.3.Final</version>
		</dependency>

		<!-- 定时任务 -->
		<dependency>
			<groupId>org.quartz-scheduler</groupId>
			<artifactId>quartz</artifactId>
			<version>2.2.1</version>
		</dependency>
		<!--定时任务需要依赖c3p0jar包 -->
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.1.2</version>
		</dependency>



		<!--dubbo依赖 -->
		<dependency>
			<groupId>org.javassist</groupId>
			<artifactId>javassist</artifactId>
			<version>3.15.0-GA</version>
		</dependency>
		<dependency>
			<groupId>org.apache.mina</groupId>
			<artifactId>mina-core</artifactId>
			<version>1.1.7</version>
		</dependency>
		<dependency>
			<groupId>org.glassfish.grizzly</groupId>
			<artifactId>grizzly-core</artifactId>
			<version>2.1.4</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.1.39</version>
		</dependency>
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>1.4.1</version>
		</dependency>

		<dependency>
			<groupId>org.apache.bsf</groupId>
			<artifactId>bsf-api</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.6</version>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>2.5.0</version>
		</dependency>
		<dependency>
			<groupId>com.googlecode.xmemcached</groupId>
			<artifactId>xmemcached</artifactId>
			<version>1.3.6</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-frontend-simple</artifactId>
			<version>2.6.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.cxf</groupId>
			<artifactId>cxf-rt-transports-http</artifactId>
			<version>2.6.1</version>
		</dependency>

		<dependency>
			<groupId>org.apache.thrift</groupId>
			<artifactId>libthrift</artifactId>
			<version>0.8.0</version>
		</dependency>
		<dependency>
			<groupId>com.caucho</groupId>
			<artifactId>hessian</artifactId>
			<version>4.0.7</version>
		</dependency>

		<dependency>
			<groupId>javax.cache</groupId>
			<artifactId>cache-api</artifactId>
			<version>0.4</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-jaxrs</artifactId>
			<version>3.0.7.Final</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-client</artifactId>
			<version>3.0.7.Final</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-netty</artifactId>
			<version>3.0.7.Final</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-jdk-http</artifactId>
			<version>3.0.7.Final</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-jackson-provider</artifactId>
			<version>3.0.7.Final</version>
		</dependency>
		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-jaxb-provider</artifactId>
			<version>3.0.7.Final</version>
		</dependency>
		<dependency>
			<groupId>com.esotericsoftware.kryo</groupId>
			<artifactId>kryo</artifactId>
			<version>2.24.0</version>
		</dependency>

		<dependency>
			<groupId>de.javakaffee</groupId>
			<artifactId>kryo-serializers</artifactId>
			<version>0.26</version>
		</dependency>
		<dependency>
			<groupId>de.ruedigermoeller</groupId>
			<artifactId>fst</artifactId>
			<version>1.55</version>
		</dependency>
		<!-- 全文检索lucene -->
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-core</artifactId>
			<version>5.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-analyzers-common</artifactId>
			<version>5.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.apache.lucene</groupId>
			<artifactId>lucene-queryparser</artifactId>
			<version>5.2.1</version>
		</dependency>

		<!-- IK分词器 -->
		<dependency>
			<groupId>org.wltea.analyzer</groupId>
			<artifactId>ik-analyzer</artifactId>
			<version>5.3.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.solr</groupId>
			<artifactId>solr-solrj</artifactId>
			<version>5.2.1</version>
		</dependency>
		<!-- 爬虫jsoup -->
		<dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.9.1</version>
		</dependency>
	</dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <artifactId>jt-common</artifactId>
  <packaging>jar</packaging>

  <name>jt-common</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <parent>
  	<groupId>com.jt</groupId>
  	<artifactId>jt-parent</artifactId>
  	<version>0.0.1-SNAPSHOT</version>
  </parent>
</project>

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值