赞
踩
下面写个简单的token单一点登录系统来验证下。当访问系统未登录时,跳转到登录页,登录后进入首页,左侧导航栏展示默认菜单(首页)和有权限的菜单。
一、写在前面:关于session和token的使用,网上争议一直很大。总的来说争议在这里:
(1)session是空间换时间,而token是时间换空间。session占用空间,但是可以管理过期时间,token管理部了过期时间,但是不占用空间.
(2)sessionId失效问题和token内包含。
(3)session基于cookie,app请求并没有cookie 。
(4)token更加安全(每次请求都需要带上)。
二、效果:
前端:vue;
后端:springboot+dubbo+mybatis+spring sercurity+JWT+ token单一点登录。
效果:
分别启动前后端服务,访问首页http://localhost:9528/#/index,由于未登录,跳转到登录页

登录后跳转到首页,http://localhost:9528/#/dashboard

左侧菜单栏展开,显示所有的权限:
此时在postman调用一次登录接口,再次回到浏览器刷新或者调用接口(如点击用户管理页),跳转到登录页面。证明单一点登录实现。
三、数据库:
1、t_user:
![]()
2、t_role:

3、t_authority:

4、t_user_role:
![]()
5、t_role_authoriy:

四、后端代码:


1、pom:
- <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.demo</groupId>
- <artifactId>mysercurity-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </project>
2、dto:
- public class AuthorityDTO implements Serializable {
-
- private Integer id;
-
- private String authorityName;
-
- private String authorityCode;
- }
- public class RoleDTO implements Serializable {
-
- private Integer id;
-
- private String roleCode;
-
- private String roleName;
- }
- public class UserDTO implements Serializable {
-
- private Integer id;
-
- private String userName;
-
- private String password;
-
- private String userNickName;
-
- //验证码
- private String code;
-
- private List<RoleDTO> roles;
- }

1、pom:
- <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.demo</groupId>
- <artifactId>mysercurity-service</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-
- <!-- springBoot -->
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.4.1.RELEASE</version>
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <!-- api -->
- <dependency>
- <groupId>com.demo</groupId>
- <artifactId>mysercurity-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <!-- mybatis -->
- <dependency>
- <groupId>org.mybatis.spring.boot</groupId>
- <artifactId>mybatis-spring-boot-starter</artifactId>
- <version>1.1.1</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>5.1.21</version>
- </dependency>
-
-
- <!-- dubbo -->
- <dependency>
- <groupId>com.alibaba.spring.boot</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>2.0.0</version>
- </dependency>
-
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>3.2.1</version>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.5</version>
- </dependency>
-
- <!--zk-->
- <dependency>
- <groupId>com.github.sgroschupf</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.1</version>
- <exclusions>
- <exclusion>
- <artifactId>log4j</artifactId>
- <groupId>log4j</groupId>
- </exclusion>
- <exclusion>
- <artifactId>slf4j-log4j12</artifactId>
- <groupId>org.slf4j</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- </dependencies>
-
- </project>

