1 files modified
54 files added
New file |
| | |
| | | HELP.md |
| | | target/ |
| | | logs/ |
| | | !.mvn/wrapper/maven-wrapper.jar |
| | | !**/src/main/** |
| | | !**/src/test/** |
| | | |
| | | ### STS ### |
| | | .apt_generated |
| | | .classpath |
| | | .factorypath |
| | | .project |
| | | .settings |
| | | .springBeans |
| | | .sts4-cache |
| | | |
| | | ### IntelliJ IDEA ### |
| | | .idea |
| | | *.iws |
| | | *.iml |
| | | *.ipr |
| | | |
| | | .mvn |
| | | mvnw |
| | | mvnw.cmd |
| | | |
| | | ### NetBeans ### |
| | | /nbproject/private/ |
| | | /nbbuild/ |
| | | /dist/ |
| | | /nbdist/ |
| | | /.nb-gradle/ |
| | | build/ |
| | | |
| | | ### VS Code ### |
| | | .vscode/ |
| | |
| | | # new_excoin |
| | | |
| | | #### 介绍 |
| | | excoin改版 |
| | | |
| | | #### 软件架构 |
| | | 软件架构说明 |
| | | |
| | | |
| | | #### 安装教程 |
| | | |
| | | 1. xxxx |
| | | 2. xxxx |
| | | 3. xxxx |
| | | |
| | | #### 使用说明 |
| | | |
| | | 1. xxxx |
| | | 2. xxxx |
| | | 3. xxxx |
| | | |
| | | #### 参与贡献 |
| | | |
| | | 1. Fork 本仓库 |
| | | 2. 新建 Feat_xxx 分支 |
| | | 3. 提交代码 |
| | | 4. 新建 Pull Request |
| | | |
| | | |
| | | #### 码云特技 |
| | | |
| | | 1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md |
| | | 2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) |
| | | 3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 |
| | | 4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 |
| | | 5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) |
| | | 6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) |
| | | # kss-framework
|
| | |
|
| | | #### 介绍
|
| | | {**以下是码云平台说明,您可以替换此简介**
|
| | | 码云是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台
|
| | | 无论是个人、团队、或是企业,都能够用码云实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
|
| | |
|
| | | #### 软件架构
|
| | | 软件架构说明
|
| | |
|
| | |
|
| | | #### 安装教程
|
| | |
|
| | | 1. xxxx
|
| | | 2. xxxx
|
| | | 3. xxxx
|
| | |
|
| | | #### 使用说明
|
| | |
|
| | | 1. mapstruct
|
| | | https://mapstruct.org/documentation/stable/reference/html/
|
| | |
|
| | | 2. mybatis-plus
|
| | | https://mybatis.plus/guide/#%E7%89%B9%E6%80%A7
|
| | | 3. 参数校验
|
| | | https://mp.weixin.qq.com/s/yRuLmtUkARG3OziHB9dJPw
|
| | |
|
| | | #### 参与贡献
|
| | |
|
| | | 1. Fork 本仓库
|
| | | 2. 新建 Feat_xxx 分支
|
| | | 3. 提交代码
|
| | | 4. 新建 Pull Request
|
| | |
|
| | |
|
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| | | <modelVersion>4.0.0</modelVersion> |
| | | <parent> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-parent</artifactId> |
| | | <version>2.2.6.RELEASE</version> |
| | | <relativePath/> <!-- lookup parent from repository --> |
| | | </parent> |
| | | <groupId>com.xcong</groupId> |
| | | <artifactId>excoin</artifactId> |
| | | <version>0.0.1-SNAPSHOT</version> |
| | | <name>excoin</name> |
| | | <description>Demo project for Spring Boot</description> |
| | | |
| | | <properties> |
| | | <java.version>1.8</java.version> |
| | | <mysql-driver.version>8.0.17</mysql-driver.version> |
| | | <alibaba-druid.version>1.1.18</alibaba-druid.version> |
| | | <mybatis.version>2.0.1</mybatis.version> |
| | | <mybatis-plus.version>3.3.1.tmp</mybatis-plus.version> |
| | | <validation-api.version>2.0.1.Final</validation-api.version> |
| | | <hibernate-validator.version>6.1.0.Final</hibernate-validator.version> |
| | | <swagger.version>2.9.2</swagger.version> |
| | | <io-swagger.version>1.5.23</io-swagger.version> |
| | | <mapstruct.version>1.3.1.Final</mapstruct.version> |
| | | <hutool.version>5.3.1</hutool.version> |
| | | <fastjson.version>1.2.61</fastjson.version> |
| | | </properties> |
| | | |
| | | <dependencies> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-web</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-actuator</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-security</artifactId> |
| | | </dependency> |
| | | |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>org.springframework.security</groupId>--> |
| | | <!-- <artifactId>spring-security-test</artifactId>--> |
| | | <!-- <scope>test</scope>--> |
| | | <!-- </dependency>--> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-data-redis</artifactId> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-devtools</artifactId> |
| | | <scope>runtime</scope> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | <optional>true</optional> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-starter-test</artifactId> |
| | | <scope>test</scope> |
| | | <exclusions> |
| | | <exclusion> |
| | | <groupId>org.junit.vintage</groupId> |
| | | <artifactId>junit-vintage-engine</artifactId> |
| | | </exclusion> |
| | | </exclusions> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.mybatis.spring.boot</groupId> |
| | | <artifactId>mybatis-spring-boot-starter</artifactId> |
| | | <version>${mybatis.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>com.baomidou</groupId> |
| | | <artifactId>mybatis-plus-boot-starter</artifactId> |
| | | <version>${mybatis-plus.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>druid-spring-boot-starter</artifactId> |
| | | <version>${alibaba-druid.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>mysql</groupId> |
| | | <artifactId>mysql-connector-java</artifactId> |
| | | <version>${mysql-driver.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- 参数校验 start --> |
| | | <dependency> |
| | | <groupId>javax.validation</groupId> |
| | | <artifactId>validation-api</artifactId> |
| | | <version>${validation-api.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>org.hibernate</groupId> |
| | | <artifactId>hibernate-validator</artifactId> |
| | | <version>${hibernate-validator.version}</version> |
| | | </dependency> |
| | | <!-- 参数校验 end --> |
| | | |
| | | <!-- swagger2 start --> |
| | | <dependency> |
| | | <groupId>io.springfox</groupId> |
| | | <artifactId>springfox-swagger2</artifactId> |
| | | <version>${swagger.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.swagger</groupId> |
| | | <artifactId>swagger-annotations</artifactId> |
| | | <version>${io-swagger.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.swagger</groupId> |
| | | <artifactId>swagger-models</artifactId> |
| | | <version>${io-swagger.version}</version> |
| | | </dependency> |
| | | <dependency> |
| | | <groupId>io.springfox</groupId> |
| | | <artifactId>springfox-swagger-ui</artifactId> |
| | | <version>${swagger.version}</version> |
| | | </dependency> |
| | | <!-- swagger2 end --> |
| | | |
| | | <!-- bean映射转化 --> |
| | | <dependency> |
| | | <groupId>org.mapstruct</groupId> |
| | | <artifactId>mapstruct</artifactId> |
| | | <version>${mapstruct.version}</version> |
| | | </dependency> |
| | | |
| | | <!-- <dependency>--> |
| | | <!-- <groupId>org.mapstruct</groupId>--> |
| | | <!-- <artifactId>mapstruct-processor</artifactId>--> |
| | | <!-- <version>${mapstruct.version}</version>--> |
| | | <!-- </dependency>--> |
| | | |
| | | <dependency> |
| | | <groupId>cn.hutool</groupId> |
| | | <artifactId>hutool-all</artifactId> |
| | | <version>${hutool.version}</version> |
| | | </dependency> |
| | | |
| | | <dependency> |
| | | <groupId>com.alibaba</groupId> |
| | | <artifactId>fastjson</artifactId> |
| | | <version>${fastjson.version}</version> |
| | | </dependency> |
| | | |
| | | |
| | | </dependencies> |
| | | |
| | | <build> |
| | | <plugins> |
| | | <plugin> |
| | | <groupId>org.springframework.boot</groupId> |
| | | <artifactId>spring-boot-maven-plugin</artifactId> |
| | | </plugin> |
| | | |
| | | <plugin> |
| | | <groupId>org.apache.maven.plugins</groupId> |
| | | <artifactId>maven-compiler-plugin</artifactId> |
| | | <version>3.5.1</version> |
| | | <configuration> |
| | | <source>${java.version}</source> |
| | | <target>${java.version}</target> |
| | | <annotationProcessorPaths> |
| | | <path> |
| | | <groupId>org.mapstruct</groupId> |
| | | <artifactId>mapstruct-processor</artifactId> |
| | | <version>${mapstruct.version}</version> |
| | | </path> |
| | | <path> |
| | | <groupId>org.projectlombok</groupId> |
| | | <artifactId>lombok</artifactId> |
| | | <version>${lombok.version}</version> |
| | | </path> |
| | | </annotationProcessorPaths> |
| | | </configuration> |
| | | </plugin> |
| | | </plugins> |
| | | </build> |
| | | </project> |
New file |
| | |
| | | package com.xcong.excoin; |
| | | |
| | | import org.mybatis.spring.annotation.MapperScan; |
| | | import org.springframework.boot.SpringApplication; |
| | | import org.springframework.boot.autoconfigure.SpringBootApplication; |
| | | import springfox.documentation.swagger2.annotations.EnableSwagger2; |
| | | |
| | | /** |
| | | * @author helius |
| | | */ |
| | | @EnableSwagger2 |
| | | @SpringBootApplication |
| | | @MapperScan("com.xcong.excoin.modules.*.dao") |
| | | public class ExcoinApplication { |
| | | |
| | | public static void main(String[] args) { |
| | | SpringApplication.run(ExcoinApplication.class, args); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.annotations; |
| | | |
| | | import java.lang.annotation.*; |
| | | |
| | | |
| | | /** |
| | | * 自动注入当前登录用户 |
| | | * |
| | | */ |
| | | @Target({ ElementType.PARAMETER, ElementType.TYPE }) |
| | | @Retention(RetentionPolicy.RUNTIME) |
| | | @Documented |
| | | public @interface UserAuth { |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.contants; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | public class AppContants { |
| | | |
| | | /** |
| | | * app用户登陆redis前缀 |
| | | */ |
| | | public static final String APP_LOGIN_PREFIX = "app_"; |
| | | |
| | | /** |
| | | * token头部 |
| | | */ |
| | | public static final String TOKEN_HEADER = "Authorization"; |
| | | |
| | | /** |
| | | * token start with |
| | | */ |
| | | public static final String TOKEN_START_WITH = "Bearer "; |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.response; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-29 11:27 |
| | | **/ |
| | | @Data |
| | | @ApiModel(value = "返回基类", description = "基础返回类") |
| | | public class Result implements Serializable { |
| | | |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | private static final int SUCCESS = 0; |
| | | |
| | | private static final int FAIL = -1; |
| | | |
| | | private static final int LOGIN_FAIL = -2; |
| | | |
| | | @ApiModelProperty(value = "状态码", example = "0") |
| | | private int code; |
| | | |
| | | @ApiModelProperty(value = "提示消息") |
| | | private String msg; |
| | | |
| | | @ApiModelProperty(value = "数据对象") |
| | | private Object data; |
| | | |
| | | public static Result ok(String msg) { |
| | | Result result = new Result(); |
| | | result.code = SUCCESS; |
| | | result.msg = msg; |
| | | return result; |
| | | } |
| | | |
| | | public static Result ok(String msg, Object data) { |
| | | Result result = new Result(); |
| | | result.code = SUCCESS; |
| | | result.msg = msg; |
| | | result.data = data; |
| | | return result; |
| | | } |
| | | |
| | | public static Result fail(String msg) { |
| | | Result result = new Result(); |
| | | result.code = FAIL; |
| | | result.msg = msg; |
| | | return result; |
| | | } |
| | | |
| | | public static Result loginFail(String msg) { |
| | | Result result = new Result(); |
| | | result.code = LOGIN_FAIL; |
| | | result.msg = msg; |
| | | return result; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.response; |
| | | |
| | | /** |
| | | * 状态码 |
| | | * @author wzy |
| | | */ |
| | | public enum ResultCode { |
| | | /** |
| | | * 成功 |
| | | */ |
| | | SUCCESS("1", "成功"), |
| | | |
| | | /** |
| | | * 失败 |
| | | */ |
| | | FAIL("0", "失败"); |
| | | |
| | | |
| | | private String code; |
| | | private String message; |
| | | |
| | | ResultCode(String code, String message) { |
| | | this.code = code; |
| | | this.message = message; |
| | | } |
| | | |
| | | public String code() { |
| | | return this.code; |
| | | } |
| | | |
| | | public String message() { |
| | | return this.message; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.system.base; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonFormat; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-24 14:58 |
| | | **/ |
| | | @Data |
| | | public class BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = 1L; |
| | | |
| | | private Long id; |
| | | |
| | | private String createBy; |
| | | |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date createTime; |
| | | |
| | | private String updateBy; |
| | | |
| | | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") |
| | | private Date updateTime; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.system.base; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | |
| | | /** |
| | | * @author wzy |
| | | */ |
| | | public interface IBaseService<T> extends IService<T> { |
| | | T findById(Object id); |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.system.bean; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonIgnore; |
| | | import com.xcong.excoin.modules.member.entity.MemberEntity; |
| | | import lombok.AllArgsConstructor; |
| | | import lombok.Getter; |
| | | import org.springframework.security.core.GrantedAuthority; |
| | | import org.springframework.security.core.userdetails.UserDetails; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Getter |
| | | @AllArgsConstructor |
| | | public class LoginUserBean implements UserDetails { |
| | | |
| | | private final MemberEntity memberEntity; |
| | | |
| | | private final List<Long> roles; |
| | | |
| | | private final List<GrantedAuthority> authorities; |
| | | |
| | | @JsonIgnore |
| | | @Override |
| | | public String getPassword() { |
| | | return memberEntity.getPassword(); |
| | | } |
| | | |
| | | @JsonIgnore |
| | | @Override |
| | | public String getUsername() { |
| | | return memberEntity.getUsername(); |
| | | } |
| | | |
| | | @JsonIgnore |
| | | @Override |
| | | public boolean isAccountNonExpired() { |
| | | return true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | @Override |
| | | public boolean isAccountNonLocked() { |
| | | return true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | @Override |
| | | public boolean isCredentialsNonExpired() { |
| | | return true; |
| | | } |
| | | |
| | | @JsonIgnore |
| | | @Override |
| | | public boolean isEnabled() { |
| | | return true; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.system.controller; |
| | | |
| | | import cn.hutool.core.util.IdUtil; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.xcong.excoin.common.contants.AppContants; |
| | | import com.xcong.excoin.common.response.Result; |
| | | import com.xcong.excoin.common.system.bean.LoginUserBean; |
| | | import com.xcong.excoin.common.system.dto.LoginDto; |
| | | import com.xcong.excoin.utils.RedisUtils; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| | | import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.validation.annotation.Validated; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | /** |
| | | * @Author wzy |
| | | * @Date 2020/5/11 |
| | | * @email wangdoubleone@gmail.com |
| | | * @Version V1.0 |
| | | **/ |
| | | @Slf4j |
| | | @RestController |
| | | @RequestMapping(value = "/") |
| | | public class LoginController { |
| | | |
| | | @Value("${rsa.private_key}") |
| | | private String privateKey; |
| | | |
| | | @Resource |
| | | private AuthenticationManagerBuilder authenticationManagerBuilder; |
| | | |
| | | @Resource |
| | | private RedisUtils redisUtils; |
| | | |
| | | @PostMapping("/login") |
| | | public Result login(@RequestBody @Validated LoginDto loginDto) { |
| | | UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword()); |
| | | Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authToken); |
| | | String token = IdUtil.simpleUUID(); |
| | | LoginUserBean loginUserBean = (LoginUserBean) authentication.getPrincipal(); |
| | | redisUtils.set(AppContants.APP_LOGIN_PREFIX + token, JSONObject.toJSONString(loginUserBean), 300000); |
| | | Map<String, Object> authInfo = new HashMap<String, Object>(2){ |
| | | { |
| | | put("token", token); |
| | | put("user", loginUserBean); |
| | | } |
| | | }; |
| | | return Result.ok("success", authInfo); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.system.dto; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Data |
| | | public class LoginDto { |
| | | |
| | | @NotBlank(message = "用户名或密码错误") |
| | | private String username; |
| | | |
| | | @NotBlank(message = "用户名或密码错误") |
| | | private String password; |
| | | |
| | | private String code; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.common.system.service; |
| | | |
| | | import com.xcong.excoin.common.system.bean.LoginUserBean; |
| | | import com.xcong.excoin.modules.member.entity.MemberEntity; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.security.core.GrantedAuthority; |
| | | import org.springframework.security.core.userdetails.UserDetailsService; |
| | | import org.springframework.security.core.userdetails.UsernameNotFoundException; |
| | | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @Author wzy |
| | | * @Date 2020/5/11 |
| | | * @email wangdoubleone@gmail.com |
| | | * @Version V1.0 |
| | | **/ |
| | | @Slf4j |
| | | @Service("userDetailsService") |
| | | public class UserDetailsServiceImpl implements UserDetailsService { |
| | | |
| | | @Override |
| | | public LoginUserBean loadUserByUsername(String username) throws UsernameNotFoundException { |
| | | List<GrantedAuthority> grantedAuthorities = new ArrayList<>(); |
| | | // GrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN"); |
| | | // grantedAuthorities.add(grantedAuthority); |
| | | |
| | | MemberEntity memberEntity = new MemberEntity(); |
| | | memberEntity.setId(1L); |
| | | memberEntity.setUsername("11111"); |
| | | memberEntity.setPassword(new BCryptPasswordEncoder().encode("123456")); |
| | | |
| | | return new LoginUserBean(memberEntity, null, null); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations; |
| | | |
| | | import com.xcong.excoin.common.response.Result; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.dao.DuplicateKeyException; |
| | | import org.springframework.security.authentication.BadCredentialsException; |
| | | import org.springframework.validation.FieldError; |
| | | import org.springframework.web.bind.MethodArgumentNotValidException; |
| | | import org.springframework.web.bind.annotation.ExceptionHandler; |
| | | import org.springframework.web.bind.annotation.RestControllerAdvice; |
| | | |
| | | import javax.validation.ValidationException; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-08 15:40 |
| | | **/ |
| | | @RestControllerAdvice |
| | | @Slf4j |
| | | public class GlobalExceptionHandler { |
| | | |
| | | /** |
| | | * 方法参数校验 |
| | | * |
| | | * @param e |
| | | * @return |
| | | */ |
| | | @ExceptionHandler(value = {MethodArgumentNotValidException.class}) |
| | | public Result handleException(MethodArgumentNotValidException e) { |
| | | log.error(e.getMessage()); |
| | | FieldError fieldError = e.getBindingResult().getFieldError(); |
| | | if (fieldError != null) { |
| | | return Result.fail(fieldError.getDefaultMessage()); |
| | | } else { |
| | | return Result.fail("参数校验失败"); |
| | | } |
| | | } |
| | | |
| | | |
| | | @ExceptionHandler(value = {ValidationException.class}) |
| | | public Result handleException(ValidationException e) { |
| | | log.error(e.getMessage(), e); |
| | | return null; |
| | | } |
| | | |
| | | @ExceptionHandler(value = {DuplicateKeyException.class}) |
| | | public Result handleException(DuplicateKeyException e) { |
| | | log.error(e.getMessage(), e); |
| | | return null; |
| | | } |
| | | |
| | | @ExceptionHandler(value = {Exception.class}) |
| | | public Result handleException(Exception e) { |
| | | log.error(e.getMessage(), e); |
| | | return Result.fail("系统异常"); |
| | | } |
| | | |
| | | /** |
| | | * spring security 账户密码验证异常 |
| | | * |
| | | * @param e |
| | | * @return |
| | | */ |
| | | @ExceptionHandler(value = { BadCredentialsException.class }) |
| | | public Result handleException(BadCredentialsException e) { |
| | | log.error(e.getMessage(), e); |
| | | return Result.fail("用户名或密码错误"); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations; |
| | | |
| | | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-29 11:17 |
| | | **/ |
| | | @Configuration |
| | | public class MybatisPlusConfig { |
| | | |
| | | /** |
| | | * 分页插件 |
| | | * |
| | | * @return |
| | | */ |
| | | @Bean |
| | | public PaginationInterceptor paginationInterceptor(){ |
| | | return new PaginationInterceptor(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations; |
| | | |
| | | import com.fasterxml.jackson.annotation.JsonAutoDetect; |
| | | import com.fasterxml.jackson.annotation.PropertyAccessor; |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import org.springframework.cache.annotation.EnableCaching; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.data.redis.connection.RedisConnectionFactory; |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; |
| | | import org.springframework.data.redis.serializer.StringRedisSerializer; |
| | | |
| | | /** |
| | | * @Author wzy |
| | | * @Date 2020/5/10 |
| | | * @email wangdoubleone@gmail.com |
| | | * @Version V1.0 |
| | | **/ |
| | | @EnableCaching |
| | | @Configuration |
| | | public class RedisConfig { |
| | | |
| | | @Bean |
| | | @SuppressWarnings("all") |
| | | public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { |
| | | RedisTemplate<String, Object> template = new RedisTemplate<>(); |
| | | template.setConnectionFactory(factory); |
| | | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); |
| | | ObjectMapper om = new ObjectMapper(); |
| | | om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); |
| | | om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); |
| | | jackson2JsonRedisSerializer.setObjectMapper(om); |
| | | StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); |
| | | // key采用String的序列化方式 |
| | | template.setKeySerializer(stringRedisSerializer); |
| | | // hash的key也采用String的序列化方式 |
| | | template.setHashKeySerializer(stringRedisSerializer); |
| | | // value序列化方式采用jackson |
| | | template.setValueSerializer(jackson2JsonRedisSerializer); |
| | | // hash的value序列化方式采用jackson |
| | | template.setHashValueSerializer(jackson2JsonRedisSerializer); |
| | | template.afterPropertiesSet(); |
| | | return template; |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations; |
| | | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import springfox.documentation.builders.ApiInfoBuilder; |
| | | import springfox.documentation.builders.ParameterBuilder; |
| | | import springfox.documentation.builders.PathSelectors; |
| | | import springfox.documentation.builders.RequestHandlerSelectors; |
| | | import springfox.documentation.schema.ModelRef; |
| | | import springfox.documentation.service.ApiInfo; |
| | | import springfox.documentation.service.Parameter; |
| | | import springfox.documentation.spi.DocumentationType; |
| | | import springfox.documentation.spring.web.plugins.Docket; |
| | | import springfox.documentation.swagger2.annotations.EnableSwagger2; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @Author wzy |
| | | * @Date 2020/5/11 |
| | | * @email wangdoubleone@gmail.com |
| | | * @Version V1.0 |
| | | **/ |
| | | @Configuration |
| | | @EnableSwagger2 |
| | | public class SwaggerConfig { |
| | | |
| | | @Bean |
| | | public Docket createRestApi(){ |
| | | // 添加请求参数,我们这里把token作为请求头部参数传入后端 |
| | | ParameterBuilder parameterBuilder = new ParameterBuilder(); |
| | | List<Parameter> parameters = new ArrayList<Parameter>(); |
| | | parameterBuilder.name("Authorization").description("令牌").modelRef(new ModelRef("string")).parameterType("header") |
| | | .required(false).build(); |
| | | parameters.add(parameterBuilder.build()); |
| | | return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select().apis(RequestHandlerSelectors.any()) |
| | | .paths(PathSelectors.any()).build().globalOperationParameters(parameters); |
| | | } |
| | | |
| | | private ApiInfo apiInfo(){ |
| | | return new ApiInfoBuilder() |
| | | .title("ExCoin") |
| | | .description("This is a restful api document of ExCoin.") |
| | | .version("1.0") |
| | | .build(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations; |
| | | |
| | | import com.xcong.excoin.utils.SpringContextHolder; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.boot.SpringBootConfiguration; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.web.servlet.config.annotation.CorsRegistry; |
| | | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; |
| | | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-27 11:54 |
| | | **/ |
| | | @SpringBootConfiguration |
| | | @Slf4j |
| | | public class WebMvcConfig implements WebMvcConfigurer { |
| | | |
| | | @Override |
| | | public void addInterceptors(InterceptorRegistry registry) { |
| | | } |
| | | |
| | | /** |
| | | * 设置cors跨域支持 |
| | | * |
| | | * @param registry |
| | | */ |
| | | @Override |
| | | public void addCorsMappings(CorsRegistry registry) { |
| | | registry.addMapping("/**") |
| | | .allowedOrigins("*") |
| | | .allowedMethods("GET", "HEAD", "POST", "PUT", "DELETE", "OPTIONS") |
| | | .allowCredentials(true).maxAge(3600); |
| | | } |
| | | |
| | | @Bean |
| | | public SpringContextHolder springContextHolder() { |
| | | return new SpringContextHolder(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.i18n; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.util.Locale; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-30 14:56 |
| | | **/ |
| | | @Configuration |
| | | public class CustomLocaleResolver implements LocaleResolver { |
| | | |
| | | @Override |
| | | public Locale resolveLocale(HttpServletRequest httpServletRequest) { |
| | | String lang = httpServletRequest.getHeader("lang"); |
| | | if(StrUtil.isBlank(lang)) { |
| | | return new Locale("zh", "CN"); |
| | | } else { |
| | | String[] splite = lang.split("_"); |
| | | return new Locale(splite[0], splite[1]); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void setLocale(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Locale locale) { |
| | | |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.i18n; |
| | | |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.web.servlet.LocaleResolver; |
| | | |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-27 11:55 |
| | | **/ |
| | | @Configuration |
| | | public class LocaleResolverConfig { |
| | | |
| | | @Bean |
| | | public LocaleResolver localeResolver() { |
| | | return new CustomLocaleResolver(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.interceptor; |
| | | |
| | | /** |
| | | * mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间 |
| | | * |
| | | * @author wzy |
| | | * @date 2020-05-13 |
| | | **/ |
| | | public class MybatisInterceptor { |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * 应用配置 |
| | | * |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Data |
| | | @Configuration |
| | | @ConfigurationProperties(prefix = "app") |
| | | public class ApplicationProperties { |
| | | private boolean debug; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.properties; |
| | | |
| | | import lombok.Data; |
| | | import org.springframework.boot.context.properties.ConfigurationProperties; |
| | | import org.springframework.context.annotation.Configuration; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-13 |
| | | **/ |
| | | @Data |
| | | @Configuration |
| | | @ConfigurationProperties(prefix = "rsa") |
| | | public class SecurityProperties { |
| | | |
| | | private String privateKey; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.security; |
| | | |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.xcong.excoin.common.response.Result; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.security.access.AccessDeniedException; |
| | | import org.springframework.security.web.access.AccessDeniedHandler; |
| | | |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import javax.servlet.http.HttpServletResponse; |
| | | import java.io.IOException; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Slf4j |
| | | public class CustomAccessDeniedHandler implements AccessDeniedHandler { |
| | | @Override |
| | | public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AccessDeniedException e) throws IOException, ServletException { |
| | | Result result = Result.loginFail("fail"); |
| | | httpServletResponse.getWriter().write(new ObjectMapper().writeValueAsString(result)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.security; |
| | | |
| | | import com.fasterxml.jackson.databind.ObjectMapper; |
| | | import com.xcong.excoin.common.response.Result; |
| | | 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; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | public class CustomAuthenticationEntryPoint implements AuthenticationEntryPoint { |
| | | |
| | | @Override |
| | | public void commence(HttpServletRequest httpServletRequest, HttpServletResponse response, AuthenticationException e) throws IOException, ServletException { |
| | | Result result = Result.loginFail("fail"); |
| | | response.setCharacterEncoding("UTF-8"); |
| | | response.setContentType("application/json; charset=utf-8"); |
| | | response.getWriter().write(new ObjectMapper().writeValueAsString(result)); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.security; |
| | | |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.security.config.annotation.SecurityConfigurerAdapter; |
| | | import org.springframework.security.config.annotation.web.builders.HttpSecurity; |
| | | import org.springframework.security.web.DefaultSecurityFilterChain; |
| | | import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @RequiredArgsConstructor |
| | | public class TokenConfigurer extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> { |
| | | |
| | | @Override |
| | | public void configure(HttpSecurity http) { |
| | | TokenFilter customFilter = new TokenFilter(); |
| | | http.addFilterBefore(customFilter, UsernamePasswordAuthenticationFilter.class); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.security; |
| | | |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.crypto.asymmetric.KeyType; |
| | | import cn.hutool.crypto.asymmetric.RSA; |
| | | import com.alibaba.fastjson.JSONObject; |
| | | import com.xcong.excoin.common.contants.AppContants; |
| | | import com.xcong.excoin.common.system.bean.LoginUserBean; |
| | | import com.xcong.excoin.configurations.properties.ApplicationProperties; |
| | | import com.xcong.excoin.configurations.properties.SecurityProperties; |
| | | import com.xcong.excoin.utils.RedisUtils; |
| | | import com.xcong.excoin.utils.SpringContextHolder; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; |
| | | import org.springframework.security.core.Authentication; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.util.StringUtils; |
| | | import org.springframework.web.filter.GenericFilterBean; |
| | | |
| | | import javax.servlet.FilterChain; |
| | | import javax.servlet.ServletException; |
| | | import javax.servlet.ServletRequest; |
| | | import javax.servlet.ServletResponse; |
| | | import javax.servlet.http.HttpServletRequest; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Slf4j |
| | | public class TokenFilter extends GenericFilterBean { |
| | | |
| | | private final ApplicationProperties applicationProperties = SpringContextHolder.getBean(ApplicationProperties.class); |
| | | |
| | | private final SecurityProperties securityProperties = SpringContextHolder.getBean(SecurityProperties.class); |
| | | |
| | | private final RedisUtils redisUtils = SpringContextHolder.getBean(RedisUtils.class); |
| | | |
| | | @Override |
| | | public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { |
| | | HttpServletRequest request = (HttpServletRequest) servletRequest; |
| | | String token = resolveToken(request); |
| | | if (StrUtil.isNotBlank(token)) { |
| | | String loginStr = (String) redisUtils.get(AppContants.APP_LOGIN_PREFIX + token); |
| | | if (StrUtil.isNotBlank(loginStr)) { |
| | | LoginUserBean loginUser = JSONObject.parseObject(loginStr, LoginUserBean.class); |
| | | Authentication authentication = new UsernamePasswordAuthenticationToken(loginUser.getMemberEntity(), token, new ArrayList<>()); |
| | | SecurityContextHolder.getContext().setAuthentication(authentication); |
| | | redisUtils.expire(AppContants.APP_LOGIN_PREFIX + token, 300000); |
| | | } else { |
| | | SecurityContextHolder.clearContext(); |
| | | } |
| | | } else { |
| | | SecurityContextHolder.clearContext(); |
| | | } |
| | | |
| | | filterChain.doFilter(servletRequest, servletResponse); |
| | | } |
| | | |
| | | /** |
| | | * 解析前端传来的token,先去掉Bearer,在rsa解密得到token_time,返回token,并判断time与当前是否在5s内 |
| | | * |
| | | * @param request |
| | | * @return |
| | | */ |
| | | private String resolveToken(HttpServletRequest request) { |
| | | try { |
| | | String bearerToken = request.getHeader(AppContants.TOKEN_HEADER); |
| | | if (StringUtils.hasText(bearerToken) && bearerToken.startsWith(AppContants.TOKEN_START_WITH)) { |
| | | // 去掉令牌前缀 |
| | | String rsaToken = bearerToken.replace(AppContants.TOKEN_START_WITH, ""); |
| | | RSA rsa = new RSA(securityProperties.getPrivateKey(), null); |
| | | String[] tokens = StrUtil.split(rsa.decryptStr(rsaToken, KeyType.PrivateKey), "_"); |
| | | |
| | | if (verifyTokenExpired(Long.parseLong(tokens[1]))) { |
| | | return tokens[0]; |
| | | } |
| | | return null; |
| | | } |
| | | } catch (Exception e) { |
| | | log.error("#解析token异常#", e); |
| | | return null; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private Boolean verifyTokenExpired(Long time) { |
| | | boolean isDebug = applicationProperties.isDebug(); |
| | | if (!isDebug) { |
| | | long currentTime = System.currentTimeMillis(); |
| | | return currentTime - time <= 5000; |
| | | } |
| | | return true; |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.configurations.security; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.annotation.Bean; |
| | | import org.springframework.context.annotation.Configuration; |
| | | import org.springframework.http.HttpMethod; |
| | | 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.configuration.EnableWebSecurity; |
| | | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; |
| | | import org.springframework.security.core.userdetails.UserDetailsService; |
| | | import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; |
| | | import org.springframework.security.crypto.password.PasswordEncoder; |
| | | import org.springframework.security.web.AuthenticationEntryPoint; |
| | | import org.springframework.security.web.access.AccessDeniedHandler; |
| | | |
| | | import javax.annotation.Resource; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-11 |
| | | **/ |
| | | @Slf4j |
| | | @Configuration |
| | | @EnableWebSecurity |
| | | @EnableGlobalMethodSecurity(prePostEnabled = true) |
| | | public class WebSecurityConfig extends WebSecurityConfigurerAdapter { |
| | | |
| | | @Resource |
| | | private UserDetailsService userDetailsService; |
| | | |
| | | @Override |
| | | protected void configure(HttpSecurity http) throws Exception { |
| | | http.httpBasic().and(). |
| | | cors().and().csrf().disable() |
| | | .exceptionHandling().authenticationEntryPoint(authenticationEntryPoint()) |
| | | .and() |
| | | .authorizeRequests() |
| | | .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() |
| | | .antMatchers("/login").permitAll() |
| | | .antMatchers("/swagger**/**").permitAll() |
| | | .antMatchers("/webjars/**").permitAll() |
| | | .antMatchers("/v2/**").permitAll() |
| | | .anyRequest().authenticated() |
| | | .and().apply(securityConfiguereAdapter()); |
| | | } |
| | | |
| | | @Override |
| | | protected void configure(AuthenticationManagerBuilder auth) throws Exception { |
| | | auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()); |
| | | } |
| | | |
| | | @Bean |
| | | public PasswordEncoder passwordEncoder() { |
| | | return new BCryptPasswordEncoder(); |
| | | } |
| | | |
| | | @Bean |
| | | public AccessDeniedHandler accessDeniedHandler() { |
| | | return new CustomAccessDeniedHandler(); |
| | | } |
| | | |
| | | @Bean |
| | | public AuthenticationEntryPoint authenticationEntryPoint() { |
| | | return new CustomAuthenticationEntryPoint(); |
| | | } |
| | | |
| | | public TokenConfigurer securityConfiguereAdapter() { |
| | | return new TokenConfigurer(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.member.entity; |
| | | |
| | | import com.xcong.excoin.common.system.base.BaseEntity; |
| | | import lombok.Data; |
| | | |
| | | import java.io.Serializable; |
| | | |
| | | /** |
| | | * 会员信息实体 |
| | | * |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Data |
| | | public class MemberEntity extends BaseEntity implements Serializable { |
| | | private static final long serialVersionUID = -1L; |
| | | |
| | | private Long id; |
| | | |
| | | private String username; |
| | | |
| | | private String password; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.controller; |
| | | |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.xcong.excoin.common.response.Result; |
| | | import com.xcong.excoin.modules.test.dto.TestUserDto; |
| | | import com.xcong.excoin.modules.test.entity.TestUserEntity; |
| | | import com.xcong.excoin.modules.test.mapper.TestUserEntityMapper; |
| | | import com.xcong.excoin.modules.test.service.TestUserService; |
| | | import com.xcong.excoin.modules.test.vo.TestUserVo; |
| | | import com.xcong.excoin.utils.MessageSourceUtils; |
| | | import io.swagger.annotations.Api; |
| | | import io.swagger.annotations.ApiOperation; |
| | | import io.swagger.annotations.ApiResponse; |
| | | import io.swagger.annotations.ApiResponses; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.security.core.context.SecurityContextHolder; |
| | | import org.springframework.web.bind.annotation.*; |
| | | |
| | | import javax.annotation.Resource; |
| | | import javax.validation.Valid; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-24 15:25 |
| | | **/ |
| | | @RestController |
| | | @RequestMapping(value = "/test") |
| | | @Slf4j |
| | | @Api(value = "这是测试用类", tags = "这是测试用类") |
| | | public class TestUserController { |
| | | |
| | | @Resource |
| | | private TestUserService testUserService; |
| | | |
| | | @ApiOperation(value = "测试用户分页请求", notes = "说明") |
| | | @ApiResponses({@ApiResponse(code = 0, message = "ok", response = TestUserVo.class)}) |
| | | @PostMapping(value = "/findUserInPage") |
| | | public Result findUserInPage(@RequestParam(value = "pageSize", defaultValue = "10") int pageSize, |
| | | @RequestParam(value = "pageNum", defaultValue = "1") int pageNum, |
| | | @RequestBody @Valid TestUserDto testUserDto) { |
| | | log.info("--->{}",SecurityContextHolder.getContext().getAuthentication()); |
| | | Page<TestUserEntity> page = new Page<>(pageNum, pageSize); |
| | | log.info(testUserDto.getName()); |
| | | IPage<TestUserEntity> list = testUserService.page(page); |
| | | return Result.ok(MessageSourceUtils.getString("111"), list); |
| | | } |
| | | |
| | | |
| | | @ApiOperation(value = "添加测试用户", notes = "该接口用于添加测试用户") |
| | | @PostMapping(value = "/add") |
| | | public Result add(@RequestBody @Valid TestUserDto testUserDto) { |
| | | TestUserEntity testUserEntity = TestUserEntityMapper.INSTANCE.dtoToEntity(testUserDto); |
| | | boolean flag = testUserService.save(testUserEntity); |
| | | if (flag) { |
| | | return Result.ok("success"); |
| | | } |
| | | return Result.fail("fail"); |
| | | } |
| | | |
| | | @ApiOperation(value = "根据ID删除用户", notes = "根据ID删除用户") |
| | | @GetMapping(value = "/del/{id}") |
| | | public Result del(@PathVariable(value = "id") Long id) { |
| | | boolean flag = testUserService.removeById(id); |
| | | if (flag) { |
| | | return Result.ok("success"); |
| | | } |
| | | return Result.fail("fail"); |
| | | } |
| | | |
| | | @ApiOperation(value = "根据Id查询用户信息", notes = "根据Id查询用户信息") |
| | | @GetMapping(value = "/findById/{id}") |
| | | public Result findById(@PathVariable(value = "id") Long id) { |
| | | TestUserEntity testUserEntity = testUserService.getById(id); |
| | | TestUserVo testUserVo = TestUserEntityMapper.INSTANCE.entityToVo(testUserEntity); |
| | | return Result.ok("success", testUserVo); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.dao; |
| | | |
| | | import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
| | | import com.baomidou.mybatisplus.core.metadata.IPage; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.xcong.excoin.modules.test.entity.TestUserEntity; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author helius |
| | | */ |
| | | public interface TestUserDao extends BaseMapper<TestUserEntity> { |
| | | |
| | | public List<TestUserEntity> selectAll(); |
| | | |
| | | IPage<TestUserEntity> selectInPage(Page<TestUserEntity> page); |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.dto; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | import org.hibernate.validator.constraints.Length; |
| | | |
| | | import javax.validation.constraints.NotBlank; |
| | | import javax.validation.constraints.NotNull; |
| | | import javax.validation.constraints.Pattern; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-08 10:17 |
| | | **/ |
| | | @Data |
| | | @ApiModel(value = "testUser参数接收类", description = "findUserInPage 参数接收类") |
| | | public class TestUserDto { |
| | | |
| | | // @NotNull(message = "id不能为空") |
| | | @ApiModelProperty(value = "这是名字啊", example = "张三") |
| | | private String name; |
| | | |
| | | // @Length(min = 6, max = 16, message = "账号长度需为6-16位") |
| | | @ApiModelProperty(value = "账号", example = "admin") |
| | | private String account; |
| | | |
| | | // @NotBlank(message = "密码不能为空") |
| | | @ApiModelProperty(value = "这是密码字段啊", example = "123456") |
| | | private String password; |
| | | |
| | | @ApiModelProperty(value = "这是地址ID", example = "123") |
| | | private Long addressId; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.entity; |
| | | |
| | | import com.baomidou.mybatisplus.annotation.TableName; |
| | | import com.xcong.excoin.common.system.base.BaseEntity; |
| | | import lombok.Data; |
| | | import lombok.EqualsAndHashCode; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-24 15:00 |
| | | **/ |
| | | @EqualsAndHashCode(callSuper = true) |
| | | @Data |
| | | @TableName("test_user") |
| | | public class TestUserEntity extends BaseEntity { |
| | | |
| | | private String name; |
| | | |
| | | private String account; |
| | | |
| | | private String password; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.mapper; |
| | | |
| | | import com.xcong.excoin.modules.test.dto.TestUserDto; |
| | | import com.xcong.excoin.modules.test.entity.TestUserEntity; |
| | | import com.xcong.excoin.modules.test.vo.TestUserVo; |
| | | import org.mapstruct.Mapper; |
| | | import org.mapstruct.factory.Mappers; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-09 15:26 |
| | | **/ |
| | | @Mapper |
| | | public abstract class TestUserEntityMapper { |
| | | public static final TestUserEntityMapper INSTANCE = Mappers.getMapper(TestUserEntityMapper.class); |
| | | |
| | | public abstract TestUserEntity dtoToEntity(TestUserDto testUserDto); |
| | | |
| | | public abstract TestUserVo entityToVo(TestUserEntity testUserEntity); |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.service; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.IService; |
| | | import com.xcong.excoin.modules.test.entity.TestUserEntity; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author helius |
| | | */ |
| | | public interface TestUserService extends IService<TestUserEntity> { |
| | | |
| | | public List<TestUserEntity> findAll(); |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.service.impl; |
| | | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.xcong.excoin.modules.test.dao.TestUserDao; |
| | | import com.xcong.excoin.modules.test.entity.TestUserEntity; |
| | | import com.xcong.excoin.modules.test.service.TestUserService; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-04-24 15:23 |
| | | **/ |
| | | @Service |
| | | @Slf4j |
| | | public class TestUserServiceImpl extends ServiceImpl<TestUserDao, TestUserEntity> implements TestUserService { |
| | | |
| | | @Resource |
| | | private TestUserDao testUserDao; |
| | | |
| | | @Override |
| | | public List<TestUserEntity> findAll() { |
| | | return testUserDao.selectAll(); |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-07 17:24 |
| | | **/ |
| | | @Data |
| | | @ApiModel(value = "测试", description = "测试用户类") |
| | | public class TestUserVo { |
| | | |
| | | @ApiModelProperty(value = "主键ID") |
| | | private Long id; |
| | | |
| | | @ApiModelProperty(value = "用户姓名") |
| | | private String userName; |
| | | |
| | | @ApiModelProperty(value = "密码") |
| | | private String password; |
| | | |
| | | @ApiModelProperty(value = "12345") |
| | | private List<TestVo> testVo; |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.modules.test.vo; |
| | | |
| | | import io.swagger.annotations.ApiModel; |
| | | import io.swagger.annotations.ApiModelProperty; |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-08 10:09 |
| | | **/ |
| | | @Data |
| | | @ApiModel(value = "12345", description = "2222222") |
| | | public class TestVo { |
| | | |
| | | @ApiModelProperty(value = "名字") |
| | | private String name; |
| | | |
| | | @ApiModelProperty(value = "密码") |
| | | private String pwd; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.utils; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.context.MessageSource; |
| | | import org.springframework.context.NoSuchMessageException; |
| | | import org.springframework.context.i18n.LocaleContextHolder; |
| | | import org.springframework.stereotype.Component; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-05 16:57 |
| | | **/ |
| | | @Component |
| | | @Slf4j |
| | | public class MessageSourceUtils { |
| | | |
| | | private static MessageSource messageSource; |
| | | |
| | | public MessageSourceUtils(MessageSource messageSource) { |
| | | MessageSourceUtils.messageSource = messageSource; |
| | | } |
| | | |
| | | public static String getString(String key) { |
| | | try { |
| | | return messageSource.getMessage(key, null, LocaleContextHolder.getLocale()); |
| | | } catch (NoSuchMessageException e) { |
| | | log.error("#获取国际化异常#", e); |
| | | return key; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.utils; |
| | | |
| | | import org.springframework.data.redis.core.RedisTemplate; |
| | | import org.springframework.stereotype.Component; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | import java.util.concurrent.TimeUnit; |
| | | |
| | | /** |
| | | * @Author wzy |
| | | * @Date 2020/5/10 |
| | | * @email wangdoubleone@gmail.com |
| | | * @Version V1.0 |
| | | **/ |
| | | @Component |
| | | public class RedisUtils { |
| | | |
| | | |
| | | @Resource |
| | | private RedisTemplate<String, Object> redisTemplate; |
| | | |
| | | |
| | | // =============================common============================ |
| | | /** |
| | | * 指定缓存失效时间 |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean expire(String key, long time) { |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.expire(key, time, TimeUnit.SECONDS); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 根据key 获取过期时间 |
| | | * @param key 键 不能为null |
| | | * @return 时间(秒) 返回0代表为永久有效 |
| | | */ |
| | | public long getExpire(String key) { |
| | | return redisTemplate.getExpire(key, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | /** |
| | | * 判断key是否存在 |
| | | * @param key 键 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hasKey(String key) { |
| | | try { |
| | | return redisTemplate.hasKey(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 删除缓存 |
| | | * @param key 可以传一个值 或多个 |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public void del(String... key) { |
| | | if (key != null && key.length > 0) { |
| | | if (key.length == 1) { |
| | | redisTemplate.delete(key[0]); |
| | | } else { |
| | | redisTemplate.delete(CollectionUtils.arrayToList(key)); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // ============================String============================= |
| | | /** |
| | | * 普通缓存获取 |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public Object get(String key) { |
| | | return key == null ? null : redisTemplate.opsForValue().get(key); |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 普通缓存获取 |
| | | * @param key 键 |
| | | * @return 值 |
| | | */ |
| | | public String getString(String key) { |
| | | Object obj = key == null ? null : redisTemplate.opsForValue().get(key); |
| | | if(obj!=null){ |
| | | return obj.toString(); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean set(String key, Object value) { |
| | | try { |
| | | redisTemplate.opsForValue().set(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 普通缓存放入并设置时间 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 |
| | | * @return true成功 false 失败 |
| | | */ |
| | | public boolean set(String key, Object value, long time) { |
| | | try { |
| | | if (time > 0) { |
| | | redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); |
| | | } else { |
| | | set(key, value); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | public boolean setNotExist(String key, Object value, long time) { |
| | | return redisTemplate.opsForValue().setIfAbsent(key, value, time, TimeUnit.SECONDS); |
| | | } |
| | | |
| | | /** |
| | | * 递增 |
| | | * @param key 键 |
| | | * @param delta 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public long incr(String key, long delta) { |
| | | if (delta < 0) { |
| | | throw new RuntimeException("递增因子必须大于0"); |
| | | } |
| | | return redisTemplate.opsForValue().increment(key, delta); |
| | | } |
| | | |
| | | /** |
| | | * 递减 |
| | | * @param key 键 |
| | | * @param delta 要减少几(小于0) |
| | | * @return |
| | | */ |
| | | public long decr(String key, long delta) { |
| | | if (delta < 0) { |
| | | throw new RuntimeException("递减因子必须大于0"); |
| | | } |
| | | return redisTemplate.opsForValue().increment(key, -delta); |
| | | } |
| | | |
| | | |
| | | // ================================Map================================= |
| | | |
| | | /** |
| | | * HashGet |
| | | * @param key 键 不能为null |
| | | * @param item 项 不能为null |
| | | * @return 值 |
| | | */ |
| | | public Object hget(String key, String item) { |
| | | return redisTemplate.opsForHash().get(key, item); |
| | | } |
| | | |
| | | /** |
| | | * 获取hashKey对应的所有键值 |
| | | * @param key 键 |
| | | * @return 对应的多个键值 |
| | | */ |
| | | public Map<Object, Object> hmget(String key) { |
| | | return redisTemplate.opsForHash().entries(key); |
| | | } |
| | | /** |
| | | * HashSet |
| | | |
| | | * @param key 键 |
| | | * @param map 对应多个键值 |
| | | * @return true 成功 false 失败 |
| | | */ |
| | | public boolean hmset(String key, Map<String, Object> map) { |
| | | try { |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * HashSet 并设置时间 |
| | | * @param key 键 |
| | | * @param map 应多个键值 |
| | | * @param time 时间(秒) |
| | | * @return true成功 false失败 |
| | | */ |
| | | public boolean hmset(String key, Map<String, Object> map, long time) { |
| | | try { |
| | | redisTemplate.opsForHash().putAll(key, map); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 向一张hash表中放入数据,如果不存在将创建 |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param value 值 |
| | | * @return true 成功 false失败 |
| | | */ |
| | | public boolean hset(String key, String item, Object value) { |
| | | try { |
| | | redisTemplate.opsForHash().put(key, item, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * 向一张hash表中放入数据,如果不存在将创建 |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param value 值 |
| | | * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 |
| | | * @return true 成功 false失败 |
| | | */ |
| | | public boolean hset(String key, String item, Object value, long time) { |
| | | try { |
| | | redisTemplate.opsForHash().put(key, item, value); |
| | | if (time > 0) { |
| | | expire(key, time); |
| | | } |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * 删除hash表中的值 |
| | | * @param key 键 不能为null |
| | | * @param item 项 可以使多个 不能为null |
| | | */ |
| | | public void hdel(String key, Object... item) { |
| | | redisTemplate.opsForHash().delete(key, item); |
| | | } |
| | | /** |
| | | * 判断hash表中是否有该项的值 |
| | | * @param key 键 不能为null |
| | | * @param item 项 不能为null |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean hHasKey(String key, String item) { |
| | | return redisTemplate.opsForHash().hasKey(key, item); |
| | | } |
| | | |
| | | /** |
| | | * hash递增 如果不存在,就会创建一个 并把新增后的值返回 |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param by 要增加几(大于0) |
| | | * @return |
| | | */ |
| | | public double hincr(String key, String item, double by) { |
| | | return redisTemplate.opsForHash().increment(key, item, by); |
| | | } |
| | | |
| | | /** |
| | | * hash递减 |
| | | * @param key 键 |
| | | * @param item 项 |
| | | * @param by 要减少记(小于0) |
| | | * @return |
| | | */ |
| | | public double hdecr(String key, String item, double by) { |
| | | return redisTemplate.opsForHash().increment(key, item, -by); |
| | | } |
| | | // ============================set============================= |
| | | /** |
| | | * 根据key获取Set中的所有值 |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | public Set<Object> sGet(String key) { |
| | | try { |
| | | return redisTemplate.opsForSet().members(key); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | /** |
| | | * 根据value从一个set中查询,是否存在 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return true 存在 false不存在 |
| | | */ |
| | | public boolean sHasKey(String key, Object value) { |
| | | try { |
| | | return redisTemplate.opsForSet().isMember(key, value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * 将数据放入set缓存 |
| | | * @param key 键 |
| | | * @param values 值 可以是多个 |
| | | * @return 成功个数 |
| | | */ |
| | | public long sSet(String key, Object... values) { |
| | | try { |
| | | return redisTemplate.opsForSet().add(key, values); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | |
| | | return 0; |
| | | } |
| | | } |
| | | /** |
| | | 336 |
| | | * 将set数据放入缓存 |
| | | 337 |
| | | * @param key 键 |
| | | * @param time 时间(秒) |
| | | * @param values 值 可以是多个 |
| | | * @return 成功个数 |
| | | */ |
| | | public long sSetAndTime(String key, long time, Object... values) { |
| | | try { |
| | | Long count = redisTemplate.opsForSet().add(key, values); |
| | | if (time > 0) |
| | | expire(key, time); |
| | | return count; |
| | | |
| | | }catch(Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | /** |
| | | * 获取set缓存的长度 |
| | | * @param key 键 |
| | | * @return |
| | | */ |
| | | |
| | | public long sGetSetSize(String key) { |
| | | try { |
| | | return redisTemplate.opsForSet().size(key); |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 移除值为value的 |
| | | * @param key 键 |
| | | * @param values 值 可以是多个 |
| | | * @return 移除的个数 |
| | | |
| | | */ |
| | | public long setRemove(String key, Object... values) { |
| | | try { |
| | | Long count = redisTemplate.opsForSet().remove(key, values); |
| | | return count; |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | // ===============================list================================= |
| | | /** |
| | | * 获取list缓存的内容 * @param key 键 |
| | | * @param start 开始 |
| | | * @param end 结束 0 到 -1代表所有值 |
| | | * @return |
| | | */ |
| | | public List<Object> lGet(String key, long start, long end) { |
| | | try { |
| | | return redisTemplate.opsForList().range(key, start, end); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | |
| | | } |
| | | |
| | | /** |
| | | * 获取list缓存的长度 |
| | | * @param key 键 |
| | | |
| | | * @return |
| | | */ |
| | | public long lGetListSize(String key) { try { |
| | | return redisTemplate.opsForList().size(key); |
| | | } catch (Exception e) { |
| | | |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } /** |
| | | * 通过索引 获取list中的值 |
| | | * @param key 键 |
| | | * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 |
| | | * @return |
| | | */ |
| | | public Object lGetIndex(String key, long index) { |
| | | |
| | | try { |
| | | return redisTemplate.opsForList().index(key, index); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, Object value) { |
| | | try { |
| | | redisTemplate.opsForList().rightPush(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 将list放入缓存 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, Object value, long time) { |
| | | try { |
| | | redisTemplate.opsForList().rightPush(key, value); |
| | | if (time > 0) |
| | | expire(key, time); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * 将list放入缓存 |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, List<Object> value) { |
| | | try { |
| | | redisTemplate.opsForList().rightPushAll(key, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * 将list放入缓存 |
| | | * |
| | | * @param key 键 |
| | | * @param value 值 |
| | | * @param time 时间(秒) |
| | | * @return |
| | | */ |
| | | public boolean lSet(String key, List<Object> value, long time) { |
| | | try { |
| | | redisTemplate.opsForList().rightPushAll(key, value); |
| | | if (time > 0) |
| | | expire(key, time); |
| | | return true; |
| | | |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | /** |
| | | * 根据索引修改list中的某条数据 |
| | | * @param key 键 |
| | | * @param index 索引 |
| | | * @param value 值 |
| | | * @return |
| | | */ |
| | | public boolean lUpdateIndex(String key, long index, Object value) { |
| | | try { |
| | | redisTemplate.opsForList().set(key, index, value); |
| | | return true; |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | |
| | | /** |
| | | * 移除N个值为value |
| | | * @param key 键 |
| | | * @param count 移除多少个 |
| | | * @param value 值 |
| | | * @return 移除的个数 |
| | | */ |
| | | public long lRemove(String key, long count, Object value) { |
| | | try { |
| | | return redisTemplate.opsForList().remove(key, count, value); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return 0; |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.utils; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.BeansException; |
| | | import org.springframework.beans.factory.DisposableBean; |
| | | import org.springframework.context.ApplicationContext; |
| | | import org.springframework.context.ApplicationContextAware; |
| | | |
| | | /** |
| | | * @Author wzy |
| | | * @Date 2020/5/11 |
| | | * @email wangdoubleone@gmail.com |
| | | * @Version V1.0 |
| | | **/ |
| | | @Slf4j |
| | | public class SpringContextHolder implements ApplicationContextAware, DisposableBean { |
| | | |
| | | private static ApplicationContext applicationContext = null; |
| | | |
| | | /** |
| | | * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. |
| | | */ |
| | | @SuppressWarnings("unchecked") |
| | | public static <T> T getBean(String name) { |
| | | assertContextInjected(); |
| | | return (T) applicationContext.getBean(name); |
| | | } |
| | | |
| | | /** |
| | | * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. |
| | | */ |
| | | public static <T> T getBean(Class<T> requiredType) { |
| | | assertContextInjected(); |
| | | return applicationContext.getBean(requiredType); |
| | | } |
| | | |
| | | private static void assertContextInjected() { |
| | | if (applicationContext == null) { |
| | | throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" + |
| | | ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder."); |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 检查ApplicationContext不为空. |
| | | */ |
| | | private static void clearHolder() { |
| | | log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext); |
| | | applicationContext = null; |
| | | } |
| | | |
| | | @Override |
| | | public void destroy() throws Exception { |
| | | SpringContextHolder.clearHolder(); |
| | | } |
| | | |
| | | @Override |
| | | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { |
| | | if (SpringContextHolder.applicationContext != null) { |
| | | log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); |
| | | } |
| | | SpringContextHolder.applicationContext = applicationContext; |
| | | } |
| | | } |
New file |
| | |
| | | server: |
| | | port: 8888 |
| | | servlet: |
| | | context-path: / |
| | | |
| | | spring: |
| | | datasource: |
| | | url: jdbc:mysql://120.27.238.55:3306/kss_framework?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2b8 |
| | | username: ct_test |
| | | password: 123456 |
| | | driver-class-name: com.mysql.jdbc.Driver |
| | | type: com.alibaba.druid.pool.DruidDataSource |
| | | druid: |
| | | initial-size: ${spring_datasource_druid_initial_size:10} |
| | | max-active: ${spring_datasource_druid_max_active:20} |
| | | min-idle: ${spring_datasource_druid_min_idle:3} |
| | | #配置获取连接等待超时的时间 |
| | | max-wait: 60000 |
| | | pool-prepared-statements: true |
| | | max-pool-prepared-statement-per-connection-size: 20 |
| | | validation-query: SELECT 'x' |
| | | test-on-borrow: true |
| | | test-on-return: true |
| | | test-while-idle: true |
| | | #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 |
| | | time-between-eviction-runs-millis: 60000 |
| | | #配置一个连接在池中最小生存的时间,单位是毫秒 |
| | | min-evictable-idle-time-millis: 300000 |
| | | #spring.datasource.druid.max-evguide.ftlictable-idle-time-millis= |
| | | filters: stat,wall |
| | | stat-view-servlet: |
| | | # 默认true 内置监控页面首页/druid/index.html |
| | | enabled: true |
| | | url-pattern: /druid/* |
| | | # 允许清空统计数据 |
| | | reset-enable: true |
| | | login-username: root |
| | | login-password: 123456 |
| | | # IP白名单 多个逗号分隔 |
| | | allow: ${spring_datasource_stat_view_servlet_allow:} |
| | | # IP黑名单 |
| | | deny: ${spring_datasource_stat_view_servlet_deny:} |
| | | ## 国际化配置 |
| | | messages: |
| | | basename: i18n/messages |
| | | ## redis配置 |
| | | redis: |
| | | ## Redis数据库索引(默认为0) |
| | | database: 1 |
| | | ## Redis服务器地址 |
| | | host: 121.40.158.8 |
| | | ## Redis服务器连接端口 |
| | | port: 6379 |
| | | ## Redis服务器连接密码(默认为空) |
| | | password: biyi123 |
| | | jedis: |
| | | pool: |
| | | ## 连接池最大连接数(使用负值表示没有限制) |
| | | #spring.redis.pool.max-active=8 |
| | | max-active: 300 |
| | | ## 连接池最大阻塞等待时间(使用负值表示没有限制) |
| | | #spring.redis.pool.max-wait=-1 |
| | | max-wait: -1 |
| | | ## 连接池中的最大空闲连接 |
| | | #spring.redis.pool.max-idle=8 |
| | | max-idle: 100 |
| | | ## 连接池中的最小空闲连接 |
| | | #spring.redis.pool.min-idle=0 |
| | | min-idle: 8 |
| | | ## 连接超时时间(毫秒) |
| | | timeout: 30000 |
| | | mybatis-plus: |
| | | mapper-locations: classpath:mapper/*.xml |
| | | |
| | | |
| | | app: |
| | | debug: true |
| | | |
| | | rsa: |
| | | private_key: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIJ/xQVkrngCIrg9G7u0135nypnvuj9BcKeTbkNGbKBWk4S7mYY1IC9+daYqnakRXZGWN5erdGJ3/4tCSidp5swl5cpIXTLEv9WDJ5PwlpDmA1s6t192Vz6YWRcnLPIm3xiS8CkR09E1JTYQ0GfuaBF8PQFg8zi9nr+u/517fwUnAgMBAAECgYBhPt9NvpI4wbanvnndLczr2GJkxfzvSE+vwLCJF4C5FusFHVsxZINggQcg1V75bwRgCiXRMyYefreCSdrCditS43PzTOmE4RRrpxLlm8oubJc0C98LQ2qlN9AsUqL5IHpVGgbHDyWAwjc1GBID6nwXKpxq1/VodFqhahG9D5EZsQJBALnkb+5VTxQbiyQI4Uc9NIvAyVcNY1OisbvY6tvNgdBbJkADgAb78M1HWxxYjUqsvzggNHc7cWqWBHMgpnJaqm8CQQCztze4D7uAk7OC9MJHY5eE980J8Kk+GEZKxz4LahzU6V6dcb9GFac3wEtgilj/tOAn9y0/Q8sm9vvCIbMDzgzJAkEAqRYcqhF26LdVDOX25DHMBgLKISDQZFbsjA13M4/usHL4i+mjHrc0BcUOHu59NpuDI65HitzLAUSLr5zXSdUmiQJAW77wOg4GCejdXsB3IhzMsHwU97sdm26nC+vVV9xvJZ6Rx8zW+f9543NOx9U5BCmhuaVtOvvwDU9PTVcI3atmSQJAXAIJ5gGdtXx0DXiX4VvzNFHqgaqHMGvXyjNVkU2FYQbSAd2A6app4uRO+BkZu9dSjh14m+oXMnV2HzAN2rRnjA== |
New file |
| | |
| | | test=test |
| | | 111=this is test msg |
New file |
| | |
| | | test=测试 |
| | | 111=这是测试消息 |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <configuration> |
| | | <contextName>logback</contextName> |
| | | <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 --> |
| | | <property name="log.path" value="logs" /> |
| | | |
| | | <!-- 彩色日志 --> |
| | | <!-- 彩色日志依赖的渲染类 --> |
| | | <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> |
| | | <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" /> |
| | | <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> |
| | | <!-- 彩色日志格式 --> |
| | | <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> |
| | | |
| | | <!--输出到控制台--> |
| | | <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
| | | <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息--> |
| | | <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| | | <level>info</level> |
| | | </filter> |
| | | <encoder> |
| | | <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> |
| | | <!-- 设置字符集 --> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | </appender> |
| | | |
| | | <!-- 时间滚动输出 level为 DEBUG 日志 --> |
| | | <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- 正在记录的日志文件的路径及文件名 --> |
| | | <file>${log.path}/log_debug.log</file> |
| | | <!--日志文件输出格式--> |
| | | <encoder> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{50} - %msg%n</pattern> |
| | | <charset>UTF-8</charset> <!-- 设置字符集 --> |
| | | </encoder> |
| | | <!-- 日志记录器的滚动策略,按日期,按大小记录 --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <!-- 日志归档 --> |
| | | <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| | | <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| | | <maxFileSize>100MB</maxFileSize> |
| | | </timeBasedFileNamingAndTriggeringPolicy> |
| | | <!--日志文件保留天数--> |
| | | <maxHistory>15</maxHistory> |
| | | </rollingPolicy> |
| | | <!-- 此日志文件只记录debug级别的 --> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <level>debug</level> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | <!-- 时间滚动输出 level为 INFO 日志 --> |
| | | <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- 正在记录的日志文件的路径及文件名 --> |
| | | <file>${log.path}/log_info.log</file> |
| | | <!--日志文件输出格式--> |
| | | <encoder> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{50} - %msg%n</pattern> |
| | | <charset>UTF-8</charset> |
| | | </encoder> |
| | | <!-- 日志记录器的滚动策略,按日期,按大小记录 --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <!-- 每天日志归档路径以及格式 --> |
| | | <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| | | <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| | | <maxFileSize>100MB</maxFileSize> |
| | | </timeBasedFileNamingAndTriggeringPolicy> |
| | | <!--日志文件保留天数--> |
| | | <maxHistory>15</maxHistory> |
| | | </rollingPolicy> |
| | | <!-- 此日志文件只记录info级别的 --> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <level>info</level> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | <!-- 时间滚动输出 level为 WARN 日志 --> |
| | | <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- 正在记录的日志文件的路径及文件名 --> |
| | | <file>${log.path}/log_warn.log</file> |
| | | <!--日志文件输出格式--> |
| | | <encoder> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{50} - %msg%n</pattern> |
| | | <charset>UTF-8</charset> <!-- 此处设置字符集 --> |
| | | </encoder> |
| | | <!-- 日志记录器的滚动策略,按日期,按大小记录 --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| | | <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| | | <maxFileSize>100MB</maxFileSize> |
| | | </timeBasedFileNamingAndTriggeringPolicy> |
| | | <!--日志文件保留天数--> |
| | | <maxHistory>15</maxHistory> |
| | | </rollingPolicy> |
| | | <!-- 此日志文件只记录warn级别的 --> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <level>warn</level> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | |
| | | <!-- 时间滚动输出 level为 ERROR 日志 --> |
| | | <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| | | <!-- 正在记录的日志文件的路径及文件名 --> |
| | | <file>${log.path}/log_error.log</file> |
| | | <!--日志文件输出格式--> |
| | | <encoder> |
| | | <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level] [%thread] %logger{50} - %msg%n</pattern> |
| | | <charset>UTF-8</charset> <!-- 此处设置字符集 --> |
| | | </encoder> |
| | | <!-- 日志记录器的滚动策略,按日期,按大小记录 --> |
| | | <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| | | <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| | | <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| | | <maxFileSize>100MB</maxFileSize> |
| | | </timeBasedFileNamingAndTriggeringPolicy> |
| | | <!--日志文件保留天数--> |
| | | <maxHistory>15</maxHistory> |
| | | </rollingPolicy> |
| | | <!-- 此日志文件只记录ERROR级别的 --> |
| | | <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| | | <level>ERROR</level> |
| | | <onMatch>ACCEPT</onMatch> |
| | | <onMismatch>DENY</onMismatch> |
| | | </filter> |
| | | </appender> |
| | | |
| | | <!--开发环境:打印控制台--> |
| | | <springProfile name="dev"> |
| | | <logger name="com.xcong.excoin" level="debug"/> |
| | | </springProfile> |
| | | |
| | | <root level="info"> |
| | | <appender-ref ref="CONSOLE" /> |
| | | <appender-ref ref="DEBUG_FILE" /> |
| | | <appender-ref ref="INFO_FILE" /> |
| | | <appender-ref ref="WARN_FILE" /> |
| | | <appender-ref ref="ERROR_FILE" /> |
| | | </root> |
| | | </configuration> |
New file |
| | |
| | | <?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.xcong.excoin.modules.test.dao.TestUserDao"> |
| | | |
| | | <select id="selectAll" resultType="com.xcong.excoin.modules.test.entity.TestUserEntity"> |
| | | select * from test_user |
| | | </select> |
| | | |
| | | <select id="selectInPage" resultType="com.xcong.excoin.modules.test.entity.TestUserEntity"> |
| | | select * from test_user |
| | | </select> |
| | | </mapper> |
New file |
| | |
| | | package com.xcong.excoin; |
| | | |
| | | import com.xcong.excoin.modules.test.dao.TestUserDao; |
| | | import com.xcong.excoin.modules.test.entity.TestUserEntity; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | |
| | | import javax.annotation.Resource; |
| | | import java.util.Date; |
| | | |
| | | @SpringBootTest |
| | | class KssframeworkApplicationTests { |
| | | |
| | | @Resource |
| | | private TestUserDao testUserDao; |
| | | |
| | | @Test |
| | | public void testUserInsert() { |
| | | for(int i = 0; i < 20; i++) { |
| | | TestUserEntity testUser = new TestUserEntity(); |
| | | testUser.setCreateBy("123"); |
| | | testUser.setCreateTime(new Date()); |
| | | testUser.setUpdateBy("123"); |
| | | testUser.setUpdateTime(new Date()); |
| | | testUser.setAccount("12345" + i); |
| | | testUser.setName("hehe" + i); |
| | | testUser.setPassword("33333"); |
| | | testUserDao.insert(testUser); |
| | | } |
| | | |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin; |
| | | |
| | | import cn.hutool.core.codec.Base64; |
| | | import cn.hutool.core.util.CharsetUtil; |
| | | import cn.hutool.core.util.HexUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | import cn.hutool.crypto.SecureUtil; |
| | | import cn.hutool.crypto.asymmetric.KeyType; |
| | | import cn.hutool.crypto.asymmetric.RSA; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | |
| | | import java.security.KeyPair; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-12 |
| | | **/ |
| | | @Slf4j |
| | | @SpringBootTest |
| | | public class RSATest { |
| | | |
| | | private String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCFU26floADA4PSEmE99u1YD30P3LAP6c7XYRASejCte+uOUfveSGHip2cgwpElu4y/r8PKAbclvs8j3y0g4MhjQbRjsiK8O2PKPaTWW+bHWPapPAhTuRHDMVFV6sajZ4dcg7mZ9+zPqG2RkvXi993v7kcTYq8hpE20/+Do7gwFowIDAQAB"; |
| | | |
| | | private String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIVTbp+WgAMDg9ISYT327VgPfQ/csA/pztdhEBJ6MK17645R+95IYeKnZyDCkSW7jL+vw8oBtyW+zyPfLSDgyGNBtGOyIrw7Y8o9pNZb5sdY9qk8CFO5EcMxUVXqxqNnh1yDuZn37M+obZGS9eL33e/uRxNiryGkTbT/4OjuDAWjAgMBAAECgYAUw8TD6C2xyndaXXB1tSKMB4WD1ew53kFPvBdDuXIhYt5yAQTIPt+37DicmpD+nnIyXI6SxKegolIilRyzNS8gQqXyqnj+UrIX8hJp0bxwEx2epcKAcwn84XFEXFGMFe2POUpFgNkxbKcWH9UNAALsO20ipP3UB6dj832HjGSagQJBAPKeVrXTnEf0Ien2A4jXAX4WZp0x7pg9ccGRo8RKFUrY0xVGstKEpCTTdDZ596/L8EN83dP2reHl2sCJpzC5NsECQQCMre6tadDg/cZE7SbxGhxlIRM1SyqGnxk+owiQbiYKLlhNR5GEZUdh+xubjtWPWhmXiy3nmFki9NESIhWf0xljAkAD/LAmGs0lrZBlHOLf+9CNdubGzIxEOjZFXRRY5HLHIRsO7XOA3CcqZ8MwJf75B5vyL/ohQpuG69UVdu2lclXBAkBq0/4Gc+9pm2y/lLNYrXJYnWg/tSfC+Pgrp5RuUSbT3mOxs6JePqaZUh2h4DJuXIZInSkr0HYH5I8LTRTMvHpvAkEAl81YqDl/deSXAq4Xy38/UrMTSEwGmHtVTxlwJ9Of+iX+pSDu/TIi3ZJtjxL+P1IcJD5r89SgJnl6secBz9rPBQ=="; |
| | | |
| | | |
| | | @Test |
| | | public void rsaTest() { |
| | | KeyPair keyPair = SecureUtil.generateKeyPair("RSA"); |
| | | log.info("{}", Base64.encode(keyPair.getPublic().getEncoded())); |
| | | log.info("{}", Base64.encode(keyPair.getPrivate().getEncoded())); |
| | | } |
| | | |
| | | |
| | | @Test |
| | | public void aaTest() { |
| | | RSA rsa = new RSA(); |
| | | String encrypt = new String(rsa.encrypt(StrUtil.bytes("1234567", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey)); |
| | | log.info("#---->{}#", encrypt); |
| | | |
| | | String decrypt = new String(rsa.decrypt(encrypt, KeyType.PrivateKey)); |
| | | log.info("#------>{}#", decrypt); |
| | | } |
| | | |
| | | @Test |
| | | public void enAndDenTest() { |
| | | RSA rsa = new RSA(); |
| | | |
| | | rsa.getPrivateKey(); |
| | | log.info(rsa.getPrivateKeyBase64()); |
| | | rsa.getPublicKey(); |
| | | log.info(rsa.getPublicKeyBase64()); |
| | | |
| | | byte[] encrypt = rsa.encrypt(StrUtil.bytes("我是一段测试aaaa", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey); |
| | | byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey); |
| | | |
| | | log.info("---->{}", new String(encrypt)); |
| | | log.info("------>{}", new String(decrypt)); |
| | | } |
| | | |
| | | @Test |
| | | public void decTest() { |
| | | String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCCf8UFZK54AiK4PRu7tNd+Z8qZ77o/QXCnk25DRmygVpOEu5mGNSAvfnWmKp2pEV2RljeXq3Rid/+LQkonaebMJeXKSF0yxL/VgyeT8JaQ5gNbOrdfdlc+mFkXJyzyJt8YkvApEdPRNSU2ENBn7mgRfD0BYPM4vZ6/rv+de38FJwIDAQAB"; |
| | | String str = "OsaRaZOuBYGiI1j62SQvJOj4CieiAFIdWRTQln2ZSAx1KHBhyCpJuLjb84ZuwsPd98crQOlE4VhgoQB/9SD5b1ATRGmpr6FR5FqXl76JDOirdYvrplJw3hO0cZM3ADL2TQTbtGanUskOWYPG+GXRdqV21und3aZXh+itTWcSFYw="; |
| | | String privateKeys = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIJ/xQVkrngCIrg9G7u0135nypnvuj9BcKeTbkNGbKBWk4S7mYY1IC9+daYqnakRXZGWN5erdGJ3/4tCSidp5swl5cpIXTLEv9WDJ5PwlpDmA1s6t192Vz6YWRcnLPIm3xiS8CkR09E1JTYQ0GfuaBF8PQFg8zi9nr+u/517fwUnAgMBAAECgYBhPt9NvpI4wbanvnndLczr2GJkxfzvSE+vwLCJF4C5FusFHVsxZINggQcg1V75bwRgCiXRMyYefreCSdrCditS43PzTOmE4RRrpxLlm8oubJc0C98LQ2qlN9AsUqL5IHpVGgbHDyWAwjc1GBID6nwXKpxq1/VodFqhahG9D5EZsQJBALnkb+5VTxQbiyQI4Uc9NIvAyVcNY1OisbvY6tvNgdBbJkADgAb78M1HWxxYjUqsvzggNHc7cWqWBHMgpnJaqm8CQQCztze4D7uAk7OC9MJHY5eE980J8Kk+GEZKxz4LahzU6V6dcb9GFac3wEtgilj/tOAn9y0/Q8sm9vvCIbMDzgzJAkEAqRYcqhF26LdVDOX25DHMBgLKISDQZFbsjA13M4/usHL4i+mjHrc0BcUOHu59NpuDI65HitzLAUSLr5zXSdUmiQJAW77wOg4GCejdXsB3IhzMsHwU97sdm26nC+vVV9xvJZ6Rx8zW+f9543NOx9U5BCmhuaVtOvvwDU9PTVcI3atmSQJAXAIJ5gGdtXx0DXiX4VvzNFHqgaqHMGvXyjNVkU2FYQbSAd2A6app4uRO+BkZu9dSjh14m+oXMnV2HzAN2rRnjA=="; |
| | | |
| | | RSA rsa = new RSA(privateKeys, null); |
| | | String aaa = new String(rsa.decrypt(str, KeyType.PrivateKey)); |
| | | log.info("---->{}", aaa); |
| | | } |
| | | |
| | | @Test |
| | | public void demoTest() { |
| | | String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIL7pbQ+5KKGYRhw7jE31hmA" |
| | | + "f8Q60ybd+xZuRmuO5kOFBRqXGxKTQ9TfQI+aMW+0lw/kibKzaD/EKV91107xE384qOy6IcuBfaR5lv39OcoqNZ" |
| | | + "5l+Dah5ABGnVkBP9fKOFhPgghBknTRo0/rZFGI6Q1UHXb+4atP++LNFlDymJcPAgMBAAECgYBammGb1alndta" |
| | | + "xBmTtLLdveoBmp14p04D8mhkiC33iFKBcLUvvxGg2Vpuc+cbagyu/NZG+R/WDrlgEDUp6861M5BeFN0L9O4hz" |
| | | + "GAEn8xyTE96f8sh4VlRmBOvVdwZqRO+ilkOM96+KL88A9RKdp8V2tna7TM6oI3LHDyf/JBoXaQJBAMcVN7fKlYP" |
| | | + "Skzfh/yZzW2fmC0ZNg/qaW8Oa/wfDxlWjgnS0p/EKWZ8BxjR/d199L3i/KMaGdfpaWbYZLvYENqUCQQCobjsuCW" |
| | | + "nlZhcWajjzpsSuy8/bICVEpUax1fUZ58Mq69CQXfaZemD9Ar4omzuEAAs2/uee3kt3AvCBaeq05NyjAkBme8SwB0iK" |
| | | + "kLcaeGuJlq7CQIkjSrobIqUEf+CzVZPe+AorG+isS+Cw2w/2bHu+G0p5xSYvdH59P0+ZT0N+f9LFAkA6v3Ae56OrI" |
| | | + "wfMhrJksfeKbIaMjNLS9b8JynIaXg9iCiyOHmgkMl5gAbPoH/ULXqSKwzBw5mJ2GW1gBlyaSfV3AkA/RJC+adIjsRGg" |
| | | + "JOkiRjSmPpGv3FOhl9fsBPjupZBEIuoMWOC8GXK/73DHxwmfNmN7C9+sIi4RBcjEeQ5F5FHZ"; |
| | | |
| | | RSA rsa = new RSA(PRIVATE_KEY, null); |
| | | |
| | | String a = "2707F9FD4288CEF302C972058712F24A5F3EC62C5A14AD2FC59DAB93503AA0FA17113A020EE4EA35EB53F" |
| | | + "75F36564BA1DABAA20F3B90FD39315C30E68FE8A1803B36C29029B23EB612C06ACF3A34BE815074F5EB5AA3A" |
| | | + "C0C8832EC42DA725B4E1C38EF4EA1B85904F8B10B2D62EA782B813229F9090E6F7394E42E6F44494BB8"; |
| | | |
| | | byte[] aByte = HexUtil.decodeHex(a); |
| | | byte[] decrypt = rsa.decrypt(aByte, KeyType.PrivateKey); |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.mapper; |
| | | |
| | | import lombok.Data; |
| | | |
| | | import java.util.Date; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-05 11:00 |
| | | **/ |
| | | @Data |
| | | public class Car { |
| | | private String name; |
| | | |
| | | private String color; |
| | | |
| | | private Date createTime; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.mapper; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-05 11:00 |
| | | **/ |
| | | @Data |
| | | public class CarDto { |
| | | private String name; |
| | | |
| | | private String color; |
| | | |
| | | private String createTime; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.mapper; |
| | | |
| | | import lombok.Data; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-05 15:04 |
| | | **/ |
| | | @Data |
| | | public class CarEntity { |
| | | private String userName; |
| | | |
| | | private String userColor; |
| | | |
| | | private String time; |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.mapper; |
| | | |
| | | import org.mapstruct.*; |
| | | import org.mapstruct.factory.Mappers; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-05 11:00 |
| | | **/ |
| | | @Mapper |
| | | public abstract class CarMapper { |
| | | public static final CarMapper INSTANCE = Mappers.getMapper(CarMapper.class); |
| | | |
| | | @Mapping(source = "createTime", target = "createTime", dateFormat = "yyyy-MM-dd HH:mm:ss") |
| | | public abstract CarDto carToCarDto(Car car); |
| | | |
| | | @InheritInverseConfiguration |
| | | @Mapping(target = "name", ignore = true) |
| | | public abstract Car carDtoToCar(CarDto carDto); |
| | | |
| | | @Named("useMe1") |
| | | @Mapping(source = "name", target = "userName") |
| | | @Mapping(source = "color", target = "userColor") |
| | | @Mapping(source = "createTime", target = "time", dateFormat = "yyyy-MM-dd HH:mm:ss") |
| | | public abstract CarEntity carToCarEntity(Car car); |
| | | |
| | | @Mapping(source = "name", target = "userName") |
| | | @Mapping(source = "color", target = "userColor") |
| | | public abstract CarEntity carToCarEntityList(Car car); |
| | | |
| | | @InheritInverseConfiguration(name = "carToCarEntity") |
| | | public abstract Car carEntityToCar(CarEntity carEntity); |
| | | |
| | | |
| | | @Named("useMe") |
| | | @InheritInverseConfiguration(name = "carToCarEntityList") |
| | | public abstract Car carEntityToCar1(CarEntity carEntity); |
| | | |
| | | @IterableMapping(qualifiedByName = "useMe1") |
| | | public abstract List<CarEntity> carEntitiesToCarList(List<Car> list); |
| | | |
| | | @IterableMapping(qualifiedByName = "useMe") |
| | | public abstract List<Car> carsToCarEntities(List<CarEntity> list); |
| | | } |
New file |
| | |
| | | package com.xcong.excoin.mapper; |
| | | |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.junit.jupiter.api.Test; |
| | | import org.springframework.boot.test.context.SpringBootTest; |
| | | |
| | | import java.util.ArrayList; |
| | | import java.util.Date; |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * @author wzy |
| | | * @date 2020-05-05 10:59 |
| | | **/ |
| | | @Slf4j |
| | | @SpringBootTest |
| | | public class MapStructMapper { |
| | | |
| | | |
| | | @Test |
| | | public void mapperConvert() { |
| | | Car car = new Car(); |
| | | car.setColor("123"); |
| | | car.setName("321"); |
| | | car.setCreateTime(new Date()); |
| | | CarDto carDto = CarMapper.INSTANCE.carToCarDto(car); |
| | | log.info(carDto.toString()); |
| | | } |
| | | |
| | | @Test |
| | | public void carDtoToCarConvert() { |
| | | CarDto carDto = new CarDto(); |
| | | carDto.setName("dddd"); |
| | | carDto.setColor("aaaa"); |
| | | carDto.setCreateTime("2020-12-12 12:22:22"); |
| | | Car car = CarMapper.INSTANCE.carDtoToCar(carDto); |
| | | log.info(car.toString()); |
| | | } |
| | | |
| | | @Test |
| | | public void carToCarEntity() { |
| | | Car car = new Car(); |
| | | car.setName("123"); |
| | | car.setColor("33333"); |
| | | car.setCreateTime(new Date()); |
| | | CarEntity carEntity = CarMapper.INSTANCE.carToCarEntity(car); |
| | | log.info(carEntity.toString()); |
| | | } |
| | | |
| | | @Test |
| | | public void carEntityToCar() { |
| | | CarEntity carEntity = new CarEntity(); |
| | | carEntity.setUserName("11111"); |
| | | carEntity.setUserColor("33333"); |
| | | carEntity.setTime("2020-12-12 12:22:22"); |
| | | Car car = CarMapper.INSTANCE.carEntityToCar(carEntity); |
| | | log.info(car.toString()); |
| | | } |
| | | |
| | | @Test |
| | | public void carEntityListToCarList() { |
| | | List<CarEntity> list = new ArrayList<>(); |
| | | for (int i = 0; i < 4; i++) { |
| | | CarEntity carEntity = new CarEntity(); |
| | | carEntity.setTime("2020-12-12 12:22:33"); |
| | | carEntity.setUserName("zs" + i); |
| | | carEntity.setUserColor("red" + i); |
| | | list.add(carEntity); |
| | | } |
| | | List<Car> cars = CarMapper.INSTANCE.carsToCarEntities(list); |
| | | log.info(cars.toString()); |
| | | } |
| | | |
| | | @Test |
| | | public void carToCarEntityList() { |
| | | List<Car> list = new ArrayList<>(); |
| | | for (int i = 0; i < 4; i++) { |
| | | Car car = new Car(); |
| | | car.setName("zs"+i); |
| | | car.setColor("black" + i); |
| | | car.setCreateTime(new Date()); |
| | | list.add(car); |
| | | } |
| | | |
| | | List<CarEntity> entities = CarMapper.INSTANCE.carEntitiesToCarList(list); |
| | | log.info(entities.toString()); |
| | | } |
| | | |
| | | } |