init
This commit is contained in:
66
pom.xml
Normal file
66
pom.xml
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
<?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.2</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.flagnote</groupId>
|
||||||
|
<artifactId>flagnote-service</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>flagnote-service</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>11</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-mongodb</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.7.22</version>
|
||||||
|
</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>
|
||||||
|
<configuration>
|
||||||
|
<excludes>
|
||||||
|
<exclude>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</exclude>
|
||||||
|
</excludes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
16
src/main/java/com/flagnote/note/NoteApplication.java
Normal file
16
src/main/java/com/flagnote/note/NoteApplication.java
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package com.flagnote.note;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAutoConfiguration
|
||||||
|
@RestController
|
||||||
|
public class NoteApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(NoteApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
127
src/main/java/com/flagnote/note/controller/NoteController.java
Normal file
127
src/main/java/com/flagnote/note/controller/NoteController.java
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
package com.flagnote.note.controller;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.HttpHeaders;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RequestPart;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import com.flagnote.note.entity.KeyMeta;
|
||||||
|
import com.flagnote.note.entity.Note;
|
||||||
|
import com.flagnote.note.entity.NoteMeta;
|
||||||
|
import com.flagnote.note.service.NoteService;
|
||||||
|
import com.flagnote.note.utils.BizKeyUtils;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
public class NoteController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NoteService noteService;
|
||||||
|
|
||||||
|
@RequestMapping(value = "/note/keyMeta", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public KeyMeta getKeyMeta() {
|
||||||
|
KeyMeta c = new KeyMeta();
|
||||||
|
String key = BizKeyUtils.getKey();
|
||||||
|
c.setKey(key);
|
||||||
|
c.setCipher(BizKeyUtils.getCipher(key));
|
||||||
|
c.setServerTime(new Date().getTime());
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/note/{key:[abcdefghijkmnopqrstuvwxyz23456789]{16}}/noteMeta", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public NoteMeta getNoteMeta(@PathVariable("key") String key) {
|
||||||
|
NoteMeta meta = new NoteMeta();
|
||||||
|
Note note = noteService.getNote(key);
|
||||||
|
if (null == note) {
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
meta.setServerTime(new Date().getTime());
|
||||||
|
meta.setKey(key);
|
||||||
|
meta.setLock(note.getLock());
|
||||||
|
meta.setMd5(note.getMd5());
|
||||||
|
|
||||||
|
meta.setTtl(note.getTtl());
|
||||||
|
|
||||||
|
return meta;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/note/{key:[abcdefghijkmnopqrstuvwxyz23456789]{16}}", method = RequestMethod.GET, produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
|
||||||
|
public void getNote(@PathVariable("key") String key, HttpServletResponse response) {
|
||||||
|
|
||||||
|
Note note = noteService.getNote(key);
|
||||||
|
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
|
||||||
|
response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + key + "\"");
|
||||||
|
|
||||||
|
if(null==note) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
OutputStream out = null;
|
||||||
|
try {
|
||||||
|
out = response.getOutputStream();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("获取写入流失败", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
out.write(note.getTextBytes());
|
||||||
|
out.flush();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("写入流失败", e);
|
||||||
|
} finally {
|
||||||
|
if (null != out) {
|
||||||
|
try {
|
||||||
|
out.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("关闭流失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/note/{key:[abcdefghijkmnopqrstuvwxyz23456789]{16}}", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
|
||||||
|
public String saveNote(@PathVariable("key") String key, @RequestPart("file") MultipartFile file,
|
||||||
|
@RequestParam("lock") Integer lock, @RequestParam("md5") String md5) throws IOException {
|
||||||
|
Date pushTime = new Date();
|
||||||
|
|
||||||
|
Note note = new Note();
|
||||||
|
note.setKey(key);
|
||||||
|
note.setTextBytes(file.getBytes());
|
||||||
|
note.setLock(lock);
|
||||||
|
note.setMd5(md5);
|
||||||
|
note.setPushTime(pushTime);
|
||||||
|
|
||||||
|
noteService.saveNote(note);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(value = "/note/{key:[abcdefghijkmnopqrstuvwxyz23456789]{16}}/delete", method = RequestMethod.POST, produces = MediaType.TEXT_PLAIN_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
|
||||||
|
public String deleteNote(@PathVariable("key") String key) {
|
||||||
|
noteService.deleteNote(key);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
20
src/main/java/com/flagnote/note/entity/KeyMeta.java
Normal file
20
src/main/java/com/flagnote/note/entity/KeyMeta.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package com.flagnote.note.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class KeyMeta implements Serializable {/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -2816061962747625732L;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String cipher;
|
||||||
|
|
||||||
|
private Long serverTime;
|
||||||
|
|
||||||
|
}
|
||||||
47
src/main/java/com/flagnote/note/entity/Note.java
Normal file
47
src/main/java/com/flagnote/note/entity/Note.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package com.flagnote.note.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Note implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 5301542293133170670L;
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
private String md5;
|
||||||
|
|
||||||
|
private Integer lock;
|
||||||
|
|
||||||
|
private String cipher;
|
||||||
|
|
||||||
|
private Integer state;
|
||||||
|
|
||||||
|
private Date pushTime;
|
||||||
|
|
||||||
|
private Date expireTime;
|
||||||
|
|
||||||
|
private Date retentionTime;
|
||||||
|
|
||||||
|
private byte[] textBytes;
|
||||||
|
|
||||||
|
public Long getTtl() {
|
||||||
|
if (null == pushTime || null == expireTime) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Date now = new Date();
|
||||||
|
return expireTime.getTime() - now.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
28
src/main/java/com/flagnote/note/entity/NoteMeta.java
Normal file
28
src/main/java/com/flagnote/note/entity/NoteMeta.java
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package com.flagnote.note.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class NoteMeta implements Serializable {/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -8234044213813670440L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String cipher;
|
||||||
|
|
||||||
|
private Integer lock;
|
||||||
|
|
||||||
|
private String md5;
|
||||||
|
|
||||||
|
private Long serverTime;
|
||||||
|
|
||||||
|
private Long ttl;
|
||||||
|
}
|
||||||
24
src/main/java/com/flagnote/note/entity/Secret.java
Normal file
24
src/main/java/com/flagnote/note/entity/Secret.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package com.flagnote.note.entity;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Secret implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = -4125184146529253566L;
|
||||||
|
|
||||||
|
private String key;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.flagnote.note.repository;
|
||||||
|
|
||||||
|
import org.springframework.data.mongodb.repository.MongoRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import com.flagnote.note.entity.Note;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface NoteMongoRepository extends MongoRepository<Note, String> {
|
||||||
|
|
||||||
|
}
|
||||||
13
src/main/java/com/flagnote/note/service/NoteService.java
Normal file
13
src/main/java/com/flagnote/note/service/NoteService.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.flagnote.note.service;
|
||||||
|
|
||||||
|
import com.flagnote.note.entity.Note;
|
||||||
|
|
||||||
|
public interface NoteService {
|
||||||
|
|
||||||
|
Note getNote(String key);
|
||||||
|
|
||||||
|
void saveNote(Note note);
|
||||||
|
|
||||||
|
void deleteNote(String key);
|
||||||
|
|
||||||
|
}
|
||||||
70
src/main/java/com/flagnote/note/service/NoteServiceImpl.java
Normal file
70
src/main/java/com/flagnote/note/service/NoteServiceImpl.java
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
package com.flagnote.note.service;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.domain.Example;
|
||||||
|
import org.springframework.data.domain.ExampleMatcher;
|
||||||
|
import org.springframework.data.mongodb.core.query.Criteria;
|
||||||
|
import org.springframework.data.mongodb.core.query.Query;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.flagnote.note.entity.Note;
|
||||||
|
import com.flagnote.note.repository.NoteMongoRepository;
|
||||||
|
import com.flagnote.note.utils.BizKeyUtils;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class NoteServiceImpl implements NoteService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private NoteMongoRepository noteMongoRepository;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Note getNote(String key) {
|
||||||
|
|
||||||
|
String mixKey = BizKeyUtils.mixKey(key);
|
||||||
|
|
||||||
|
Note note = noteMongoRepository.findById(mixKey).orElse(null);
|
||||||
|
|
||||||
|
if (null == note) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note.getState() != 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note.getExpireTime().getTime() <= new Date().getTime()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return note;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void saveNote(Note note) {
|
||||||
|
String mixKey = BizKeyUtils.mixKey(note.getKey());
|
||||||
|
|
||||||
|
note.setId(mixKey);
|
||||||
|
note.setKey(mixKey);
|
||||||
|
|
||||||
|
|
||||||
|
note.setExpireTime(DateUtil.offsetHour(note.getPushTime(), 1));
|
||||||
|
note.setRetentionTime(DateUtil.offsetSecond(note.getPushTime(), 4000 * 3600));
|
||||||
|
|
||||||
|
note.setState(1);
|
||||||
|
|
||||||
|
noteMongoRepository.save(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteNote(String key) {
|
||||||
|
String mixKey = BizKeyUtils.mixKey(key);
|
||||||
|
|
||||||
|
noteMongoRepository.deleteById(mixKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
95
src/main/java/com/flagnote/note/utils/BizKeyUtils.java
Normal file
95
src/main/java/com/flagnote/note/utils/BizKeyUtils.java
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
package com.flagnote.note.utils;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
|
public class BizKeyUtils {
|
||||||
|
|
||||||
|
public static final String MIX_STRING = "6v8muhqp8ta45ncsyi8y";
|
||||||
|
|
||||||
|
public static final String RANGE_STRING = "abcdefhikmnopqstuvwxyz23456789";
|
||||||
|
|
||||||
|
public static String getKey() {
|
||||||
|
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
|
||||||
|
for (int i = 0; i < 13; i++) {
|
||||||
|
sb.append(RANGE_STRING.charAt(RandomUtils.nextInt(30)));
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append(getFilteredKey(md5(sb.toString() + MIX_STRING + getPrefixTime())));
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getFilteredKey(String key) {
|
||||||
|
String result = "";
|
||||||
|
for (int i = 0; i < key.length(); i++) {
|
||||||
|
String ts = String.valueOf(key.charAt(i));
|
||||||
|
if (RANGE_STRING.indexOf(ts) >= 0) {
|
||||||
|
result += ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.length() == 3) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1; i < 3; i++) {
|
||||||
|
result += "x";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Boolean validateKey(String key) {
|
||||||
|
String oKey = key.substring(0, 13);
|
||||||
|
|
||||||
|
String cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + getPrefixTime()));
|
||||||
|
|
||||||
|
if (cKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + (getPrefixTime() - 1)));
|
||||||
|
|
||||||
|
if (cKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cKey = oKey + getFilteredKey(md5(oKey + MIX_STRING + (getPrefixTime() + 1)));
|
||||||
|
|
||||||
|
if (cKey.equals(key)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String mixKey(String key) {
|
||||||
|
return md5(key + md5(MIX_STRING + key));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String md5(String text) {
|
||||||
|
try {
|
||||||
|
return DigestUtils.md5DigestAsHex(text.getBytes("UTF-8"));
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
throw new RuntimeException("无法生成MD5");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer getPrefixTime() {
|
||||||
|
return Integer.parseInt(String.valueOf(new Date().getTime()).substring(0, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getCipher(String key) {
|
||||||
|
return md5(key + MIX_STRING + key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getSecretKey(String key, String password) {
|
||||||
|
return md5(key + md5(MIX_STRING + password));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
112
src/main/java/com/flagnote/note/utils/JsonUtils.java
Normal file
112
src/main/java/com/flagnote/note/utils/JsonUtils.java
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
package com.flagnote.note.utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class JsonUtils {
|
||||||
|
|
||||||
|
private static ObjectMapper om = new ObjectMapper();
|
||||||
|
|
||||||
|
static {
|
||||||
|
|
||||||
|
// 对象的所有字段全部列入,还是其他的选项,可以忽略null等
|
||||||
|
om.setSerializationInclusion(Include.ALWAYS);
|
||||||
|
// 设置Date类型的序列化及反序列化格式
|
||||||
|
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
||||||
|
|
||||||
|
// 忽略空Bean转json的错误
|
||||||
|
om.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
||||||
|
// 忽略未知属性,防止json字符串中存在,java对象中不存在对应属性的情况出现错误
|
||||||
|
om.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||||
|
|
||||||
|
// 注册一个时间序列化及反序列化的处理模块,用于解决jdk8中localDateTime等的序列化问题
|
||||||
|
om.registerModule(new JavaTimeModule());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象 => json字符串
|
||||||
|
*
|
||||||
|
* @param obj 源对象
|
||||||
|
*/
|
||||||
|
public static <T> String toJson(T obj) {
|
||||||
|
|
||||||
|
String json = null;
|
||||||
|
if (obj != null) {
|
||||||
|
try {
|
||||||
|
json = om.writeValueAsString(obj);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
log.warn(e.getMessage(), e);
|
||||||
|
throw new IllegalArgumentException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json字符串 => 对象
|
||||||
|
*
|
||||||
|
* @param json 源json串
|
||||||
|
* @param clazz 对象类
|
||||||
|
* @param <T> 泛型
|
||||||
|
*/
|
||||||
|
public static <T> T parse(String json, Class<T> clazz) {
|
||||||
|
|
||||||
|
return parse(json, clazz, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json字符串 => 对象
|
||||||
|
*
|
||||||
|
* @param json 源json串
|
||||||
|
* @param type 对象类型
|
||||||
|
* @param <T> 泛型
|
||||||
|
*/
|
||||||
|
public static <T> T parse(String json, TypeReference<T> type) {
|
||||||
|
|
||||||
|
return parse(json, null, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* json => 对象处理方法
|
||||||
|
* <br>
|
||||||
|
* 参数clazz和type必须一个为null,另一个不为null
|
||||||
|
* <br>
|
||||||
|
* 此方法不对外暴露,访问权限为private
|
||||||
|
*
|
||||||
|
* @param json 源json串
|
||||||
|
* @param clazz 对象类
|
||||||
|
* @param type 对象类型
|
||||||
|
* @param <T> 泛型
|
||||||
|
*/
|
||||||
|
private static <T> T parse(String json, Class<T> clazz, TypeReference<T> type) {
|
||||||
|
|
||||||
|
T obj = null;
|
||||||
|
if (StringUtils.hasLength(json)) {
|
||||||
|
try {
|
||||||
|
if (clazz != null) {
|
||||||
|
obj = om.readValue(json, clazz);
|
||||||
|
} else {
|
||||||
|
obj = om.readValue(json, type);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn(e.getMessage(), e);
|
||||||
|
throw new IllegalArgumentException(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/main/java/com/flagnote/note/utils/RandomUtils.java
Normal file
15
src/main/java/com/flagnote/note/utils/RandomUtils.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.flagnote.note.utils;
|
||||||
|
|
||||||
|
import java.util.concurrent.ThreadLocalRandom;
|
||||||
|
|
||||||
|
public class RandomUtils {
|
||||||
|
|
||||||
|
|
||||||
|
public static ThreadLocalRandom getRandom() {
|
||||||
|
return ThreadLocalRandom.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Integer nextInt(Integer num) {
|
||||||
|
return getRandom().nextInt(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/main/resources/application.yml
Normal file
16
src/main/resources/application.yml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
server:
|
||||||
|
port: 3333
|
||||||
|
spring:
|
||||||
|
codec:
|
||||||
|
max-in-memory-size: 128MB
|
||||||
|
data:
|
||||||
|
mongodb:
|
||||||
|
authentication-database: flagnote
|
||||||
|
database: flagnote
|
||||||
|
host: service.flagnote.com
|
||||||
|
port: 37017
|
||||||
|
username: flagnote
|
||||||
|
password: flagnote1qazx
|
||||||
|
autoConnectRetry: true
|
||||||
|
socketKeepAlive: true
|
||||||
|
socketTimeout: 1000
|
||||||
13
src/test/java/com/flagnote/note/NoteApplicationTests.java
Normal file
13
src/test/java/com/flagnote/note/NoteApplicationTests.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package com.flagnote.note;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class NoteApplicationTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user