Commit 9f87bedef77ebf74f6a18c655d446edcfd4dac16
0 parents
SNManage init
Showing
13 changed files
with
728 additions
and
0 deletions
.gitignore
0 → 100644
1 | +++ a/.gitignore | ||
1 | +target/ | ||
2 | +!.mvn/wrapper/maven-wrapper.jar | ||
3 | +!**/src/main/**/target/ | ||
4 | +!**/src/test/**/target/ | ||
5 | + | ||
6 | +### IntelliJ IDEA ### | ||
7 | +.idea/ | ||
8 | + | ||
9 | +### Eclipse ### | ||
10 | +.apt_generated | ||
11 | +.classpath | ||
12 | +.factorypath | ||
13 | +.project | ||
14 | +.settings | ||
15 | +.springBeans | ||
16 | +.sts4-cache | ||
17 | + | ||
18 | +### NetBeans ### | ||
19 | +/nbproject/private/ | ||
20 | +/nbbuild/ | ||
21 | +/dist/ | ||
22 | +/nbdist/ | ||
23 | +/.nb-gradle/ | ||
24 | +build/ | ||
25 | +!**/src/main/**/build/ | ||
26 | +!**/src/test/**/build/ | ||
27 | + | ||
28 | +### VS Code ### | ||
29 | +.vscode/ | ||
30 | + | ||
31 | +### Mac OS ### | ||
32 | +.DS_Store | ||
0 | \ No newline at end of file | 33 | \ No newline at end of file |
README.md
0 → 100644
1 | +++ a/README.md | ||
1 | +**配置SN文件路径:** | ||
2 | +在resources下设置**application.properties**文件中的**SN.file.path**属性(该属性是存储SN的文件的路径,文件格式是txt,例:D:/temp/SN.txt) | ||
3 | +以及设置**SN.file.temp.path**属性(该属性是SN备份文件的路径,文件格式是txt,例:D:/temp/SNTemp.txt) | ||
4 | + | ||
5 | +**配置日志文件路径:** | ||
6 | +在resources下设置**log4j2.xml**文件中"Property name="baseDir" value="./log"/"标签内的value值(该值为存储日志文件的文件夹路径,例:D:/temp/log) |
pom.xml
0 → 100644
1 | +++ a/pom.xml | ||
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <modelVersion>4.0.0</modelVersion> | ||
6 | + | ||
7 | + <groupId>com.haoge</groupId> | ||
8 | + <artifactId>SNManageDemo</artifactId> | ||
9 | + <version>1.0</version> | ||
10 | + | ||
11 | + <properties> | ||
12 | + | ||
13 | + </properties> | ||
14 | + | ||
15 | + | ||
16 | + <parent> | ||
17 | + <groupId>org.springframework.boot</groupId> | ||
18 | + <artifactId>spring-boot-starter-parent</artifactId> | ||
19 | + <version>2.3.1.RELEASE</version> | ||
20 | + <relativePath/> | ||
21 | + </parent> | ||
22 | + | ||
23 | + <dependencies> | ||
24 | + <!--springboot启动类依赖导入--> | ||
25 | + <dependency> | ||
26 | + <groupId>org.springframework.boot</groupId> | ||
27 | + <artifactId>spring-boot-starter-web</artifactId> | ||
28 | + </dependency> | ||
29 | + <!--junit5--> | ||
30 | + <dependency> | ||
31 | + <groupId>org.springframework.boot</groupId> | ||
32 | + <artifactId>spring-boot-starter-test</artifactId> | ||
33 | + <scope>test</scope> | ||
34 | + </dependency> | ||
35 | + <dependency> | ||
36 | + <groupId>org.springframework.boot</groupId> | ||
37 | + <artifactId>spring-boot-starter-thymeleaf</artifactId> | ||
38 | + </dependency> | ||
39 | + <dependency> | ||
40 | + <groupId>io.springfox</groupId> | ||
41 | + <artifactId>springfox-swagger2</artifactId> | ||
42 | + <version>2.7.0</version> | ||
43 | + </dependency> | ||
44 | + <dependency> | ||
45 | + <groupId>io.springfox</groupId> | ||
46 | + <artifactId>springfox-swagger-ui</artifactId> | ||
47 | + <version>2.7.0</version> | ||
48 | + </dependency> | ||
49 | + <!--hutool工具类--> | ||
50 | + <dependency> | ||
51 | + <groupId>cn.hutool</groupId> | ||
52 | + <artifactId>hutool-http</artifactId> | ||
53 | + <version>4.1.14</version> | ||
54 | + </dependency> | ||
55 | + <dependency> | ||
56 | + <groupId>org.projectlombok</groupId> | ||
57 | + <artifactId>lombok</artifactId> | ||
58 | + <version>1.16.10</version> | ||
59 | + </dependency> | ||
60 | + <!--排除springboot自带的日志依赖--> | ||
61 | + <dependency> | ||
62 | + <groupId>org.springframework.boot</groupId> | ||
63 | + <artifactId>spring-boot-starter</artifactId> | ||
64 | + <exclusions> | ||
65 | + <exclusion> | ||
66 | + <groupId>org.springframework.boot</groupId> | ||
67 | + <artifactId>spring-boot-starter-logging</artifactId> | ||
68 | + </exclusion> | ||
69 | + </exclusions> | ||
70 | + </dependency> | ||
71 | + <!--导入log4j2日志依赖--> | ||
72 | + <dependency> | ||
73 | + <groupId>org.springframework.boot</groupId> | ||
74 | + <artifactId>spring-boot-starter-log4j2</artifactId> | ||
75 | + </dependency> | ||
76 | + | ||
77 | + | ||
78 | + </dependencies> | ||
79 | + | ||
80 | + <build> | ||
81 | + | ||
82 | + <resources> | ||
83 | + <resource> | ||
84 | + <directory>src/main/java</directory> | ||
85 | + <includes> | ||
86 | + <include>**/*.xml</include> | ||
87 | + </includes> | ||
88 | + </resource> | ||
89 | + <resource> | ||
90 | + <directory>src/main/resources</directory> | ||
91 | + <includes> | ||
92 | + <include>**/*.*</include> | ||
93 | + </includes> | ||
94 | + </resource> | ||
95 | + </resources> | ||
96 | + </build> | ||
97 | + | ||
98 | +</project> | ||
0 | \ No newline at end of file | 99 | \ No newline at end of file |
src/main/java/com/example/demo/SNManageApplication.java
0 → 100644
1 | +++ a/src/main/java/com/example/demo/SNManageApplication.java | ||
1 | +package com.example.demo; | ||
2 | + | ||
3 | +import org.springframework.boot.SpringApplication; | ||
4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
5 | +import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||
6 | + | ||
7 | + | ||
8 | +@SpringBootApplication | ||
9 | +@EnableSwagger2 | ||
10 | +public class SNManageApplication { | ||
11 | + | ||
12 | + public static void main(String[] args) { | ||
13 | + SpringApplication.run(SNManageApplication.class, args); | ||
14 | + } | ||
15 | + | ||
16 | +} |
src/main/java/com/example/demo/controller/SNController.java
0 → 100644
1 | +++ a/src/main/java/com/example/demo/controller/SNController.java | ||
1 | +package com.example.demo.controller; | ||
2 | + | ||
3 | +import com.example.demo.exception.SNRepetitiveException; | ||
4 | +import com.example.demo.service.SNService; | ||
5 | +import com.example.demo.util.HttpResult; | ||
6 | +import io.swagger.annotations.Api; | ||
7 | +import io.swagger.annotations.ApiOperation; | ||
8 | +import org.apache.logging.log4j.LogManager; | ||
9 | +import org.apache.logging.log4j.Logger; | ||
10 | +import org.springframework.beans.factory.annotation.Autowired; | ||
11 | +import org.springframework.stereotype.Controller; | ||
12 | +import org.springframework.web.bind.annotation.*; | ||
13 | + | ||
14 | +import javax.servlet.http.HttpServletRequest; | ||
15 | +import javax.servlet.http.HttpServletResponse; | ||
16 | +import java.io.IOException; | ||
17 | + | ||
18 | +@Api(tags = "SN操作") | ||
19 | +@Controller | ||
20 | +public class SNController { | ||
21 | + static Logger logger = LogManager.getLogger(SNController.class); | ||
22 | + | ||
23 | + @Autowired | ||
24 | + SNService snService; | ||
25 | + | ||
26 | + @ApiOperation("首页") | ||
27 | + @GetMapping("/index.html") | ||
28 | + public String index() { | ||
29 | + return "Index"; | ||
30 | + } | ||
31 | + | ||
32 | + @ApiOperation("添加SN") | ||
33 | + @PostMapping("/add_SN") | ||
34 | + @ResponseBody | ||
35 | + public HttpResult addSN(@RequestBody String SNDto) { | ||
36 | + | ||
37 | + try { | ||
38 | + snService.addSN(SNDto); | ||
39 | + return HttpResult.success("添加成功"); | ||
40 | + } catch (SNRepetitiveException e) { | ||
41 | + return HttpResult.fail("SN已存在,请勿重复添加!"); | ||
42 | + } catch (Exception e) { | ||
43 | + logger.error(e.getMessage()); | ||
44 | + return HttpResult.fail(); | ||
45 | + } | ||
46 | + | ||
47 | + } | ||
48 | + | ||
49 | + | ||
50 | +// @ApiOperation("获取全部SN") | ||
51 | +// @GetMapping("/get_SNs") | ||
52 | +// @ResponseBody | ||
53 | +// public void getSNs(HttpServletRequest request, HttpServletResponse response) { | ||
54 | +// try { | ||
55 | +// snService.downloadSNFile(request, response); | ||
56 | +// } catch (Exception e) { | ||
57 | +// response.setStatus(500); | ||
58 | +// } | ||
59 | +// | ||
60 | +// } | ||
61 | + | ||
62 | + @ApiOperation("获取全部base64加密后的SN") | ||
63 | + @GetMapping("/get_SNs") | ||
64 | + @ResponseBody | ||
65 | + public HttpResult<String> getBase64SNs() throws IOException { | ||
66 | + try { | ||
67 | + return HttpResult.success("",snService.getEncryptSNs()); | ||
68 | + } catch (Exception e) { | ||
69 | + logger.error(e.getMessage()); | ||
70 | + return HttpResult.fail("服务器异常"); | ||
71 | + } | ||
72 | + | ||
73 | + } | ||
74 | + | ||
75 | + @ApiOperation("删除指定SN") | ||
76 | + @PostMapping("/delete_SN") | ||
77 | + @ResponseBody | ||
78 | + public HttpResult deleteSN(@RequestBody String SN) { | ||
79 | + try { | ||
80 | + snService.deleteSN(SN); | ||
81 | + return HttpResult.success("SN已删除或不存在!"); | ||
82 | + } | ||
83 | + catch (Exception e) { | ||
84 | + logger.error(e.getMessage()); | ||
85 | + return HttpResult.fail("服务器异常!"); | ||
86 | + } | ||
87 | + } | ||
88 | + | ||
89 | + | ||
90 | +} |
src/main/java/com/example/demo/exception/SNRepetitiveException.java
0 → 100644
1 | +++ a/src/main/java/com/example/demo/exception/SNRepetitiveException.java | ||
1 | +package com.example.demo.exception; | ||
2 | + | ||
3 | +public class SNRepetitiveException extends Exception{ | ||
4 | + | ||
5 | + public SNRepetitiveException() {} | ||
6 | + | ||
7 | + public SNRepetitiveException(String message) { | ||
8 | + super(message); | ||
9 | + } | ||
10 | + | ||
11 | +} |
src/main/java/com/example/demo/service/SNService.java
0 → 100644
1 | +++ a/src/main/java/com/example/demo/service/SNService.java | ||
1 | +package com.example.demo.service; | ||
2 | + | ||
3 | +import com.example.demo.exception.SNRepetitiveException; | ||
4 | + | ||
5 | +import javax.servlet.http.HttpServletRequest; | ||
6 | +import javax.servlet.http.HttpServletResponse; | ||
7 | +import java.io.FileNotFoundException; | ||
8 | +import java.io.IOException; | ||
9 | + | ||
10 | +public interface SNService { | ||
11 | + /** | ||
12 | + * 新增SN号 | ||
13 | + * @param SN SN号 | ||
14 | + */ | ||
15 | + void addSN(String SN) throws SNRepetitiveException, IOException; | ||
16 | + | ||
17 | + /** | ||
18 | + * 下载所有SN号 | ||
19 | + */ | ||
20 | + void downloadSNFile(HttpServletRequest request, HttpServletResponse response) throws IOException; | ||
21 | + | ||
22 | + /** | ||
23 | + * 获取所有加密后的SN字符串 | ||
24 | + * @return - | ||
25 | + */ | ||
26 | + String getEncryptSNs() throws IOException; | ||
27 | + | ||
28 | + /** | ||
29 | + * 删除指定SN记录 | ||
30 | + * @param SN SN号 | ||
31 | + */ | ||
32 | + void deleteSN(String SN) throws Exception; | ||
33 | + | ||
34 | +} |
src/main/java/com/example/demo/service/impl/SNServiceImpl.java
0 → 100644
1 | +++ a/src/main/java/com/example/demo/service/impl/SNServiceImpl.java | ||
1 | +package com.example.demo.service.impl; | ||
2 | + | ||
3 | +import cn.hutool.core.codec.Base64; | ||
4 | +import com.example.demo.exception.SNRepetitiveException; | ||
5 | +import com.example.demo.service.SNService; | ||
6 | +import org.springframework.beans.factory.annotation.Value; | ||
7 | +import org.springframework.stereotype.Service; | ||
8 | + | ||
9 | +import javax.servlet.http.HttpServletRequest; | ||
10 | +import javax.servlet.http.HttpServletResponse; | ||
11 | +import java.io.*; | ||
12 | +import java.util.HashSet; | ||
13 | +import java.util.Set; | ||
14 | +import java.util.concurrent.locks.Lock; | ||
15 | +import java.util.concurrent.locks.ReentrantLock; | ||
16 | + | ||
17 | +@Service | ||
18 | +public class SNServiceImpl implements SNService { | ||
19 | + /** | ||
20 | + * 多线程改写文件存在并发问题,需加锁操作 | ||
21 | + */ | ||
22 | + private static final Lock lock = new ReentrantLock(); | ||
23 | + | ||
24 | + @Value("${SN.file.path}") | ||
25 | + String SNFilePath; | ||
26 | + | ||
27 | + @Value("${SN.file.temp.path}") | ||
28 | + String SNTempFilePath; | ||
29 | + | ||
30 | + @Override | ||
31 | + public void addSN(String SNDto) throws SNRepetitiveException, IOException { | ||
32 | + //加try,catch只为释放锁 | ||
33 | + try { | ||
34 | + //加锁 | ||
35 | + lock.lock(); | ||
36 | + | ||
37 | + //读取文件,判断SN是否重复 | ||
38 | + Set<String> set = new HashSet<>(); | ||
39 | + BufferedReader bufferedReader = new BufferedReader(new FileReader(SNFilePath)); | ||
40 | + String br; | ||
41 | + while ((br=bufferedReader.readLine()) != null) { | ||
42 | + //截取SN | ||
43 | + int index = br.indexOf('#'); | ||
44 | + String SN = br.substring(0,index == -1? 0 : index); | ||
45 | + set.add(SN); | ||
46 | + } | ||
47 | + | ||
48 | + String addSn = SNDto.substring(0,SNDto.indexOf('#')); | ||
49 | + if (set.contains(addSn)) { | ||
50 | + throw new SNRepetitiveException("SN:" + addSn + " 已存在,请勿重复添加"); | ||
51 | + } | ||
52 | + | ||
53 | + //写入 | ||
54 | + FileWriter fileWriter = new FileWriter(SNFilePath,true); | ||
55 | + fileWriter.write(SNDto+System.lineSeparator()); | ||
56 | + fileWriter.flush(); | ||
57 | + fileWriter.close(); | ||
58 | + } finally { //释放锁 | ||
59 | + lock.unlock(); | ||
60 | + } | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public String getEncryptSNs() throws IOException { | ||
65 | + File file = new File(SNFilePath); | ||
66 | + //读取文件 | ||
67 | + byte[] SNsByteArr = new byte[(int) file.length()]; | ||
68 | + FileInputStream fileInputStream = new FileInputStream(file); | ||
69 | + fileInputStream.read(SNsByteArr); | ||
70 | + //加密 | ||
71 | + String encodeSNs = Base64.encode(SNsByteArr); | ||
72 | + | ||
73 | + return encodeSNs; | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public void deleteSN(String SN) throws Exception{ | ||
78 | + try { | ||
79 | + lock.lock(); | ||
80 | + | ||
81 | + //读取文件,记录不用删除的数据 | ||
82 | + BufferedReader bufferedReader = new BufferedReader(new FileReader(SNFilePath)); | ||
83 | + String br; | ||
84 | + StringBuilder stringBuilder = new StringBuilder(); | ||
85 | + boolean SNExist = false; | ||
86 | + while ((br=bufferedReader.readLine()) != null) { | ||
87 | + //截取SN | ||
88 | + int index = br.indexOf('#'); | ||
89 | + String str = br.substring(0,index == -1? 0 : index); | ||
90 | + if (!SN.equals(str)) { | ||
91 | + stringBuilder.append(br); | ||
92 | + stringBuilder.append(System.lineSeparator()); | ||
93 | + } else { | ||
94 | + SNExist = true; | ||
95 | + } | ||
96 | + } | ||
97 | + bufferedReader.close(); | ||
98 | + | ||
99 | + //如果存在要删除的SN,先将数据备份,再将留存数据覆盖掉原SN文件,避免数据写一半断电丢失。 | ||
100 | + if (SNExist) { | ||
101 | + //备份数据 | ||
102 | + FileWriter SNTempfileWriter = new FileWriter(SNTempFilePath); | ||
103 | + SNTempfileWriter.write(stringBuilder.toString()); | ||
104 | + SNTempfileWriter.flush(); | ||
105 | + SNTempfileWriter.close(); | ||
106 | + //覆盖掉原来的数据到SN文件中 | ||
107 | + FileWriter SNfileWriter = new FileWriter(SNFilePath); | ||
108 | + SNfileWriter.write(stringBuilder.toString()); | ||
109 | + SNfileWriter.flush(); | ||
110 | + SNfileWriter.close(); | ||
111 | + | ||
112 | + } | ||
113 | + | ||
114 | + | ||
115 | + } finally { | ||
116 | + lock.unlock(); | ||
117 | + } | ||
118 | + } | ||
119 | + | ||
120 | + @Override | ||
121 | + public void downloadSNFile(HttpServletRequest request, HttpServletResponse response) throws IOException { | ||
122 | + File file = new File(SNFilePath); | ||
123 | + | ||
124 | + response.setCharacterEncoding("UTF-8"); | ||
125 | + response.setHeader("Content-type","application/octet-stream;charset=UTF-8"); | ||
126 | + response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(file.getName().trim(), "UTF-8")); | ||
127 | + response.addHeader("Pargam", "no-cache"); | ||
128 | + response.addHeader("Cache-Control", "no-cache"); | ||
129 | + | ||
130 | + //读取文件 | ||
131 | + byte[] SNsByteArr = new byte[(int) file.length()]; | ||
132 | + FileInputStream fileInputStream = new FileInputStream(file); | ||
133 | + fileInputStream.read(SNsByteArr); | ||
134 | + //加密 | ||
135 | + String encodeSNs = Base64.encode(SNsByteArr); | ||
136 | + | ||
137 | + //写入到输出流 | ||
138 | + response.addHeader("Content-Length",String.valueOf(encodeSNs.getBytes().length)); | ||
139 | + OutputStream outputStream = response.getOutputStream(); | ||
140 | + outputStream.write(encodeSNs.getBytes()); | ||
141 | + outputStream.flush(); | ||
142 | + outputStream.close(); | ||
143 | + | ||
144 | + } | ||
145 | + | ||
146 | +} |
src/main/java/com/example/demo/util/HttpResult.java
0 → 100644
1 | +++ a/src/main/java/com/example/demo/util/HttpResult.java | ||
1 | +package com.example.demo.util; | ||
2 | + | ||
3 | +import lombok.AllArgsConstructor; | ||
4 | +import lombok.Data; | ||
5 | +import lombok.NoArgsConstructor; | ||
6 | + | ||
7 | +import java.io.Serializable; | ||
8 | + | ||
9 | +@Data | ||
10 | +@AllArgsConstructor | ||
11 | +@NoArgsConstructor | ||
12 | +public class HttpResult<T> implements Serializable { | ||
13 | + public static final int CODE_SUCCESS = 200; | ||
14 | + public static final int CODE_FAILED = 500; | ||
15 | + | ||
16 | + private Integer code; | ||
17 | + | ||
18 | + private String message; | ||
19 | + | ||
20 | + private T data; | ||
21 | + | ||
22 | + public static <T> HttpResult<T> success() { | ||
23 | + return new HttpResult<>(200,"success",null); | ||
24 | + } | ||
25 | + | ||
26 | + public static <T> HttpResult<T> success(String message) { | ||
27 | + return new HttpResult<>(200,message,null); | ||
28 | + } | ||
29 | + | ||
30 | + public static <T> HttpResult<T> success(String message, T data) { | ||
31 | + return new HttpResult<>(200,message,data); | ||
32 | + } | ||
33 | + | ||
34 | + public static <T> HttpResult<T> fail() { | ||
35 | + return new HttpResult<>(500,"fail",null); | ||
36 | + } | ||
37 | + public static <T> HttpResult<T> fail(String message) { | ||
38 | + return new HttpResult<>(500,message,null); | ||
39 | + } | ||
40 | +} |
src/main/resources/application.properties
0 → 100644
1 | +++ a/src/main/resources/application.properties | ||
1 | + server.port=8080 | ||
2 | + | ||
3 | + | ||
4 | +spring.web.resources.static-locations=classpath:/META-INF/resources/,classpath:/resources/,classpath:/static/,classpath:/public/ | ||
5 | + | ||
6 | + | ||
7 | +logging.config=classpath:log4j2.xml | ||
8 | + | ||
9 | +#swagger.basic.enable = true | ||
10 | +#swagger.basic.username = test | ||
11 | +#swagger.basic.password = 123 | ||
12 | + | ||
13 | +spring.thymeleaf.cache=false | ||
14 | +spring.thymeleaf.prefix=classpath:/templates/ | ||
15 | +spring.thymeleaf.suffix=.html | ||
16 | + | ||
17 | + | ||
18 | +SN.file.path=D:/temp/SN.txt | ||
19 | +SN.file.temp.path=D:/temp/SNTemp.txt | ||
0 | \ No newline at end of file | 20 | \ No newline at end of file |
src/main/resources/log4j2.xml
0 → 100644
1 | +++ a/src/main/resources/log4j2.xml | ||
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> | ||
3 | +<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出--> | ||
4 | +<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数--> | ||
5 | +<configuration status="WARN" monitorInterval="30"> | ||
6 | + <Properties> | ||
7 | + <Property name="baseDir" value="D:/temp/log"/> | ||
8 | + </Properties> | ||
9 | + <!--先定义所有的appender--> | ||
10 | + <appenders> | ||
11 | + <!--这个输出控制台的配置--> | ||
12 | + <console name="Console" target="SYSTEM_OUT"> | ||
13 | + <!--输出日志的格式--> | ||
14 | + <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
15 | + </console> | ||
16 | + <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,个这也挺有用的,适合临时测试用--> | ||
17 | +<!-- <File name="log" fileName="${baseDir}/all.log" append="false">--> | ||
18 | +<!-- <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>--> | ||
19 | +<!-- </File>--> | ||
20 | + <!--这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--> | ||
21 | + <RollingFile name="RollingFileInfo" fileName="${baseDir}/info.log" | ||
22 | + filePattern="${baseDir}/$${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log"> | ||
23 | + <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)--> | ||
24 | + <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> | ||
25 | + <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
26 | + <Policies> | ||
27 | + <TimeBasedTriggeringPolicy/> | ||
28 | + <SizeBasedTriggeringPolicy size="100 MB"/> | ||
29 | + </Policies> | ||
30 | + </RollingFile> | ||
31 | + <RollingFile name="RollingFileWarn" fileName="${baseDir}/warn.log" | ||
32 | + filePattern="${baseDir}/$${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log"> | ||
33 | + <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> | ||
34 | + <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
35 | + <Policies> | ||
36 | + <TimeBasedTriggeringPolicy/> | ||
37 | + <SizeBasedTriggeringPolicy size="100 MB"/> | ||
38 | + </Policies> | ||
39 | + <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --> | ||
40 | + <DefaultRolloverStrategy max="20"/> | ||
41 | + </RollingFile> | ||
42 | + <RollingFile name="RollingFileError" fileName="${baseDir}/error.log" | ||
43 | + filePattern="${baseDir}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log"> | ||
44 | + <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> | ||
45 | + <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/> | ||
46 | + <Policies> | ||
47 | + <TimeBasedTriggeringPolicy/> | ||
48 | + <SizeBasedTriggeringPolicy size="100 MB"/> | ||
49 | + </Policies> | ||
50 | + </RollingFile> | ||
51 | + </appenders> | ||
52 | + <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效--> | ||
53 | + <loggers> | ||
54 | + <!--过滤掉spring和mybatis的一些无用的DEBUG信息--> | ||
55 | + <logger name="org.springframework" level="INFO"></logger> | ||
56 | + <logger name="org.mybatis" level="INFO"></logger> | ||
57 | + <root level="all"> | ||
58 | + <appender-ref ref="Console"/> | ||
59 | +<!-- <appender-ref ref="RollingFileInfo"/>--> | ||
60 | + <appender-ref ref="RollingFileWarn"/> | ||
61 | + <appender-ref ref="RollingFileError"/> | ||
62 | + </root> | ||
63 | + </loggers> | ||
64 | +</configuration> | ||
0 | \ No newline at end of file | 65 | \ No newline at end of file |
src/main/resources/templates/Index.html
0 → 100644
1 | +++ a/src/main/resources/templates/Index.html | ||
1 | +<!DOCTYPE html> | ||
2 | +<html lang="en"> | ||
3 | +<meta charset="UTF-8"> | ||
4 | + | ||
5 | +<body> | ||
6 | + <div> | ||
7 | + <div> | ||
8 | + <input type="text" placeholder="请输入SN号" id="SNContent"/> | ||
9 | + <input type="text" placeholder="请输入项目名称" id="projectName"/> | ||
10 | + </div> | ||
11 | + <button id="add">添加</button> | ||
12 | + </div> | ||
13 | + <br/> | ||
14 | + | ||
15 | + <div> | ||
16 | + <div> | ||
17 | + <input type="text" placeholder="请输入SN号" id="SNContentDelete"/> | ||
18 | + </div> | ||
19 | + <button id="delete">删除</button> | ||
20 | + </div> | ||
21 | + <br/> | ||
22 | + | ||
23 | + <div> | ||
24 | + <button id="show">获取所有</button> | ||
25 | + | ||
26 | + </div> | ||
27 | + <span id="SNShow" style="display: inline-block; | ||
28 | + width: 500px; | ||
29 | + word-break: break-all; | ||
30 | + white-space: normal;"></span> | ||
31 | + | ||
32 | + <script> | ||
33 | + //添加 | ||
34 | + var addButton = document.getElementById("add"); | ||
35 | + addButton.onclick = function () { | ||
36 | + let SNcontent = document.getElementById("SNContent").value.trim(); | ||
37 | + let projectName = document.getElementById("projectName").value.trim(); | ||
38 | + let dateTime = formattedDate().trim(); | ||
39 | + | ||
40 | + //数据判空 | ||
41 | + if (typeof SNcontent === 'undefined' || SNcontent == null || SNcontent === '') { | ||
42 | + alert("请输入SN号") | ||
43 | + return; | ||
44 | + } | ||
45 | + if (typeof projectName === 'undefined' || projectName == null || projectName === '') { | ||
46 | + alert("请输入projectName") | ||
47 | + return; | ||
48 | + } | ||
49 | + | ||
50 | + let SNDto = SNcontent + "##" + projectName + "##" +dateTime; | ||
51 | + //ajax请求提交数据 | ||
52 | + var xhr = new XMLHttpRequest(); | ||
53 | + xhr.open('POST','/add_SN'); | ||
54 | + xhr.setRequestHeader('Content-Type','application/json') | ||
55 | + xhr.send(SNDto); | ||
56 | + xhr.onreadystatechange = function () { | ||
57 | + if (xhr.readyState === XMLHttpRequest.DONE) { | ||
58 | + let responseObject = JSON.parse(xhr.responseText); | ||
59 | + alert(responseObject.message); | ||
60 | + } | ||
61 | + } | ||
62 | + } | ||
63 | + | ||
64 | + //查询 | ||
65 | + var showButton = document.getElementById("show"); | ||
66 | + showButton.onclick = function () { | ||
67 | + //ajax请求获取数据 | ||
68 | + var xhr = new XMLHttpRequest(); | ||
69 | + xhr.open('GET','/get_SNs',true); | ||
70 | + xhr.send(); | ||
71 | + xhr.onreadystatechange = function () { | ||
72 | + | ||
73 | + // if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { | ||
74 | + // var blob = new Blob([this.response], {type: 'application/octet-stream'}); | ||
75 | + // var url = URL.createObjectURL(blob); | ||
76 | + // var a = document.createElement('a'); | ||
77 | + // a.href = url; | ||
78 | + // a.download = 'SNs.txt'; | ||
79 | + // a.target = '_blank'; | ||
80 | + // a.click(); | ||
81 | + // } | ||
82 | + if (xhr.readyState === XMLHttpRequest.DONE) { | ||
83 | + if (xhr.status === 200) { | ||
84 | + let responseObject = JSON.parse(xhr.responseText); | ||
85 | + let SNs = responseObject.data; | ||
86 | + document.getElementById("SNShow").innerText = SNs; | ||
87 | + } else { | ||
88 | + document.getElementById("SNShow").innerText = "出错了!"; | ||
89 | + } | ||
90 | + } | ||
91 | + } | ||
92 | + | ||
93 | + } | ||
94 | + | ||
95 | + //删除 | ||
96 | + var deleteButton = document.getElementById("delete"); | ||
97 | + deleteButton.onclick = function () { | ||
98 | + let SNContentDelete = document.getElementById("SNContentDelete").value.trim(); | ||
99 | + if (typeof SNContentDelete === 'undefined' || SNContentDelete == null || SNContentDelete === '') { | ||
100 | + alert("请输入SN号") | ||
101 | + return; | ||
102 | + } | ||
103 | + | ||
104 | + //ajax请求获取数据 | ||
105 | + var xhr = new XMLHttpRequest(); | ||
106 | + xhr.open('POST','/delete_SN',true); | ||
107 | + xhr.send(SNContentDelete); | ||
108 | + xhr.onreadystatechange = function () { | ||
109 | + if (xhr.readyState === XMLHttpRequest.DONE) { | ||
110 | + let responseObject = JSON.parse(xhr.responseText); | ||
111 | + alert(responseObject.message); | ||
112 | + } | ||
113 | + } | ||
114 | + | ||
115 | + } | ||
116 | + | ||
117 | + | ||
118 | + | ||
119 | + function formattedDate() { | ||
120 | + const date = new Date(); | ||
121 | + const year = date.getFullYear(); | ||
122 | + const month = (date.getMonth() + 1).toString().padStart(2, '0'); | ||
123 | + const day = date.getDate().toString().padStart(2, '0'); | ||
124 | + const hour = date.getHours().toString().padStart(2, '0'); | ||
125 | + const minute = date.getMinutes().toString().padStart(2, '0'); | ||
126 | + const second = date.getSeconds().toString().padStart(2, '0'); | ||
127 | + const formattedDate = `${year}-${month}-${day} ${hour}:${minute}:${second}`; | ||
128 | + return formattedDate; | ||
129 | + } | ||
130 | + | ||
131 | + | ||
132 | + | ||
133 | + | ||
134 | + </script> | ||
135 | + | ||
136 | +</body> | ||
137 | + | ||
138 | + | ||
139 | +</html> | ||
0 | \ No newline at end of file | 140 | \ No newline at end of file |
src/test/java/com/example/demo/SNManageApplicationTest.java
0 → 100644
1 | +++ a/src/test/java/com/example/demo/SNManageApplicationTest.java | ||
1 | +package com.example.demo; | ||
2 | + | ||
3 | +import com.example.demo.service.SNService; | ||
4 | +import org.junit.Test; | ||
5 | +import org.junit.runner.RunWith; | ||
6 | +import org.springframework.beans.factory.annotation.Autowired; | ||
7 | +import org.springframework.beans.factory.annotation.Value; | ||
8 | +import org.springframework.boot.test.context.SpringBootTest; | ||
9 | +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; | ||
10 | +import org.springframework.util.StringUtils; | ||
11 | + | ||
12 | +import java.io.File; | ||
13 | +import java.util.Date; | ||
14 | + | ||
15 | +@RunWith(SpringJUnit4ClassRunner.class) | ||
16 | +@SpringBootTest | ||
17 | +public class SNManageApplicationTest { | ||
18 | + @Autowired | ||
19 | + SNService snService; | ||
20 | + | ||
21 | + @Value("${SN.file.path}") | ||
22 | + String SNFilePath; | ||
23 | + | ||
24 | + @Value("${SN.file.temp.path}") | ||
25 | + String SNTempFilePath; | ||
26 | + | ||
27 | + @Test | ||
28 | + public void test() throws Exception { | ||
29 | + String encryptedSN = "c24x"; | ||
30 | + snService.deleteSN(encryptedSN); | ||
31 | + | ||
32 | + } | ||
33 | +} |