2、application.properties:
- spring.datasource.driver-class-name=com.mysql.jdbc.Driver
- spring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
- spring.datasource.username=root
- spring.datasource.password=wtyy
-
- mybatis.mapper-locations=classpath*:Mapper/*Mapper.xml
-
- server.port=9998
-
3、provider.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:dubbo="http://code.alibabatech.com/schema/dubbo"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://code.alibabatech.com/schema/dubbo
- http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
- <dubbo:application name="mysercurity-service"/>
- <dubbo:provider timeout="3000" retries="0"/>
- <!-- register改为false不注册到注册中心 -->
- <dubbo:registry protocol="zookeeper" address="192.168.57.xxx:2181,192.168.57.xx:2181,192.168.59.xxx:2181"
- register="false" check="false"/>
- <dubbo:protocol name="dubbo" port="20881"/>
-
- <dubbo:service interface="com.demo.service.UserService" ref="userService"></dubbo:service>
- <dubbo:service interface="com.demo.service.RoleService" ref="roleService"></dubbo:service>
- </beans>

4、serviceImpl:
- package com.demo.service.impl;
- import com.demo.dao.UserRoleDao;
- import com.demo.dto.RoleDTO;
- import com.demo.service.RoleService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.util.List;
-
- @Service("roleService")
- public class RoleServiceImpl implements RoleService {
-
- @Autowired
- private UserRoleDao userRoleDao;
-
- @Override
- public List<RoleDTO> findRoleByUserId(Integer id) {
- return userRoleDao.findRoleByUserId(id);
- }
- }

- package com.demo.service.impl;
- import com.demo.dao.AuthorityDao;
- import com.demo.dao.UserDao;
- import com.demo.dao.UserRoleDao;
- import com.demo.dto.AuthorityDTO;
- import com.demo.dto.RoleDTO;
- import com.demo.dto.UserDTO;
- import com.demo.exception.UsernameNotFoundException;
- import com.demo.service.RoleService;
- import com.demo.service.UserService;
- import org.apache.commons.collections.CollectionUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.List;
- import java.util.stream.Collectors;
-
- @Service("userService")
- public class UserServiceImpl implements UserService {
-
- @Autowired
- private UserDao userDao;
-
- @Autowired
- private UserRoleDao userRoleDao;
-
- @Autowired
- private AuthorityDao authorityDao;
-
- @Autowired
- private RoleService roleService;
-
- @Override
- public UserDTO findByUserName(String username) {
-
- UserDTO user = userDao.findByUserName(username);
- if(user == null){
- throw new UsernameNotFoundException("用户不存在");
- }
- List<RoleDTO> roles = roleService.findRoleByUserId(user.getId());
- user.setRoles(roles);
- return user;
- }
-
- @Override
- public List<UserDTO> getAllUsers() {
- return userDao.getAllUsers();
- }
-
- @Override
- public List<AuthorityDTO> getAuthortiesByUserId(Integer userId) {
- List<RoleDTO> roles = userRoleDao.findRoleByUserId(userId);
- if(CollectionUtils.isNotEmpty(roles)){
- List<Integer> roleIds = roles.stream().map(RoleDTO::getId).collect(Collectors.toList());
- return authorityDao.getAuthortiesByRoleIds(roleIds);
- }
- return new ArrayList<>();
- }
-
- }

5、dao:
- public interface AuthorityDao {
- List<AuthorityDTO> getAuthortiesByRoleIds(@Param("roleIds") List<Integer> roleIds);
- }
- <?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.demo.dao.AuthorityDao">
- <select id="getAuthortiesByRoleIds" resultType="com.demo.dto.AuthorityDTO">
- select
- a.id id,
- a.authority_code authorityCode,
- a.authority_name authorityName
- from t_role_authoriy ra left join t_authority a on ra.authority_id = a.id
- where ra.role_id in
- <foreach collection="roleIds" item="item" open="(" close=")" separator=",">
- #{item}
- </foreach>
- and ra.is_delete = 0
- </select>
- </mapper>

- public interface UserDao {
- public UserDTO findByUserName(@Param("userName") String userAccount);
- List<UserDTO> getAllUsers();
- }
- <?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.demo.dao.UserDao">
- <select id="findByUserName" resultType="com.demo.dto.UserDTO">
- select
- id,
- user_nick_name userNickName,
- user_name userName,
- user_nick_name userNickName,
- user_password password
- from t_user where user_name = #{userName}
- and is_delete = 0
- </select>
-
- <select id="getAllUsers" resultType="com.demo.dto.UserDTO">
- select
- id,
- user_nick_name userNickName,
- user_name userName,
- user_nick_name userNickName
- from t_user
- </select>
- </mapper>

- public interface UserRoleDao {
- List<RoleDTO> findRoleByUserId(@Param("userId") Integer userId);
- }
- <?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.demo.dao.UserRoleDao">
- <select id="findRoleByUserId" resultType="com.demo.dto.RoleDTO">
- select
- r.id id,
- r.role_code roleCode,
- r.role_name roleName
- from t_user_role ur
- left join t_role r
- on ur.role_id = r.id
- where ur.user_id = #{userId}
- and is_delete = 0
- </select>
- </mapper>
6、启动类:
- package com.demo;
-
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.context.annotation.ImportResource;
-
- @SpringBootApplication
- @MapperScan("com.demo.dao")
- @ImportResource("classpath:provider.xml")
- public class ServiceStart {
- public static void main(String args[]){
- SpringApplication.run(ServiceStart.class,args);
- }
- }

1、pom:
- <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.demo</groupId>
- <artifactId>mysercurity-rest</artifactId>
- <version>0.0.1-SNAPSHOT</version>
-
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.4.1.RELEASE</version>
- </parent>
- <dependencies>
-
- <!--api-->
- <dependency>
- <groupId>com.demo</groupId>
- <artifactId>mysercurity-api</artifactId>
- <version>1.0.0-SNAPSHOT</version>
- </dependency>
-
- <!-- dubbo -->
- <dependency>
- <groupId>com.alibaba.spring.boot</groupId>
- <artifactId>dubbo-spring-boot-starter</artifactId>
- <version>2.0.0</version>
- </dependency>
-
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-security</artifactId>
- </dependency>
-
-
-
- <dependency>
- <groupId>io.jsonwebtoken</groupId>
- <artifactId>jjwt</artifactId>
- <version>0.9.0</version>
- </dependency>
-
- <!-- redis -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.springframework.session</groupId>
- <artifactId>spring-session-data-redis</artifactId>
- </dependency>
-
- <dependency>
- <groupId>redis.clients</groupId>
- <artifactId>jedis</artifactId>
- </dependency>
- <!--httpclient -->
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
- <version>4.5.6</version>
- </dependency>
-
- <dependency>
- <groupId>com.alibaba</groupId>
- <artifactId>fastjson</artifactId>
- <version>1.2.31</version>
- </dependency>
-
- <dependency>
- <groupId>commons-collections</groupId>
- <artifactId>commons-collections</artifactId>
- <version>3.2.1</version>
- </dependency>
- <dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <version>2.5</version>
- </dependency>
-
-
- <!--zk-->
- <dependency>
- <groupId>com.github.sgroschupf</groupId>
- <artifactId>zkclient</artifactId>
- <version>0.1</version>
- <exclusions>
- <exclusion>
- <artifactId>log4j</artifactId>
- <groupId>log4j</groupId>
- </exclusion>
- <exclusion>
- <artifactId>slf4j-log4j12</artifactId>
- <groupId>org.slf4j</groupId>
- </exclusion>
- </exclusions>
- </dependency>
-
- </dependencies>
- </project>

2、配置文件:
(1)application.properties:
- server.port=9999
- server.context-path=/demo
- spring.redis.host=localhost
- spring.redis.port=6379
- #spring.redis.password=
- spring.redis.database=1
- spring.redis.pool.max-active=8
- spring.redis.pool.max-wait=-1
- spring.redis.pool.max-idle=500
- spring.redis.pool.min-idle=0
- spring.redis.timeout=0
-
(2) consumer.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:dubbo="http://code.alibabatech.com/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
- <dubbo:application name="mysercurity-test" />
- <dubbo:consumer timeout="3000" retries="0" check="false"/>
- <dubbo:registry protocol="zookeeper" address="192.168.57.xxx:2181,192.168.57.xx:2181,192.168.59.xxx:2181" register="true" timeout="100000"/>
-
- <!-- 加上 url="dubbo://127.0.0.1:20881" 表示直连本地-->
- <dubbo:reference interface="com.demo.service.UserService" id="userService"
- url="dubbo://127.0.0.1:20881"/>
- <dubbo:reference interface="com.demo.service.RoleService" id="roleService"
- url="dubbo://127.0.0.1:20881"/>
- </beans>
-

3、config:
- package com.demo.config;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.CorsRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
-
- @Configuration
- public class WebMvcConfig extends WebMvcConfigurerAdapter {
-
- @Override
- public void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**").allowedHeaders("*")
- .allowedMethods("*")
- .allowedOrigins("*")
- .allowCredentials(true);
- }
- }

4、常量:
(1)CommonEnums:
- package com.demo.constants;
-
- public enum CommonEnums {
-
- CODE_200(200,"请求成功"),
- CODE_300(300,"登录成功"),
- CODE_301(301,"登录失败"),
- CODE_302(302,"退出成功"),
- CODE_303(303,"退出失败"),
- CODE_304(304,"用户或密码错误"),
- CODE_305(305,"账户已被锁定"),
- CODE_401(401,"授权失败"),
- CODE_400(400,"业务异常"),
- CODE_402(402,"非法请求"),
- CODE_403(403,"验证码错误"),
- CODE_405(405,"验证码无效"),
- CODE_500(500,"系统异常"),
-
- ;
- public final int code;
-
- public final String message;
-
- CommonEnums(int code, String message ) {
- this.code = code;
- this.message = message;
- }
-
- public int getCode() {
- return this.code;
- }
-
- public String getMessage() {
- return message;
- }
-
- public static String getEnumToValue(int code){
- for (CommonEnums statusEnum: CommonEnums.values()) {
- if (statusEnum.code == code){
- return statusEnum.message;
- }
- }
- return "";
- }
- }

(2)Constants :
- package com.demo.constants;
- public class Constants {
-
- public static final long EXPIRATIONTIME = (long)1000 * 60 * 60 * 24 * 1; //1 days
- public static final String SECRET = "spring-security-jwt";
- public static final String HEADER_STRING = "token";
- public static final String TOKEN_PREFIX = "Bearer";
- public static final String TOKEN_JWT="token_jwt:";
- public static final String JWT_USER="jwt_user:";
- public static final String LOCK="lock:";
- public static final String ERROR_NUM="error_num:";
- }
5、dto:
(1)JWTUserDTO:
- package com.demo.dto;
-
- import org.springframework.security.core.GrantedAuthority;
- import org.springframework.security.core.userdetails.UserDetails;
-
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.List;
-
- /**
- * 登录用户
- */
- public class JWTUserDTO implements UserDetails {
-
- private Integer id;
- private String userName;
- private String password;
- private String userNickName;
- private List<RoleDTO> roles = new ArrayList<>();
- private Collection<? extends GrantedAuthority> authorities;
-
- public JWTUserDTO(){
-
- }
-
- public JWTUserDTO(Integer id, String userName, String password, String userNickName,
- Collection<? extends GrantedAuthority> authorities, List<RoleDTO> roles){
- this.id = id;
- this.userName = userName;
- this.userNickName = userNickName;
- this.password = password;
- this.authorities = authorities;
- this.roles = roles;
- }
-
- @Override
- public String getUsername() {
- return userName;
- }
-
- @Override
- public boolean isAccountNonExpired() {
- return false;
- }
-
- @Override
- public boolean isAccountNonLocked() {
- return false;
- }
-
- @Override
- public boolean isCredentialsNonExpired() {
- return false;
- }
-
- @Override
- public boolean isEnabled() {
- return false;
- }
-
- public void setUsername(String username) {
- this.userName = username;
- }
-
- @Override
- public Collection<? extends GrantedAuthority> getAuthorities() {
- return authorities;
- }
-
- @Override
- public String getPassword() {
- return password;
- }
-
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
- this.authorities = authorities;
- }
-
- public List<RoleDTO> getRoles() {
- return roles;
- }
-
- public void setRoles(List<RoleDTO> roles) {
- this.roles = roles;
- }
-
- public String getUserName() {
- return userName;
- }
-
- public void setUserName(String userName) {
- this.userName = userName;
- }
-
- public String getUserNickName() {
- return userNickName;
- }
-
- public void setUserNickName(String userNickName) {
- this.userNickName = userNickName;
- }
- }

(2)ResponseMessage:
- package com.demo.dto;
-
- import com.demo.constants.CommonEnums;
-
- public class ResponseMessage {
-
- private int code;
-
- private String status;
-
- private String message;
-
- private String errorMessage;
-
- private String errorExceptionMessage;
-
- private Object data;
-
- public ResponseMessage(int code,String status,Object data){
- this.code = code;
- this.status = status;
- this.data = data;
- }
-
- public ResponseMessage(int code,String status,String message){
- this.code = code;
- this.status = status;
- this.message = message;
- }
-
- public ResponseMessage(int code,String status,String message,Object data){
- this.code = code;
- this.status = status;
- this.message = message;
- this.data = data;
- }
-
-
-
-
- public ResponseMessage(int code,String status,String message,String errorMessage){
- this.code = code;
- this.status = status;
- this.message = message;
- this.errorMessage = errorMessage;
- }
-
- public ResponseMessage(int code,String status,String message,String errorMessage,String errorExceptionMessage){
- this.code = code;
- this.status = status;
- this.message = message;
- this.errorMessage = errorMessage;
- this.errorExceptionMessage = errorExceptionMessage;
- }
-
-
- public static ResponseMessage success(String message){
- return new ResponseMessage(CommonEnums.CODE_200.code,"success",message);
- }
- public static ResponseMessage success(Object data){
- return new ResponseMessage(CommonEnums.CODE_200.code,"success",data);
- }
-
-
- public static ResponseMessage success(String message,Object data){
- return new ResponseMessage(CommonEnums.CODE_200.code,"success",message,data);
- }
-
- public static ResponseMessage success(int code,String message,Object data){
- return new ResponseMessage(code,"success",message,data);
- }
-
- public static ResponseMessage success(){
- return new ResponseMessage(CommonEnums.CODE_200.code,null,CommonEnums.CODE_200.message);
- }
-
- public static ResponseMessage success(int code,Object data){
- return new ResponseMessage(code,"success",data);
- }
-
-
- public static ResponseMessage success(int code,String message){
- return new ResponseMessage(code,"success",message);
- }
-
- public static ResponseMessage error(int code,String message){
- return new ResponseMessage(code,"error",message);
- }
-
- public static ResponseMessage error(int code,String message,String errorMessage){
- return new ResponseMessage(code,"error",message,errorMessage);
- }
-
- public static ResponseMessage error(int code,String message,String errorMessage,String errorExceptionMessage){
- return new ResponseMessage(code,"error",message,errorMessage,errorExceptionMessage);
- }
-
-
- public static ResponseMessage error(String message,String errorMessage){
- return new ResponseMessage(CommonEnums.CODE_500.code,"error",message,errorMessage);
- }
-
- public static ResponseMessage error(String message){
- return new ResponseMessage(CommonEnums.CODE_400.code,"error",message);
- }
-
- public static ResponseMessage infor(int code,String message){
- return new ResponseMessage(code,"infor",message);
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
-
- public Object getData() {
- return data;
- }
-
- public void setData(Object data) {
- this.data = data;
- }
-
- public String getErrorMessage() {
- return errorMessage;
- }
-
- public void setErrorMessage(String errorMessage) {
- this.errorMessage = errorMessage;
- }
-
- public String getErrorExceptionMessage() {
- return errorExceptionMessage;
- }
-
- public void setErrorExceptionMessage(String errorExceptionMessage) {
- this.errorExceptionMessage = errorExceptionMessage;
- }
-
- public int getCode() {
- return code;
- }
-
- public void setCode(int code) {
- this.code = code;
- }
- }

6、exception:
(1):
- package com.demo.exception;
-
- import com.alibaba.fastjson.JSON;
- import com.demo.constants.CommonEnums;
- import com.demo.dto.ResponseMessage;
- import org.apache.http.entity.ContentType;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.web.authentication.AuthenticationFailureHandler;
- import org.springframework.stereotype.Component;
-
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
-
- @Component
- public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler {
-
- @Override
- public void onAuthenticationFailure(HttpServletRequest httpServletRequest,
- HttpServletResponse httpServletResponse, AuthenticationException e)
- throws IOException, ServletException {
- httpServletResponse.setContentType(ContentType.APPLICATION_JSON.toString());
- httpServletResponse.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_304.code,CommonEnums.CODE_304.message)));
- }
- }

(2):
- package com.demo.exception;
-
- import com.alibaba.fastjson.JSON;
- import com.demo.constants.CommonEnums;
- import com.demo.dto.ResponseMessage;
- import org.apache.http.entity.ContentType;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.web.AuthenticationEntryPoint;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
-
- public class Http401AuthenticationEntryPoint implements AuthenticationEntryPoint {
-
-
- @Override
- public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException, ServletException {
- response.setContentType(ContentType.APPLICATION_JSON.toString());
- response.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_401.code,CommonEnums.CODE_401.message)));
- }
-
- }

(3):
- package com.demo.exception;
-
-
- public class TokenException extends RuntimeException {
-
- private static final long serialVersionUID = 1L;
-
- public TokenException(String message) {
- super(message);
- }
- }
7、factory:主要是全局上下文:
(1):
- package com.demo.factory;
-
-
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.BeansException;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.ApplicationContextAware;
- import org.springframework.stereotype.Component;
-
-
- @Component
- public class ApplicationContextRegister implements ApplicationContextAware {
- private static Logger logger = LoggerFactory.getLogger(ApplicationContextRegister.class);
- private static ApplicationContext APPLICATION_CONTEXT;
- /**
- * 设置spring上下文
- * @param applicationContext spring上下文
- * @throws BeansException
- * */
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- logger.debug("ApplicationContext registed-->{}", applicationContext);
- DefaultBeanFactory.setSpringApplicationContext(applicationContext);
- APPLICATION_CONTEXT = applicationContext;
- }
-
- /**
- * 获取容器
- * @return
- */
- public static ApplicationContext getApplicationContext() {
- return APPLICATION_CONTEXT;
- }
-
- /**
- * 获取容器对象
- * @param type
- * @param <T>
- * @return
- */
- public static <T> T getBean(Class<T> type) {
- return APPLICATION_CONTEXT.getBean(type);
- }
- }

(2):
- package com.demo.factory;
-
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
-
- public class DefaultBeanFactory {
- private static ApplicationContext context = null;
- private static DefaultBeanFactory instance = null;
- private static Object lock = new Object();
-
- private DefaultBeanFactory(String filepath){
- try {
- context = new ClassPathXmlApplicationContext(filepath);
- } catch (Exception e) {
- }
- }
- @SuppressWarnings("static-access")
- private DefaultBeanFactory(ApplicationContext context){
- try {
- this.context = context;
- } catch (Exception e) {
- }
- }
-
- public static void setSpringApplicationContext(ApplicationContext context){
- synchronized (lock) {
- instance = new DefaultBeanFactory(context);
- }
- }
- public static DefaultBeanFactory getInstance() {
- if(instance == null || context == null){
- throw new RuntimeException("Spring context is null!");
- }
- return instance;
- }
-
- public static DefaultBeanFactory getInstance(String filepath) {
- synchronized (lock) {
- instance = new DefaultBeanFactory(filepath);
- }
- return instance;
- }
- public Object getBean(String name) {
- return context.getBean(name);
- }
- }

