天择外汇模拟交易系统后端框架搭建
commit
7c16d404cc
@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
@ -0,0 +1,18 @@
|
|||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip
|
||||||
|
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
@ -0,0 +1,98 @@
|
|||||||
|
<?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.7.12</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.sztzjy</groupId>
|
||||||
|
<artifactId>foreign_exchange_trading</artifactId>
|
||||||
|
<version>2.0-SNAPSHOT</version>
|
||||||
|
<name>foreign_exchange_trading</name>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.10</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-jwt</artifactId>
|
||||||
|
<version>1.1.1.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.nimbusds</groupId>
|
||||||
|
<artifactId>nimbus-jose-jwt</artifactId>
|
||||||
|
<version>9.26</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>druid-spring-boot-starter</artifactId>
|
||||||
|
<version>1.2.18</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||||
|
<version>3.0.3</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security.oauth</groupId>
|
||||||
|
<artifactId>spring-security-oauth2</artifactId>
|
||||||
|
<version>2.3.8.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.hibernate</groupId>
|
||||||
|
<artifactId>hibernate-spatial</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<!-- MySQL连接驱动 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.28</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class ForeignExchangeTradingApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(ForeignExchangeTradingApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 常量定义
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class Constant {
|
||||||
|
/**
|
||||||
|
* 请求头
|
||||||
|
*/
|
||||||
|
public static final String AUTHORIZATION = "Authorization";
|
||||||
|
/**
|
||||||
|
* Basic 请求头
|
||||||
|
*/
|
||||||
|
public static final String BASIC = "Basic";
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.springframework.context.ApplicationEvent;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@Lazy(false)
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查ApplicationContext不为空.
|
||||||
|
*/
|
||||||
|
private static void assertContextInjected() {
|
||||||
|
if (applicationContext == null) {
|
||||||
|
throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
|
||||||
|
".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除SpringContextHolder中的ApplicationContext为Null.
|
||||||
|
*/
|
||||||
|
private static void clearHolder() {
|
||||||
|
log.debug("清除SpringContextHolder中的ApplicationContext:"
|
||||||
|
+ applicationContext);
|
||||||
|
applicationContext = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void destroy(){
|
||||||
|
SpringContextHolder.clearHolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
if (SpringContextHolder.applicationContext != null) {
|
||||||
|
log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext);
|
||||||
|
}
|
||||||
|
SpringContextHolder.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布事件
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
*/
|
||||||
|
public static void publishEvent(ApplicationEvent event) {
|
||||||
|
if (applicationContext == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
applicationContext.publishEvent(event);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 当用户访问受保护资源但不提供任何凭据时将抛出此异常
|
||||||
|
*
|
||||||
|
* @author 陈沅
|
||||||
|
* @version 1.0.0
|
||||||
|
*/
|
||||||
|
public class UnAuthorizedException extends RuntimeException {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new runtime exception with the specified detail message.
|
||||||
|
* The cause is not initialized, and may subsequently be initialized by a
|
||||||
|
* call to {@link #initCause}.
|
||||||
|
*
|
||||||
|
* @param message the detail message. The detail message is saved for
|
||||||
|
* later retrieval by the {@link #getMessage()} method.
|
||||||
|
*/
|
||||||
|
public UnAuthorizedException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new runtime exception with the specified detail message and
|
||||||
|
* cause. <p>Note that the detail message associated with
|
||||||
|
* {@code cause} is <i>not</i> automatically incorporated in
|
||||||
|
* this runtime exception's detail message.
|
||||||
|
*
|
||||||
|
* @param message the detail message (which is saved for later retrieval
|
||||||
|
* by the {@link #getMessage()} method).
|
||||||
|
* @param cause the cause (which is saved for later retrieval by the
|
||||||
|
* {@link #getCause()} method). (A {@code null} value is
|
||||||
|
* permitted, and indicates that the cause is nonexistent or
|
||||||
|
* unknown.)
|
||||||
|
* @since 1.4
|
||||||
|
*/
|
||||||
|
public UnAuthorizedException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.exception.handler;
|
||||||
|
|
||||||
|
import com.sztzjy.forex.trading_trading.config.exception.UnAuthorizedException;
|
||||||
|
import com.sztzjy.forex.trading_trading.util.ResultEntity;
|
||||||
|
import com.sztzjy.forex.trading_trading.util.ThrowableUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.authentication.BadCredentialsException;
|
||||||
|
import org.springframework.validation.FieldError;
|
||||||
|
import org.springframework.validation.ObjectError;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局异常处理
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@RestControllerAdvice
|
||||||
|
public class GlobalExceptionHandler {
|
||||||
|
|
||||||
|
@ExceptionHandler(IllegalArgumentException.class)
|
||||||
|
public ResultEntity<String> illegalArgumentException(IllegalArgumentException e) {
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(AccessDeniedException.class)
|
||||||
|
public ResultEntity<String> accessDeniedException(AccessDeniedException e) {
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return new ResultEntity<>(HttpStatus.FORBIDDEN, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(UnAuthorizedException.class)
|
||||||
|
public ResultEntity<String> UnAuthorizedException(UnAuthorizedException e) {
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return new ResultEntity<>(HttpStatus.UNAUTHORIZED, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理所有接口数据验证异常
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||||
|
public ResultEntity<String> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
|
||||||
|
String message = objectError.getDefaultMessage();
|
||||||
|
if (objectError instanceof FieldError) {
|
||||||
|
message = ((FieldError) objectError).getField() + ": " + message;
|
||||||
|
}
|
||||||
|
return new ResultEntity<>(HttpStatus.BAD_REQUEST, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理所有不可知的异常
|
||||||
|
*
|
||||||
|
* @param e 未知异常
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(Throwable.class)
|
||||||
|
public ResultEntity<String> nullPointerException(Throwable e) {
|
||||||
|
log.error(ThrowableUtil.getStackTrace(e));
|
||||||
|
return new ResultEntity<>(HttpStatus.BAD_REQUEST, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BadCredentialsException
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(BadCredentialsException.class)
|
||||||
|
public ResultEntity<String> badCredentialsException(BadCredentialsException e) {
|
||||||
|
// 打印堆栈信息
|
||||||
|
String message = "坏的凭证".equals(e.getMessage()) ? "用户名或密码不正确" : e.getMessage();
|
||||||
|
log.error(message);
|
||||||
|
return new ResultEntity<>(HttpStatus.BAD_REQUEST, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,91 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.security;
|
||||||
|
|
||||||
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
|
import com.sztzjy.forex.trading_trading.config.Constant;
|
||||||
|
import com.sztzjy.forex.trading_trading.config.exception.UnAuthorizedException;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统登陆认证拦截
|
||||||
|
*
|
||||||
|
* @author 陈沅
|
||||||
|
*/
|
||||||
|
public class AuthenticationFilter extends OncePerRequestFilter {
|
||||||
|
private final PathMatcher matcher = new AntPathMatcher();
|
||||||
|
private final TokenProvider tokenProvider;
|
||||||
|
public AuthenticationFilter(TokenProvider tokenProvider) {
|
||||||
|
this.tokenProvider = tokenProvider;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
|
||||||
|
String requestRri = request.getRequestURI();
|
||||||
|
if (requestRri.equals("/")) {
|
||||||
|
response.sendRedirect("/doc.html");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isExclude(request)) {
|
||||||
|
System.out.println("--------------------------------->>> " + LocalDateTime.now() + " ---ip:" + ServletUtil.getClientIP(request) + " requestUri:" + requestRri);
|
||||||
|
}
|
||||||
|
String token = request.getHeader(Constant.AUTHORIZATION);
|
||||||
|
|
||||||
|
if (token == null || token.equals("undefined") || token.equals("") || token.equals("null")) {
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.startsWithIgnoreCase(token, "Bearer ")) {
|
||||||
|
throw new UnAuthorizedException("令牌错误: 缺失Bearer..");
|
||||||
|
}
|
||||||
|
JwtUser currentUser = tokenProvider.getClaims(token);
|
||||||
|
Authentication authentication = new UsernamePasswordAuthenticationToken(currentUser, "****", currentUser.getAuthorities());
|
||||||
|
request.getUserPrincipal();
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
filterChain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 排除的请求路径匹配
|
||||||
|
*/
|
||||||
|
private final static List<String> patterns = Arrays.asList(
|
||||||
|
"/swagger-resources/**",
|
||||||
|
"/doc.html",
|
||||||
|
"/webjars/**",
|
||||||
|
"/v2/**",
|
||||||
|
"/favicon.ico",
|
||||||
|
"/login",
|
||||||
|
"/druid/**"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断请求路径是否是在排除之外
|
||||||
|
*
|
||||||
|
* @param request /
|
||||||
|
* @return true-是排除的
|
||||||
|
*/
|
||||||
|
private boolean isExclude(HttpServletRequest request) {
|
||||||
|
String requestURI = request.getRequestURI();
|
||||||
|
for (String pattern : patterns) {
|
||||||
|
if (matcher.match(pattern, requestURI)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.security;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* jwt用户对象
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class JwtUser implements UserDetails {
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String name;
|
||||||
|
private String userId;
|
||||||
|
private int roleId;
|
||||||
|
private int schoolId;
|
||||||
|
private int classId;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonExpired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isAccountNonLocked() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCredentialsNonExpired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.security;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TokenProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析jwtToken
|
||||||
|
*
|
||||||
|
* @param jwtToken jwtToken
|
||||||
|
* @return jwt解析对象
|
||||||
|
*/
|
||||||
|
|
||||||
|
public JwtUser getClaims(String jwtToken) {
|
||||||
|
//todo 解析用户token
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.security;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统配置
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class WebConfigurerAdapter implements WebMvcConfigurer {
|
||||||
|
@Resource
|
||||||
|
private StringHttpMessageConverter stringHttpMessageConverter;
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsFilter corsFilter() {
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
config.addAllowedOriginPattern("*");
|
||||||
|
config.addAllowedMethod("*");
|
||||||
|
config.addAllowedHeader("*");
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
return new CorsFilter(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public ReloadableResourceBundleMessageSource messageSource() {
|
||||||
|
ReloadableResourceBundleMessageSource reloadableResourceBundleMessageSource = new ReloadableResourceBundleMessageSource();
|
||||||
|
reloadableResourceBundleMessageSource.setBasename("classpath:messages");
|
||||||
|
return reloadableResourceBundleMessageSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
|
for (int i = 0; i < converters.size(); i++) {
|
||||||
|
if (converters.get(i) instanceof StringHttpMessageConverter) {
|
||||||
|
stringHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||||
|
converters.set(i, stringHttpMessageConverter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.config.swagger;
|
||||||
|
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import io.swagger.models.auth.In;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.boot.web.context.WebServerInitializedEvent;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Profile;
|
||||||
|
import springfox.documentation.builders.ApiInfoBuilder;
|
||||||
|
import springfox.documentation.builders.PathSelectors;
|
||||||
|
import springfox.documentation.builders.RequestHandlerSelectors;
|
||||||
|
import springfox.documentation.service.*;
|
||||||
|
import springfox.documentation.spi.DocumentationType;
|
||||||
|
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||||
|
import springfox.documentation.spring.web.plugins.Docket;
|
||||||
|
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.net.Inet4Address;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* swagger 3.0接口文档配置类
|
||||||
|
*
|
||||||
|
* @author 陈沅
|
||||||
|
*/
|
||||||
|
@EnableSwagger2
|
||||||
|
@Configuration
|
||||||
|
@Profile({"dev", "pro", "test"})
|
||||||
|
public class Swagger2Config implements ApplicationListener<WebServerInitializedEvent> {
|
||||||
|
@Resource
|
||||||
|
private SwaggerProperties swaggerProperties;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Docket docket() {
|
||||||
|
return new Docket(DocumentationType.SWAGGER_2)
|
||||||
|
.enable(swaggerProperties.getEnable())
|
||||||
|
.apiInfo(apiInfo())
|
||||||
|
.select()
|
||||||
|
.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
|
||||||
|
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
|
||||||
|
.paths(PathSelectors.any())
|
||||||
|
// .globalRequestParameters(requestParameters())
|
||||||
|
.build()
|
||||||
|
.securitySchemes(securitySchemes())
|
||||||
|
.securityContexts(securityContexts());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiInfo apiInfo() {
|
||||||
|
return new ApiInfoBuilder().title(swaggerProperties.getTitle())
|
||||||
|
.description(swaggerProperties.getDescription())
|
||||||
|
.contact(new Contact(swaggerProperties.getContactName(), swaggerProperties.getContactAddress(), swaggerProperties.getContactEmail()))
|
||||||
|
.version(swaggerProperties.getVersion())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置全局安全策略
|
||||||
|
*
|
||||||
|
* @return /
|
||||||
|
*/
|
||||||
|
private List<SecurityScheme> securitySchemes() {
|
||||||
|
List<SecurityScheme> schemes = new ArrayList<>();
|
||||||
|
SecurityScheme scheme = new ApiKey(swaggerProperties.getTokenHeader(), swaggerProperties.getTokenHeader(), In.HEADER.toValue());
|
||||||
|
schemes.add(scheme);
|
||||||
|
return schemes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权信息全局应用
|
||||||
|
*/
|
||||||
|
private List<SecurityContext> securityContexts() {
|
||||||
|
SecurityContext securityContext = SecurityContext.builder()
|
||||||
|
.securityReferences(Collections.singletonList(new SecurityReference(swaggerProperties.getTokenHeader(), new AuthorizationScope[]{new AuthorizationScope("global", "")})))
|
||||||
|
.build();
|
||||||
|
return Collections.singletonList(securityContext);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(WebServerInitializedEvent webServerInitializedEvent) {
|
||||||
|
try {
|
||||||
|
Logger logger = LoggerFactory.getLogger(Swagger2Config.class);
|
||||||
|
|
||||||
|
//获取IP
|
||||||
|
String hostAddress = Inet4Address.getLocalHost().getHostAddress();
|
||||||
|
//获取端口号
|
||||||
|
int port = webServerInitializedEvent.getWebServer().getPort();
|
||||||
|
//获取应用名
|
||||||
|
String applicationName = webServerInitializedEvent.getApplicationContext().getApplicationName();
|
||||||
|
logger.info("项目启动成功!接口文档地址: http://" + hostAddress + ":" + webServerInitializedEvent.getWebServer().getPort() + applicationName + "/doc.html#");
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,55 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.util;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 出参对象统一封装
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
public class ResultDataEntity<T> {
|
||||||
|
/**
|
||||||
|
* 状态码
|
||||||
|
*/
|
||||||
|
private final Integer code;
|
||||||
|
/**
|
||||||
|
* 异常提示
|
||||||
|
*/
|
||||||
|
// @JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
private String msg = null;
|
||||||
|
/**
|
||||||
|
* 返回体对象
|
||||||
|
*/
|
||||||
|
// @JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
private T data = null;
|
||||||
|
|
||||||
|
public ResultDataEntity(T data) {
|
||||||
|
this.code = HttpStatus.OK.value();
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultDataEntity(HttpStatus status, T data) {
|
||||||
|
this.code = status.value();
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultDataEntity(HttpStatus status, String msg, T data) {
|
||||||
|
this.code = status.value();
|
||||||
|
this.msg = msg;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultDataEntity(String msg) {
|
||||||
|
this.code = HttpStatus.OK.value();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultDataEntity(HttpStatus status, String msg) {
|
||||||
|
this.code = status.value();
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultDataEntity(HttpStatus status) {
|
||||||
|
this.code = status.value();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.util;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对ResponseEntity做了简单包装
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@ApiModel("API返回对象")
|
||||||
|
@Getter
|
||||||
|
public class ResultEntity<T> extends ResponseEntity<ResultDataEntity<T>> {
|
||||||
|
public ResultEntity(T data) {
|
||||||
|
super(new ResultDataEntity<>(HttpStatus.OK, data), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultEntity(HttpStatus status, T data) {
|
||||||
|
super(new ResultDataEntity<>(status, data), status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultEntity(HttpStatus status, String msg, T data) {
|
||||||
|
super(new ResultDataEntity<>(status, msg, data), status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultEntity(String msg) {
|
||||||
|
super(new ResultDataEntity<>(HttpStatus.OK, msg), HttpStatus.OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultEntity(HttpStatus status, String msg) {
|
||||||
|
super(new ResultDataEntity<>(status, msg), status);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultEntity(HttpStatus status) {
|
||||||
|
super(new ResultDataEntity<>(status), status);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.sztzjy.forex.trading_trading.util;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异常工具
|
||||||
|
*
|
||||||
|
* 陈沅
|
||||||
|
*/
|
||||||
|
public class ThrowableUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取堆栈信息
|
||||||
|
*/
|
||||||
|
public static String getStackTrace(Throwable throwable) {
|
||||||
|
StringWriter sw = new StringWriter();
|
||||||
|
try (PrintWriter pw = new PrintWriter(sw)) {
|
||||||
|
throwable.printStackTrace(pw);
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
spring:
|
||||||
|
datasource:
|
||||||
|
druid:
|
||||||
|
db-type: com.alibaba.druid.pool.DruidDataSource
|
||||||
|
driverClassName: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://${DB_HOST:118.31.7.2}:${DB_PORT:3306}}/${DB_NAME:foreign_trading_system}?useSSL=false&serverTimezone=UTC
|
||||||
|
username: ${DB_USER:root}
|
||||||
|
password: ${DB_PWD:sztzjy2017}
|
@ -0,0 +1,82 @@
|
|||||||
|
server:
|
||||||
|
port: 8800
|
||||||
|
servlet:
|
||||||
|
context-path: /
|
||||||
|
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: trading_system
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
mvc:
|
||||||
|
pathmatch:
|
||||||
|
matching-strategy: ant_path_matcher
|
||||||
|
jackson:
|
||||||
|
time-zone: GMT+8
|
||||||
|
datasource:
|
||||||
|
druid:
|
||||||
|
# 初始连接数
|
||||||
|
initial-size: 5
|
||||||
|
# 最小连接数
|
||||||
|
min-idle: 15
|
||||||
|
# 最大连接数
|
||||||
|
max-active: 500
|
||||||
|
# 获取连接超时时间
|
||||||
|
max-wait: 5000
|
||||||
|
# 连接有效性检测时间
|
||||||
|
time-between-eviction-runs-millis: 60000
|
||||||
|
# 连接在池中最小生存的时间
|
||||||
|
min-evictable-idle-time-millis: 300000
|
||||||
|
# 连接在池中最大生存的时间
|
||||||
|
max-evictable-idle-time-millis: 900000
|
||||||
|
# 指明连接是否被空闲连接回收器(如果有)进行检验.如果检测失败,则连接将被从池中去除
|
||||||
|
test-while-idle: true
|
||||||
|
# 指明是否在从池中取出连接前进行检验,如果检验失败, 则从池中去除连接并尝试取出另一个
|
||||||
|
test-on-borrow: false
|
||||||
|
# 是否在归还到池中前进行检验
|
||||||
|
test-on-return: false
|
||||||
|
# 检测连接是否有效
|
||||||
|
validation-query: select 'X'
|
||||||
|
# 配置监控统计
|
||||||
|
webStatFilter:
|
||||||
|
enabled: true
|
||||||
|
stat-view-servlet:
|
||||||
|
allow:
|
||||||
|
enabled: true
|
||||||
|
# 控制台管理用户名和密码
|
||||||
|
url-pattern: /druid/*
|
||||||
|
reset-enable: false
|
||||||
|
login-username: admin
|
||||||
|
login-password: 2023inspect
|
||||||
|
filter:
|
||||||
|
stat:
|
||||||
|
enabled: true
|
||||||
|
# 记录慢SQL
|
||||||
|
log-slow-sql: false
|
||||||
|
slow-sql-millis: 1000
|
||||||
|
merge-sql: true
|
||||||
|
wall:
|
||||||
|
config:
|
||||||
|
multi-statement-allow: true
|
||||||
|
#配置 Jpa
|
||||||
|
jpa:
|
||||||
|
hibernate:
|
||||||
|
ddl-auto: update
|
||||||
|
open-in-view: true
|
||||||
|
show-sql: true
|
||||||
|
properties:
|
||||||
|
hibernate:
|
||||||
|
format_sql: true
|
||||||
|
dialect: org.hibernate.dialect.MySQL8Dialect
|
||||||
|
temp:
|
||||||
|
use_jdbc_metadata_defaults: false
|
||||||
|
database: mysql
|
||||||
|
|
||||||
|
swagger:
|
||||||
|
enable: true
|
||||||
|
tokenHeader: Authorization
|
||||||
|
title: 天择外汇模拟交易 • 接口文档
|
||||||
|
description: 天择外汇模拟交易WebAPI接口文档
|
||||||
|
contactName: 深圳天择教育科技有限公司
|
||||||
|
contactAddress: www.sztzjy.com
|
||||||
|
version: @project.version@
|
@ -0,0 +1,13 @@
|
|||||||
|
package com.sztzjy.foreign_exchange_trading;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class ForeignExchangeTradingApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue