enums.JxcEnum
import lombok.Getter;
@Getter
public enum JxcEnum {
PARAMETER_ERROR(1,"参数不合法"),
USERNAME_ERROR(2,"用户名错误"),
PASSWORD_ERROR(3,"密码错误"),
UNKNOWN_ERROR(4,"未知错误"),
USER_NOT_LOGIN(5,"用户未登录"),
STOCK_NOT_ENOUGH(6,"库存不足"),
REDUCE_STOCK_ERROR(7,"削减库存失败"),
PRODUCT_NOT_EXIST(8,"商品不存在"),
SALE_SAVE_ERROR(9,"保存失败"),
;
private Integer code;
private String msg;
JxcEnum(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
}
exception.JxcException
import lombok.Getter;
@Getter
public class JxcException extends RuntimeException{
private Integer code;
public JxcException(Integer code,String message){
super(message);
this.code = code;
}
public JxcException(JxcEnum jxcEnum){
super(jxcEnum.getMsg());
this.code = jxcEnum.getCode();
}
}
util.R
public class R {
public static ResultVO ok(){
return new ResultVO(0,"成功",null);
}
public static ResultVO ok(Object data){
return new ResultVO(0,"成功",data);
}
public static ResultVO error(Integer code,String msg){
return new ResultVO(code,msg,null);
}
public static ResultVO error(JxcEnum jxcEnum){
return new ResultVO(jxcEnum.getCode(),jxcEnum.getMsg(),null);
}
}
vo.ResultVO
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResultVO {
private Integer code;
private String msg;
private Object data;
}
task.BackUpDB
import com.qf.lock.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
public class BackupDB {
@Autowired
private RedisLock lock;
private final String BACKUP_DB_LOCK = "redis-lock:BACKUP_DB";
private static final String BASE_PATH_LINUX = "/usr/local/app-sql-backup/";
private static final String BASE_PATH_WINDEWS = "D:\\";
//@Scheduled(cron = "0,30 * * * * ?")
//public void backwindows() {
//
// try {
//
// String sqlname = BASE_PATH_WINDEWS + "jxc."
//
// + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
// + ".sql";
// // mysqldump --user=root --password=P@ssw0rd --opt jxc> jxc-2011-11-11.sql
// String mysql = "mysqldump --user=root --password=dong1995 --opt jxc> "
//
// + sqlname;
//
// java.lang.Runtime.getRuntime().exec("cmd /c " + mysql);
//
// } catch (Exception e) {
//
// e.printStackTrace();
//
// }
//
//}
@Scheduled(cron = "0,30 * * * * ?")
public void backLinux() {
String value = System.currentTimeMillis() + "";
// 上锁.
if(lock.lock(BACKUP_DB_LOCK,value)) {
try {
System.out.println("backup!!!!!!!!!!!开始");
String sqlname = BASE_PATH_LINUX + "jxc."
+ new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
+ ".sql";
// mysqldump --user=root --password=P@ssw0rd --opt jxc> jxc-2001-11-11.sql
String mysql = "mysqldump --user=root --password=dong1995 --opt jxc>" + sqlname;
System.out.println(mysql);
java.lang.Runtime.getRuntime().exec(
new String[]{"sh", "-c", mysql});
System.out.println("backup!!!!!!!!!!!!结束");
lock.unlock(BACKUP_DB_LOCK);
} catch (Exception e) {
e.printStackTrace();
}
}else{
// 没有拿到锁
System.out.println("没有竞争到锁资源,由其他服务执行任务.");
}
}
}
lock.RedisLock
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
@Component
public class RedisLock {
@Autowired
private RedisTemplate<String,String> redisTemplate;
private final Long TIME_OUT = 5000L;
//开锁
//key -> 商品的id, value -> 当前系统时间的毫秒值
public boolean lock(String key,String value){
if (!redisTemplate.opsForValue().setIfAbsent(key, value)){
//获取锁资源失败
String oldValue = redisTemplate.opsForValue().get(key);
if (!StringUtils.isEmpty(oldValue)&&Long.parseLong(value)-Long.parseLong(oldValue)>TIME_OUT){
//当前线程在死锁发生后,获取到了锁资源
return true;
}
return false;
}
//获取到了锁资源
return true;
}
//释放锁资源
public void unlock(String key){
redisTemplate.delete(key);
}
}
controller.UserController
import com.qf.entity.User;
import com.qf.enums.JxcEnum;
import com.qf.service.UserService;
import com.qf.util.R;
import com.qf.vo.ResultVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
@Slf4j
@CrossOrigin(allowCredentials = "true")
@Api(tags = "用户模块接口")
public class UserController {
@Autowired
private UserService userService;
@PostMapping("/login")
@ApiOperation(value = "用户登录接口")
@ApiImplicitParams({@ApiImplicitParam(name = "username",value = "请输入用户名",defaultValue = "lisi"),
@ApiImplicitParam(name = "password",value = "请输入密码",defaultValue = "aaa")})
public ResultVO login(String username, String password){
if (StringUtils.isEmpty(username)||StringUtils.isEmpty(password)){
log.info("[用户登录]参数不合法,username = {},password = {}",username,password);
return R.error(JxcEnum.PARAMETER_ERROR);
}
Subject subject = SecurityUtils.getSubject();
try {
subject.login(new UsernamePasswordToken(username,password));
} catch (UnknownAccountException e) {
e.printStackTrace();
return R.error(JxcEnum.USERNAME_ERROR);
}catch (IncorrectCredentialsException e){
e.printStackTrace();
return R.error(JxcEnum.PARAMETER_ERROR);
}catch (Exception e){
e.printStackTrace();
return R.error(JxcEnum.UNKNOWN_ERROR);
}
return R.ok();
}
@GetMapping("/info")
@ApiOperation(value = "获取登录用户真实姓名")
public ResultVO info(){
Subject subject = SecurityUtils.getSubject();
User user = (User)subject.getPrincipal();
if (user == null){
log.info("[获取真实姓名] 用户未登录!!!");
return R.error(JxcEnum.USER_NOT_LOGIN);
}
return R.ok(user.getRealname());
}
//public static void main(String[] args) {
// System.out.println(new Md5Hash("aaa",null,1024).toString());
//}
@PostMapping("/logout")
@ApiOperation("退出登录")
public ResultVO logout(){
Subject subject = SecurityUtils.getSubject();
try {
subject.logout();
} catch (Exception e) {
e.printStackTrace();
return R.error(JxcEnum.UNKNOWN_ERROR);
}
return R.ok();
}
}
logback-spring.xml
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>
%d - %msg%n
</pattern>
</layout>
</appender>
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>
%msg%n
</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>D:logs/info.%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>
%msg%n
</pattern>
</encoder>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>D:logs/error.%d.log</fileNamePattern>
</rollingPolicy>
</appender>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE"/>
<root level="info">
<appender-ref ref="consoleLog" />
<appender-ref ref="fileInfoLog" />
<appender-ref ref="fileErrorLog" />
</root>
</configuration>
JxcApplication.java
@SpringBootApplication
@MapperScan(basePackages = "com.qf.mapper")
@EnableTransactionManagement
@EnableScheduling
public class JxcApplication {
public static void main(String[] args) {
SpringApplication.run(JxcApplication.class, args);
}
}
application-dev.yml
server:
port: 80
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///jxc?characterEncoding=UTF-8&serverTimezone=GMT%2B8
username: root
password:
type: com.alibaba.druid.pool.DruidDataSource
redis:
host: 47.98.189.ccc
port: 6379
mybatis:
type-aliases-package: com.qf.entity
mapper-locations: classpath:mapper/*.xml
configuration:
map-underscore-to-camel-case: true
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
shiro:
loginUrl: /
unauthorizedUrl: /
pom.xml
<?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.0.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.qf</groupId>
<artifactId>jxc</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jxc</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--swagger-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!--mapper-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
<!--pagehelper-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
<!--shiro-->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-web-starter</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</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>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>