(3):
- package com.demo.factory;
-
- import com.demo.util.RedisClient;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
-
- public class ServiceFactory {
-
- private static Logger logger = LoggerFactory.getLogger(ServiceFactory.class);
-
- private static ServiceFactory instance = new ServiceFactory();
-
- private final String REDIS_CLIENT_BEAN="redisClient";
-
- private final String USER_ACTION_LOG_SERVICE = "userActionLogService";
-
-
- public ServiceFactory() {
- // TODO Auto-generated constructor stub
- }
-
- public static ServiceFactory getInstance() {
- if (instance == null) {
- instance = new ServiceFactory();
- }
- return instance;
- }
-
- public RedisClient createRedisClient() {
- try {
- return (RedisClient) DefaultBeanFactory.getInstance().getBean(REDIS_CLIENT_BEAN);
- } catch (Exception e) {
- throw new RuntimeException("创建 createRedisClient BEAN 异常", e);
- }
- }
-
-
- }

8、filter:
(1):
- package com.demo.filter;
-
-
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.demo.constants.CommonEnums;
- import com.demo.constants.Constants;
- import com.demo.dto.JWTUserDTO;
- import com.demo.dto.ResponseMessage;
- import com.demo.dto.UserDTO;
- import com.demo.factory.ServiceFactory;
- import com.demo.service.UserService;
- import com.demo.util.JwtProvider;
- import com.demo.util.RedisClient;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.http.HttpStatus;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- import org.springframework.security.core.context.SecurityContextHolder;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
- import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
- import org.springframework.util.StringUtils;
-
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- import java.util.Objects;
- import org.apache.http.entity.ContentType;
-
- /**非登录接口拦截
- *
- * 自定义JWT认证过滤器
- * 该类继承自BasicAuthenticationFilter,在doFilterInternal方法中,
- * 从http头的Authorization 项读取token数据,然后用Jwts包提供的方法校验token的合法性。
- * 如果校验通过,就认为这是一个取得授权的合法请求
- */
- public class JWTAuthenticationFilter extends BasicAuthenticationFilter{
-
- private static final Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class);
-
- private static RedisClient redisClient;
-
- static {
- redisClient = ServiceFactory.getInstance().createRedisClient();
- }
- private UserService userService;
-
-
- public JWTAuthenticationFilter(AuthenticationManager authenticationManager,
- UserService userService) {
- super(authenticationManager);
- this.userService = userService;
- }
-
-
- @Override
- protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
-
- String token = request.getHeader(Constants.HEADER_STRING);
- String username = JwtProvider.getAuthentication(request);
- if(StringUtils.isEmpty(username)){
- response.sendError(HttpStatus.UNAUTHORIZED.value(), "Authentication Failed: username not found");
- return;
- }
-
- //效验token是否过期
-
- String tokenReids = redisClient.get(Constants.TOKEN_JWT+username);
- if (StringUtils.isEmpty(tokenReids)){
- logger.error("Token已过期: {} ",token);
- response.setContentType(ContentType.APPLICATION_JSON.toString());
- response.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_401.code,"Token已过期")));
- return;
- }
-
- if (!Objects.equals(tokenReids,token)){
- logger.error("Token不匹配: {} " + tokenReids);
- response.setContentType(ContentType.APPLICATION_JSON.toString());
- response.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_401.code,"Token不匹配")));
- return;
- }
-
- // if(SecurityContextHolder.getContext().getAuthentication() == null) {
- String userJson = redisClient.get(Constants.JWT_USER+username);
- UserDetails userDetails = null;
- if (!StringUtils.isEmpty(userJson)){
- JWTUserDTO jwtUser = JSONObject.parseObject(userJson,JWTUserDTO.class);
- userDetails = jwtUser;
- }else{
- UserDTO user = userService.findByUserName(username);
- userDetails = new JWTUserDTO(user.getId(),user.getUserName(),user.getPassword(),
- user.getUserNickName(),null,user.getRoles());
- redisClient.set(Constants.JWT_USER+username, JSONObject.toJSONString(userDetails));
- }
- UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
- authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
- SecurityContextHolder.getContext().setAuthentication(authentication);
- // }
- chain.doFilter(request, response);
-
- }
- }

(2):
- package com.demo.filter;
-
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.demo.constants.CommonEnums;
- import com.demo.constants.Constants;
- import com.demo.dto.JWTUserDTO;
- import com.demo.dto.ResponseMessage;
- import com.demo.dto.UserDTO;
- import com.demo.exception.CustomAuthenticationFailureHandler;
- import com.demo.factory.ServiceFactory;
- import com.demo.service.UserService;
- import com.demo.util.JwtProvider;
- import com.demo.util.RedisClient;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.apache.commons.lang.StringUtils;
- import org.apache.http.entity.ContentType;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.security.authentication.AuthenticationManager;
- import org.springframework.security.authentication.BadCredentialsException;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
- import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
- import javax.servlet.FilterChain;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.Objects;
-
- /**登录接口(/login)拦截
- *
- * 验证用户名密码正确后,生成一个token,并将token返回给客户端
- * 该类继承自UsernamePasswordAuthenticationFilter,重写了其中的2个方法
- * attemptAuthentication :接收并解析用户凭证。
- * successfulAuthentication :用户成功登录后,这个方法会被调用,我们在这个方法里生成token。
- */
- public class JWTLoginFilter extends UsernamePasswordAuthenticationFilter{
-
- private static Logger logger = LoggerFactory.getLogger(JWTLoginFilter.class);
- private AuthenticationManager authenticationManager;
- private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
- private UserService userService;
- private static RedisClient redisClient;
-
- static {
- redisClient = ServiceFactory.getInstance().createRedisClient();
- }
-
-
-
- public JWTLoginFilter(AuthenticationManager authenticationManager,
- CustomAuthenticationFailureHandler customAuthenticationFailureHandler,
- UserService userService) {
- this.authenticationManager = authenticationManager;
- this.customAuthenticationFailureHandler = customAuthenticationFailureHandler;
- this.userService = userService;
- setAuthenticationManager(authenticationManager);
- }
-
- // 接收并解析用户凭证
- @Override
- public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res) throws AuthenticationException {
- String userName = "";
- HttpSession httpSession = req.getSession();
-
- try {
- UserDTO user = new ObjectMapper().readValue(req.getInputStream(), UserDTO.class);
-
- //判断用户是否多次登录失败被锁定
- String lock = redisClient.get(Constants.LOCK+user.getUserName());
- if (StringUtils.isNotEmpty(lock)) {
- httpSession.setAttribute("code",null);
- Long time = redisClient.ttl(Constants.LOCK+user.getUserName());
- res.setContentType(ContentType.APPLICATION_JSON.toString());
- res.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_305.code, CommonEnums.CODE_305.message+":"+time+"秒后解锁")));
- return null;
- }
-
-
- //校验验证码
- if (StringUtils.isNotEmpty(user.getCode())){
- if (!Objects.equals(user.getCode(),"1111")){
- String code = (String) httpSession.getAttribute("code");
- if(StringUtils.isEmpty(code)){
- httpSession.setAttribute("code",null);
- res.setContentType(ContentType.APPLICATION_JSON.toString());
- res.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_405.code,CommonEnums.CODE_405.message)));
- return null;
- }
- if (!Objects.equals(user.getCode().toLowerCase(),code.toLowerCase())){
- httpSession.setAttribute("code",null);
- res.setContentType(ContentType.APPLICATION_JSON.toString());
- res.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_403.code,CommonEnums.CODE_403.message)));
- return null;
- }
- }
- }else{
- httpSession.setAttribute("code",null);
- res.setContentType(ContentType.APPLICATION_JSON.toString());
- res.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_405.code,CommonEnums.CODE_405.message)));
- }
- userName = user.getUserName();
- return authenticationManager.authenticate(
- new UsernamePasswordAuthenticationToken(
- user.getUserName(),
- user.getPassword(),
- new ArrayList<>())
- );
- }catch (IOException e) {
- throw new RuntimeException(e);
- }catch (UsernameNotFoundException | BadCredentialsException e){
- try {
- if (StringUtils.isNotEmpty(userName)){
- String errorNum = redisClient.get(Constants.ERROR_NUM+userName);
- if (StringUtils.isNotEmpty(errorNum)){
- if (Objects.equals(errorNum,"3")){
- httpSession.setAttribute("code",null);
- redisClient.set(Constants.LOCK+userName,"true",120);
- res.setContentType(ContentType.APPLICATION_JSON.toString());
- res.getWriter().write(JSON.toJSONString(ResponseMessage.error(CommonEnums.CODE_305.code,CommonEnums.CODE_305.message+":120秒后解锁")));
- }else{
- httpSession.setAttribute("code",null);
- redisClient.set(Constants.ERROR_NUM+userName,String.valueOf(Integer.valueOf(errorNum)+1),120);
- customAuthenticationFailureHandler.onAuthenticationFailure(req,res,e);
- }
- }else{
- httpSession.setAttribute("code",null);
- redisClient.set(Constants.ERROR_NUM+userName,"1",120);
- customAuthenticationFailureHandler.onAuthenticationFailure(req,res,e);
- }
- }else{
- httpSession.setAttribute("code",null);
- customAuthenticationFailureHandler.onAuthenticationFailure(req,res,e);
- }
- } catch (Exception e1) {
- throw new RuntimeException(e);
- }
- return null;
- }
- }
-
- // 用户成功登录后,这个方法会被调用,我们在这个方法里生成token
- @Override
- protected void successfulAuthentication(HttpServletRequest request,
- HttpServletResponse response,
- FilterChain chain,
- Authentication auth) throws IOException, ServletException {
- HttpSession httpSession = request.getSession();
- httpSession.setAttribute("code",null);
- redisClient.del(Constants.LOCK+auth.getName());
- redisClient.del(Constants.ERROR_NUM+auth.getName());
- String token = JwtProvider.addAuthentication(response, auth.getName());
- UserDTO userDTO = userService.findByUserName(auth.getName());
- JWTUserDTO userDetails = new JWTUserDTO(userDTO.getId(),userDTO.getUserName(),userDTO.getPassword(),
- userDTO.getUserNickName(),null,userDTO.getRoles());;
- redisClient.set(Constants.JWT_USER+auth.getName(), JSONObject.toJSONString(userDetails));
- response.setContentType(ContentType.APPLICATION_JSON.toString());
- response.getWriter().write(JSON.toJSONString(ResponseMessage.success(CommonEnums.CODE_300.code,CommonEnums.CODE_300.message,token)));
- }
-
- }

9、rest接口:
(1) :
- package com.demo.rest;
-
- import com.demo.dto.ResponseMessage;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.util.Random;
-
- @RestController
- @RequestMapping("/code")
- public class CodeController {
-
- private static Logger logger = LoggerFactory.getLogger(CodeController.class);
-
- /**
- * 获取验证码
- */
- @GetMapping(value = "/getCode")
- public ResponseMessage images(HttpServletRequest request, HttpServletResponse response) {
-
- try {
- HttpSession httpSession = request.getSession();
- Random r = new Random();
- String code = String.valueOf(r.nextInt(100));
- httpSession.setAttribute("code",code);
- return ResponseMessage.success("验证码",code);
- } catch (Exception e) {
- logger.error("ValidateCodeController images ERROR MESSAGE={}", e.getMessage(), e);
- }
- return ResponseMessage.error("");
- }
- }

(2):
- package com.demo.rest;
-
- import com.demo.constants.CommonEnums;
- import com.demo.constants.Constants;
- import com.demo.dto.AuthorityDTO;
- import com.demo.dto.JWTUserDTO;
- import com.demo.dto.ResponseMessage;
- import com.demo.dto.UserDTO;
- import com.demo.service.UserService;
- import com.demo.util.RedisClient;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.security.core.context.SecurityContextHolder;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RestController;
-
- import java.util.List;
-
- @RequestMapping("/user")
- @RestController
- public class UserController {
-
- @Autowired
- private UserService userService;
-
- @Autowired
- private RedisClient redisClient;
-
- /**
- * 获取所有用户
- * @return
- */
- @RequestMapping("/getAllUsers")
- public ResponseMessage getAllUsers(){
- List<UserDTO> users = userService.getAllUsers();
- return ResponseMessage.success(users);
- }
-
- /**
- * 获取权限
- */
- @RequestMapping("/getMyAuthorities")
- public ResponseMessage getMyAuthorities(){
- JWTUserDTO jwtUser = (JWTUserDTO) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
- Integer currentUserId = jwtUser.getId();
- List<AuthorityDTO> authorityDTOS= userService.getAuthortiesByUserId(currentUserId);
- return ResponseMessage.success(authorityDTOS);
- }
-
- @GetMapping(value = "/logout")
- public ResponseMessage logout(HttpServletRequest request) {
- try{
- JWTUserDTO jwtUser = (JWTUserDTO)SecurityContextHolder.getContext().getAuthentication().getPrincipal();
- String userName = jwtUser.getUsername();
- if (StringUtils.isEmpty(userName)){
- throw new RuntimeException(CommonEnums.CODE_303.message);
- }
- redisClient.del(Constants.TOKEN_JWT+userName);
- request.logout();
-
- }catch (Exception e){
-
- }
- return ResponseMessage.success(CommonEnums.CODE_200.code,CommonEnums.CODE_200.message);
- }
- }
-

10、sercurity:
- package com.demo.sercurity;
-
-
- import com.demo.exception.CustomAuthenticationFailureHandler;
- import com.demo.exception.Http401AuthenticationEntryPoint;
- import com.demo.filter.JWTAuthenticationFilter;
- import com.demo.filter.JWTLoginFilter;
- import com.demo.service.CustomAuthenticationProvider;
- import com.demo.service.UserService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.builders.WebSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.config.http.SessionCreationPolicy;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
- /**
- * SpringSecurity的配置
- * 通过SpringSecurity的配置,将JWTLoginFilter,JWTAuthenticationFilter组合在一起
- */
- @Configuration
- @EnableWebSecurity
- @EnableGlobalMethodSecurity(securedEnabled = true, jsr250Enabled = true, prePostEnabled = true)
- public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
-
- /**白名单
- * 需要放行的URL
- */
- private static final String[] AUTH_WHITELIST = {
- "/v2/api-docs",
- "/swagger-resources",
- "/swagger-resources/**",
- "/configuration/ui",
- "/configuration/security",
- "/swagger-ui.html",
- "/static",
- "/static/diagram-viewer",
- "/static/**",
- "/index.html",
- "/code/**", //验证码
-
- };
-
- @Autowired
- private UserService userService;
-
- @Autowired
- private CustomAuthenticationFailureHandler customAuthenticationFailureHandler;
-
-
- // 设置 HTTP 验证规则
- @Override
- protected void configure(HttpSecurity httpSecurity) throws Exception {
-
- httpSecurity.cors().and().csrf().disable()
- .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()
- .authorizeRequests()
- .anyRequest().authenticated() // 所有请求需要身份认证
- .and()
- .exceptionHandling()
- .authenticationEntryPoint(
- new Http401AuthenticationEntryPoint())
- .and()
- .addFilterBefore(new JWTLoginFilter(authenticationManager(),customAuthenticationFailureHandler,userService), UsernamePasswordAuthenticationFilter.class)
- .addFilterBefore(new JWTAuthenticationFilter(authenticationManager(),userService), UsernamePasswordAuthenticationFilter.class);
- //因为是spring整合了spring Security,本例加了session共享,每次检查原session的时候如果不存在的话,就会创建新的session,故需要手动设置
- httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.NEVER);
-
- }
-
- // 该方法是登录的时候会进入
- @Override
- public void configure(AuthenticationManagerBuilder auth) throws Exception {
- // 使用自定义身份验证组件
- auth.authenticationProvider(new CustomAuthenticationProvider(userService));
- }
-
- @Override
- public void configure(WebSecurity web) throws Exception {
- web.ignoring().antMatchers(AUTH_WHITELIST);
- }
-
- }

11、 service:
- package com.demo.service;
-
-
- import com.demo.dto.JWTUserDTO;
- import com.demo.dto.UserDTO;
- import com.demo.util.AESUtils;
- import com.demo.util.MD5Util;
- import org.springframework.security.authentication.AuthenticationProvider;
- import org.springframework.security.authentication.BadCredentialsException;
- import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
- import org.springframework.security.core.Authentication;
- import org.springframework.security.core.AuthenticationException;
- import org.springframework.security.core.userdetails.UserDetails;
- import org.springframework.security.core.userdetails.UsernameNotFoundException;
-
- import java.security.NoSuchAlgorithmException;
- import java.util.Objects;
-
- /**
- * 自定义身份认证验证组件
- */
- public class CustomAuthenticationProvider implements AuthenticationProvider {
- private UserService userService;
-
- public CustomAuthenticationProvider(
- UserService userService
- ){
- this.userService = userService;
- }
-
- @Override
- public Authentication authenticate(Authentication authentication) throws AuthenticationException {
- // 获取认证的用户名 & 密码
- //前端带入的username
- String username = authentication.getName();
- //前端带入的加密password
- String passwordRsa = authentication.getCredentials().toString();
- //passwordRsa解密后的密码
- String password = "";
- String passwordMd5 = "";
- //RSA解密
- try {
- password = AESUtils.decryptStr(passwordRsa,AESUtils.key);
- } catch (Exception e) {
- throw new UsernameNotFoundException("用户不存在");
- }
-
- UserDTO userDO = userService.findByUserName(username);
- if (userDO == null) {
- throw new UsernameNotFoundException("用户不存在");
- }
-
- //判断密码
- try {
- //md5加密
- passwordMd5 = MD5Util.MD5(password);
- } catch (NoSuchAlgorithmException e) {
- throw new UsernameNotFoundException("用户不存在");
- }
- if (!Objects.equals(passwordMd5,userDO.getPassword())){
- throw new BadCredentialsException("密码错误");
- }
-
- UserDTO userDTO = userService.findByUserName(username);
- JWTUserDTO userDetails = new JWTUserDTO(userDTO.getId(),userDTO.getUserName(),userDTO.getPassword(),
- userDTO.getUserNickName(),null,userDTO.getRoles());
- // 这里设置权限和角色
- Authentication auth = new UsernamePasswordAuthenticationToken(userDetails, null,userDetails.getAuthorities());
- return auth;
- }
-
- /**
- * 是否可以提供输入类型的认证服务
- * @param authentication
- * @return
- */
- @Override
- public boolean supports(Class<?> authentication) {
- return authentication.equals(UsernamePasswordAuthenticationToken.class);
- }
-
- }

12、util:
(1):
- package com.demo.util;
-
-
- import javax.crypto.*;
- import javax.crypto.spec.IvParameterSpec;
- import javax.crypto.spec.SecretKeySpec;
- import java.io.UnsupportedEncodingException;
- import java.nio.charset.Charset;
- import java.security.InvalidAlgorithmParameterException;
- import java.security.InvalidKeyException;
- import java.security.NoSuchAlgorithmException;
-
- public class AESUtils {
-
- private static String iv = "HGty&6%4ojyUyhgy";//偏移量字符串必须是16位 当模式是CBC的时候必须设置偏移量
- private static String Algorithm = "AES";
- private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; //算法/模式/补码方式
- public final static String key="FUjs@17654HGJKKn";
-
- public static byte[] generatorKey() throws NoSuchAlgorithmException {
- KeyGenerator keyGenerator = KeyGenerator.getInstance(Algorithm);
- keyGenerator.init(256);//默认128,获得无政策权限后可为192或256
- SecretKey secretKey = keyGenerator.generateKey();
- return secretKey.getEncoded();
- }
-
- public static IvParameterSpec getIv() throws UnsupportedEncodingException {
- IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
- System.out.println("偏移量:"+byteToHexString(ivParameterSpec.getIV()));
- return ivParameterSpec;
- }
-
- public static byte[] encrypt(String src, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException,
- InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
- SecretKey secretKey = new SecretKeySpec(key, Algorithm);
- IvParameterSpec ivParameterSpec = getIv();
- Cipher cipher = Cipher.getInstance(AlgorithmProvider);
- cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
- byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
- return cipherBytes;
- }
-
- public static byte[] decrypt(String src, byte[] key) throws Exception {
- SecretKey secretKey = new SecretKeySpec(key, Algorithm);
-
- IvParameterSpec ivParameterSpec = getIv();
- Cipher cipher = Cipher.getInstance(AlgorithmProvider);
- cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
- byte[] hexBytes = hexStringToBytes(src);
- byte[] plainBytes = cipher.doFinal(hexBytes);
- return plainBytes;
- }
-
- /**
- * 解密
- * @param src
- * @param keyStr
- * @return
- * @throws Exception
- */
- public static String decryptStr(String src, String keyStr) throws Exception {
-
- byte key[] = keyStr.getBytes("utf-8");
- SecretKey secretKey = new SecretKeySpec(key, Algorithm);
-
- IvParameterSpec ivParameterSpec = getIv();
- Cipher cipher = Cipher.getInstance(AlgorithmProvider);
- cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
- byte[] hexBytes = hexStringToBytes(src);
- byte[] plainBytes = cipher.doFinal(hexBytes);
- return new String(plainBytes,"UTF-8");
- }
-
-
- public static String encrypt(String src, String keyStr) throws NoSuchAlgorithmException, NoSuchPaddingException,
- InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
-
- byte key[] = keyStr.getBytes("utf-8");
- SecretKey secretKey = new SecretKeySpec(key, Algorithm);
- IvParameterSpec ivParameterSpec = getIv();
- Cipher cipher = Cipher.getInstance(AlgorithmProvider);
- cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
- byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
- return new String(cipherBytes,"UTF-8");
- }
-
- public static void main(String args[]){
- try {
- String passwordMd5 = MD5Util.MD5("123456");
- System.out.println("加密后密码:"+passwordMd5);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 将byte转换为16进制字符串
- * @param src
- * @return
- */
- public static String byteToHexString(byte[] src) {
- StringBuilder sb = new StringBuilder();
- for (int i = 0; i < src.length; i++) {
- int v = src[i] & 0xff;
- String hv = Integer.toHexString(v);
- if (hv.length() < 2) {
- sb.append("0");
- }
- sb.append(hv);
- }
- return sb.toString();
- }
-
- /**
- * 将16进制字符串装换为byte数组
- * @param hexString
- * @return
- */
- public static byte[] hexStringToBytes(String hexString) {
- hexString = hexString.toUpperCase();
- int length = hexString.length() / 2;
- char[] hexChars = hexString.toCharArray();
- byte[] b = new byte[length];
- for (int i = 0; i < length; i++) {
- int pos = i * 2;
- b[i] = (byte) (charToByte(hexChars[pos]) << 4 | (charToByte(hexChars[pos + 1]))& 0xff);
- }
- return b;
- }
-
- private static byte charToByte(char c) {
- return (byte) "0123456789ABCDEF".indexOf(c);
- }
-
-
- /*public static void main(String[] args) {
- try {
- // byte key[] = generatorKey();
- System.out.println("FUjs@17654HGJKKn".length());
- // 密钥必须是16的倍数
- byte key[] = "FUjs@17654HGJKKn".getBytes("utf-8");//hexStringToBytes("0123456789ABCDEF");
- String src = "usersrs=111111?sdfjsalkj=1mlkjklasjdfkls?sss=sdfsjlk1123123123?sdd=453456465432165765432221351567897654132";
- System.out.println("密钥:"+byteToHexString(key));
- System.out.println("原字符串:"+src);
-
- String enc = byteToHexString(encrypt(src, key));
- System.out.println("加密:"+enc);
- System.out.println("解密:"+decryptStr(enc, AESUtils.key));
- } catch (InvalidKeyException e) {
- e.printStackTrace();
- } catch (NoSuchAlgorithmException e) {
- e.printStackTrace();
- } catch (NoSuchPaddingException e) {
- e.printStackTrace();
- } catch (IllegalBlockSizeException e) {
- e.printStackTrace();
- } catch (BadPaddingException e) {
- e.printStackTrace();
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }*/
-
-
- }

(2):
- package com.demo.util;
-
- import org.apache.commons.codec.digest.DigestUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- import java.io.UnsupportedEncodingException;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.util.*;
-
- /**
- * Md5算法加密
- *
- * @author <a href="mailTo:helen@ibw.cn">Helen</a>
- * @time Mar 19, 2013
- * @version 1.0
- */
- public class MD5Util {
-
- private final static Logger logger = LoggerFactory.getLogger(MD5Util.class);
-
- private final static String APP_KEY="hYHN#1son@16faEV2";
- private final static String CHARSET="UTF-8";
- /**
- * MD5加密算法
- *
- * @param s
- * @return
- */
- public final static String MD5(String s) throws NoSuchAlgorithmException {
- char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F' };
- byte[] btInput = s.getBytes();
- // 获得MD5摘要算法的 MessageDigest 对象
- MessageDigest mdInst;
- mdInst = MessageDigest.getInstance("MD5");
- // 使用指定的字节更新摘要
- mdInst.update(btInput);
- // 获得密文
- byte[] md = mdInst.digest();
- // 把密文转换成十六进制的字符串形式
- int j = md.length;
- char str[] = new char[j * 2];
- int k = 0;
- for (int i = 0; i < j; i++) {
- byte byte0 = md[i];
- str[k++] = hexDigits[byte0 >>> 4 & 0xf];
- str[k++] = hexDigits[byte0 & 0xf];
- }
- return new String(str);
- }
-
-
- /**
- * 编码转换
- * @param content
- * @param charset
- * @return
- * @throws UnsupportedEncodingException
- */
- private static byte[] getContentBytes(String content, String charset) {
- if (charset == null || "".equals(charset)) {
- return content.getBytes();
- }
- try {
- return content.getBytes(charset);
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
- }
- }
-
- public static String sign(String prestr){
- String mysign = DigestUtils.md5Hex(getContentBytes(prestr + APP_KEY, CHARSET));
- return mysign;
- }
-
- public static String signParams(Map<String,String> params){
- try {
- if (params != null && params.size()>0){
- List<Map.Entry<String, String>> list = new ArrayList(params.entrySet());
- Collections.sort(list, new Comparator<Map.Entry<String,String>>() {
- @Override
- public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
- return o1.getKey().compareTo(o2.getKey());
- }
- });
- StringBuffer sb = new StringBuffer();
- for (Map.Entry<String, String> ent:list) {
- sb.append(ent.getKey());
- sb.append(ent.getValue());
- }
- logger.info("原字符串:{}",sb.toString());
- return sign(sb.toString());
- }
- }catch (Exception e){
-
- }
- return "";
- }
-
- public static boolean isSign(HashMap<String,String> params,String sign){
- try{
- String newSign = signParams(params);
- logger.info("原签名:{}",sign);
- logger.info("新签名:{}",newSign);
- if (Objects.equals(sign,newSign)){
- return true;
- }
- }catch (Exception e){
-
- }
- return false;
- }
-
-
-
- }

(3):
- package com.demo.util;
-
- import com.demo.constants.Constants;
- import com.demo.exception.TokenException;
- import com.demo.factory.ServiceFactory;
- import io.jsonwebtoken.*;
- import org.apache.commons.lang.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.util.Date;
-
- /**
- * token管理器
- */
- public class JwtProvider {
-
- private static final Logger logger = LoggerFactory.getLogger(JwtProvider.class);
- private static RedisClient redisClient;
-
- static {
- redisClient = ServiceFactory.getInstance().createRedisClient();
- }
-
- /**
- * 生成token并将token写入redis
- * @param res
- * @param username
- * @return
- */
- public static String addAuthentication(HttpServletResponse res, String username){
- String jwtStr = Jwts.builder()
- .setSubject(username)
- .setExpiration(new Date(System.currentTimeMillis() + Constants.EXPIRATIONTIME))
- .signWith(SignatureAlgorithm.HS512, Constants.SECRET)
- .compact();
- String tokent = jwtStr;
- res.addHeader(Constants.HEADER_STRING,tokent );
- //每次重置token,实现单一点登录
- redisClient.set(Constants.TOKEN_JWT+username,tokent);
- return tokent;
- }
-
- /**
- * 从token中获取username
- * @param req
- * @return
- */
- public static String getAuthentication(HttpServletRequest req){
- String token = req.getHeader(Constants.HEADER_STRING);
- String username = null;
- if(!StringUtils.isEmpty(token)){
- try{
- // parse the jwt
- username = Jwts.parser()
- .setSigningKey(Constants.SECRET)
- .parseClaimsJws(token)
- .getBody()
- .getSubject();
- }catch (ExpiredJwtException e) {
- logger.error("Token已过期: {} " + e);
- throw new TokenException("Token已过期");
- } catch (UnsupportedJwtException e) {
- logger.error("Token格式错误: {} " + e);
- throw new TokenException("Token格式错误");
- } catch (MalformedJwtException e) {
- logger.error("Token没有被正确构造: {} " + e);
- throw new TokenException("Token没有被正确构造");
- } catch (SignatureException e) {
- logger.error("签名失败: {} " + e);
- throw new TokenException("签名失败");
- } catch (IllegalArgumentException e) {
- logger.error("非法参数异常: {} " + e);
- throw new TokenException("非法参数异常");
- }
- }
- return username;
- }
- }

(4):
- package com.demo.util;
-
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import redis.clients.jedis.Jedis;
- import redis.clients.jedis.JedisPool;
- import redis.clients.jedis.JedisPoolConfig;
-
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.ObjectInputStream;
- import java.io.ObjectOutputStream;
- import java.lang.reflect.Field;
- import java.util.*;
-
- @Component
- public class RedisClient {
-
- private final Logger logger = LoggerFactory.getLogger(RedisClient.class);
-
- private final String SUCCESS_OK = "OK";
- private final Long SUCCESS_STATUS_LONG = 1L;
-
- // SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作
- private final String SET_IF_NOT_EXIST = "NX";
- // 给key加一个过期的设置,具体时间由第五个参数决定
- private final String SET_WITH_EXPIRE_TIME = "PX";
-
- private static JedisPool jedisPool;
-
- private static final String IP = "127.0.0.1"; // ip
- private static final int PORT = 6379; // 端口
- // private static final String AUTH=""; // 密码(原始默认是没有密码)
- private static int MAX_ACTIVE = 1024; // 最大连接数
- private static int MAX_IDLE = 200; // 设置最大空闲数
- private static int MAX_WAIT = 10000; // 最大连接时间
- private static int TIMEOUT = 10000; // 超时时间
- private static boolean BORROW = true; // 在borrow一个事例时是否提前进行validate操作
-
- /**
- * 初始化线程池
- */
- static {
- JedisPoolConfig config = new JedisPoolConfig();
- config.setMaxTotal(MAX_ACTIVE);
- config.setMaxIdle(MAX_IDLE);
- config.setMaxWaitMillis(MAX_WAIT);
- config.setTestOnBorrow(BORROW);
- jedisPool = new JedisPool(config, IP, PORT, TIMEOUT);
- }
-
- public JedisPool getJedisPool(){
- return jedisPool;
- }
-
- /**
- * 字符串set
- *
- * @param key
- * @param value
- * @return
- */
- public boolean set(String key, String value) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- String status = jedis.set(key, value);
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis set 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
-
-
- /**
- * 字符串set
- *
- * @param key
- * @param value
- * @param seconds
- * 单位秒,大于0
- * @return
- */
- public boolean set(String key, String value, int seconds) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- String status = jedis.setex(key, seconds, value);
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis set 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- public boolean set(byte[] key, int seconds, byte[] value) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- String status = jedis.setex(key, seconds, value);
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis set 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- /**
- * 是否存在key
- *
- * @param key
- * @return
- */
- public boolean isExists(String key) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- return jedis.exists(key);
- } catch (Exception e) {
- logger.error("redis isExists 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- /**
- * 字符串 删除
- *
- * @param key
- * @return
- */
- public boolean del(byte[] key) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- Long status = jedis.del(key);
- if (Objects.equals(SUCCESS_STATUS_LONG,status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis del 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- public boolean del(String key) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- Long status = jedis.del(key);
- if (Objects.equals(SUCCESS_STATUS_LONG,status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis del 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- /**
- * 字符串获取
- *
- * @param key
- * @return
- */
- public String get(String key) {
- String ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- ret = jedis.get(key);
- } catch (Exception e) {
- logger.error("redis get 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- public Long ttl(String key){
- Long ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- ret = jedis.ttl(key);
- } catch (Exception e) {
- logger.error("redis get 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- public byte[] get(byte[] key) {
- byte[] ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- ret = jedis.get(key);
- } catch (Exception e) {
- logger.error("redis get 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- /**
- * 获取分布式锁
- *
- * @param lockKey
- * key为锁
- * @param requestId
- * 加锁请求
- * @param expireTime
- * key的过期时间
- * @return
- */
- public boolean getLock(String lockKey, String requestId, int expireTime) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- String status = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis 获取分布式锁 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- /**
- * 释放分布式锁
- *
- * @param lockKey
- * @param requestId
- */
- public boolean releaseLock(String lockKey, String requestId) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- /*
- * 其他请求误解锁问题 if(requestId.equals(jedis.get(lockKey))) { jedis.del(lockKey); }
- */
-
- String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
- Object status = jedis.eval(script, Collections.singletonList(lockKey),
- Collections.singletonList(requestId));
- if (SUCCESS_STATUS_LONG.equals(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis 释放分布式锁 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
- return ret;
- }
-
- /**
- * 序列化存入对象
- *
- * @param key
- * @param obj
- * @return
- */
- public boolean set(byte[] key, Object obj) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- ObjectOutputStream oos = new ObjectOutputStream(baos);
- oos.writeObject(obj);
- String status = jedis.set(key, baos.toByteArray());
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis set 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
-
- }
-
- /**
- * 取序列化对象
- *
- * @param key
- * @return
- */
- public Object getObj(byte[] key) {
- Object ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
-
- byte[] rets = jedis.get(key);
- ByteArrayInputStream bais = new ByteArrayInputStream(rets);
- ObjectInputStream ois = new ObjectInputStream(bais);
- return ois.readObject();
- } catch (Exception e) {
- logger.error("redis get 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- /**
- * hash数据类型存储对象
- *
- * @param key
- * @param obj
- * @return
- */
- public boolean setHm(String key, Object obj) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- Map<String, String> hash = objToMap(obj);
- String status = jedis.hmset(key, hash);
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis setHm 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- /**
- * 修改对象属性
- *
- * @param key
- * @param field
- * @param value
- * @return
- */
- public boolean setHm(String key, String field, String value) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
-
- Long status = jedis.hset(key, field, value);
- if (0L == status) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis setHm 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- /**
- * 根据fields 查询key对象属性列表
- *
- * @param key
- * @param fields
- * @return
- */
- public List<String> getHm(String key, String... fields) {
- List<String> ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return null;
- }
- ret = jedis.hmget(key, fields);
- } catch (Exception e) {
- logger.error("redis getHm 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- /**
- * 根据field 查询key对象属性
- *
- * @param key
- * @param
- * @return
- */
- public String getHm(String key, String field) {
- String ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return null;
- }
-
- ret = jedis.hget(key, field);
-
- } catch (Exception e) {
- logger.error("redis getHm 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
-
-
- /**
- * json格式存对象
- * @param key
- * @param obj
- * @return
- */
- public boolean setJson(String key,Object obj) {
- boolean ret = false;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- ObjectMapper mapper = new ObjectMapper();
- String status = jedis.set(key, mapper.writeValueAsString(obj));
- if (SUCCESS_OK.equalsIgnoreCase(status)) {
- ret = true;
- }
- } catch (Exception e) {
- logger.error("redis setJson 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
- }
-
- /**
- * json格式取对象
- * @param key
- * @param clazz
- * @return
- */
- public Object getJson(String key,Class clazz) {
- Object ret = null;
- Jedis jedis = null;
- try {
- jedis = jedisPool.getResource();
- if (jedis == null) {
- return ret;
- }
- String str = jedis.get(key);
- ObjectMapper mapper = new ObjectMapper();
- ret = mapper.readValue(str, clazz);
- } catch (Exception e) {
- logger.error("redis getJson 出错", e);
- jedisPool.returnBrokenResource(jedis);
- } finally {
- if (null != jedis) {
- jedisPool.returnResource(jedis);
- }
- }
-
- return ret;
-
- }
-
- private HashMap<String, String> objToMap(Object obj) {
-
- if(null == obj) {
- return null;
- }
- HashMap<String, String> map = new HashMap<String, String>();
- Field[] fields = obj.getClass().getDeclaredFields();
- try {
- for (int i = 0; i < fields.length; i++) {
- String varName = fields[i].getName();
- boolean accessFlag = fields[i].isAccessible();
- fields[i].setAccessible(true);
-
- Object o = fields[i].get(obj);
- if (o != null) {
- map.put(varName, o.toString());
- }
-
- fields[i].setAccessible(accessFlag);
- }
- } catch (Exception e) {
-
- }
-
- return map;
- }
-
- /**
- * 设置一个key的过期的秒数
- *
- * @param keyFormat
- * key标识
- * @param seconds
- * 过期的秒数
- * @param keyValues
- * key变量
- * @return 1表示设置成功, 0 表示设置失败或者无法被设置
- */
- public Long expire(String key, int seconds) {
- Jedis jedis = null;
- try {
- jedis =jedisPool.getResource();
- return jedis.expire(key, seconds);
- } finally {
- if (jedis != null) {
- jedis.close();
- }
- }
- }
- }

12、启动类:
- package com.demo;
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
- import org.springframework.context.annotation.ImportResource;
-
- @SpringBootApplication
- @ImportResource("classpath:consumer.xml")
- public class RestStart {
-
- public static void main(String args[]){
- SpringApplication.run(RestStart.class,args);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。