feat:模块名称调整
This commit is contained in:
42
springboot-util/pom.xml
Normal file
42
springboot-util/pom.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.tiesheng</groupId>
|
||||
<artifactId>springboot-parent</artifactId>
|
||||
<version>0.0.18</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>springboot-util</artifactId>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
<version>5.8.11</version>
|
||||
</dependency>
|
||||
|
||||
<!-- fastJson -->
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.78</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.tiesheng.util;
|
||||
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.crypto.SecureUtil;
|
||||
import com.tiesheng.util.exception.ApiException;
|
||||
|
||||
public class PasswordUtils {
|
||||
|
||||
private static final int PREFIX_SIZE = 8;
|
||||
|
||||
|
||||
/**
|
||||
* 获取加密密码
|
||||
*
|
||||
* @param password
|
||||
* @return
|
||||
*/
|
||||
public static String buildPassword(String password) {
|
||||
String prefix = RandomUtil.randomString(PREFIX_SIZE);
|
||||
return prefix + SecureUtil.sha1(password);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 验证密码
|
||||
*
|
||||
* @param userInput
|
||||
* @param encrypted
|
||||
* @return
|
||||
*/
|
||||
public static void verifyPassword(String userInput, String encrypted) {
|
||||
String userEncrypted = buildPassword(userInput);
|
||||
|
||||
userEncrypted = StrUtil.subSuf(userEncrypted, PREFIX_SIZE);
|
||||
encrypted = StrUtil.subSuf(encrypted, PREFIX_SIZE);
|
||||
|
||||
if (!StrUtil.equals(userEncrypted, encrypted)) {
|
||||
throw new ApiException("账号或密码错误");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.tiesheng.util;
|
||||
|
||||
import cn.hutool.extra.servlet.ServletUtil;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletRequestAttributes;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
public class ServletKit extends ServletUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前线程的request
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static HttpServletRequest getRequest() {
|
||||
ServletRequestAttributes attributes = (ServletRequestAttributes)
|
||||
RequestContextHolder.getRequestAttributes();
|
||||
return attributes.getRequest();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.tiesheng.util;
|
||||
|
||||
import cn.hutool.cache.CacheUtil;
|
||||
import cn.hutool.cache.impl.TimedCache;
|
||||
|
||||
public class TimedCacheHelper {
|
||||
|
||||
private static volatile TimedCache<String, String> timedCache;
|
||||
|
||||
/**
|
||||
* 获取一个默认2分钟过期的缓存
|
||||
*/
|
||||
public static TimedCache<String, String> getTimedCache() {
|
||||
if (timedCache == null) {
|
||||
synchronized (TimedCacheHelper.class) {
|
||||
if (timedCache == null) {
|
||||
timedCache = CacheUtil.newTimedCache(2 * 60 * 1000);
|
||||
timedCache.schedulePrune(1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return timedCache;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.tiesheng.util;
|
||||
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@ComponentScan({
|
||||
"com.tiesheng.util.**.*",
|
||||
})
|
||||
@ComponentScan("cn.hutool.extra.spring")
|
||||
public class UtilAutoConfigurer {
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.tiesheng.util.config;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.hutool.log.LogFactory;
|
||||
import com.tiesheng.util.exception.ApiException;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "tiesheng.global")
|
||||
public class GlobalConfig {
|
||||
|
||||
private String host;
|
||||
private String service;
|
||||
private String version;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 逻辑方法
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getContextPath() {
|
||||
String context = SpringUtil.getProperty("server.servlet.context-path");
|
||||
if (StrUtil.isEmpty(context)) {
|
||||
context = "";
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 构建完整的路径
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
public String buildPath(String path) {
|
||||
if (StrUtil.isEmpty(path)) {
|
||||
path = "";
|
||||
}
|
||||
if (!StrUtil.isEmpty(host) && !StrUtil.startWith(path, "http")) {
|
||||
path = host + getContextPath() + path;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 重定向
|
||||
*
|
||||
* @param htmlDir 资源目录
|
||||
* @param route
|
||||
*/
|
||||
public void redirect(String htmlDir, String route, HttpServletResponse response) {
|
||||
PathMatchingResourcePatternResolver patternResolver = new PathMatchingResourcePatternResolver();
|
||||
try {
|
||||
Resource[] resources = patternResolver.getResources(String.format("classpath*:static/%s/*/index.html", htmlDir));
|
||||
if (resources.length == 0) {
|
||||
throw new ApiException("无法重定向,请检查资源");
|
||||
}
|
||||
String filename = resources[resources.length - 1].getURL().getPath();
|
||||
filename = FileUtil.normalize(filename);
|
||||
String path = buildPath(String.format("/%s%s#%s", htmlDir, StrUtil.subAfter(filename, htmlDir, true), route));
|
||||
response.sendRedirect(path);
|
||||
} catch (IOException e) {
|
||||
LogFactory.get().info(e);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public void setHost(String host) {
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
public String getService() {
|
||||
return service;
|
||||
}
|
||||
|
||||
public void setService(String service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.tiesheng.util.config;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.log.LogFactory;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.RandomAccessFile;
|
||||
|
||||
/**
|
||||
* @author hao
|
||||
*/
|
||||
@Configuration
|
||||
@ConfigurationProperties(prefix = "tiesheng.ip2region")
|
||||
public class Ip2regionConfig {
|
||||
|
||||
private String dbUrl = "http://git.kepai365.com/zeng_wenhao/kepai-repo/raw/master/ipdb/ip2region.db";
|
||||
private String dbPath = System.getProperty("user.dir") + "/ipdb/ip2region.db";
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 逻辑方法
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@PostConstruct
|
||||
public void downloadDbFile() {
|
||||
if (!FileUtil.exist(dbPath)) {
|
||||
LogFactory.get().info("download ip2region file start");
|
||||
HttpUtil.downloadFile(dbUrl, dbPath);
|
||||
LogFactory.get().info("download ip2region file finish");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取db文件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public RandomAccessFile getDbAccessFile() throws FileNotFoundException {
|
||||
if (!FileUtil.exist(dbPath)) {
|
||||
downloadDbFile();
|
||||
}
|
||||
return new RandomAccessFile(dbPath, "r");
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getDbUrl() {
|
||||
return dbUrl;
|
||||
}
|
||||
|
||||
public void setDbUrl(String dbUrl) {
|
||||
this.dbUrl = dbUrl;
|
||||
}
|
||||
|
||||
public String getDbPath() {
|
||||
return dbPath;
|
||||
}
|
||||
|
||||
public void setDbPath(String dbPath) {
|
||||
this.dbPath = dbPath;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.tiesheng.util.exception;
|
||||
|
||||
import com.tiesheng.util.pojos.ApiResp;
|
||||
|
||||
/**
|
||||
* @author huang
|
||||
* @ProjectName health
|
||||
* @Copyright Hangzhou ShuoChuang Technology Co.,Ltd All Right Reserved
|
||||
* @Description 这里是对文件的描述
|
||||
* @data 2017/8/8
|
||||
* @note 这里写文件的详细功能和改动
|
||||
* @note
|
||||
*/
|
||||
public class ApiException extends RuntimeException {
|
||||
|
||||
private ApiResp<String> apiResp;
|
||||
|
||||
public ApiException(String message) {
|
||||
super(message);
|
||||
this.apiResp = ApiResp.respCust(102, message);
|
||||
}
|
||||
|
||||
public ApiException(int code, String message) {
|
||||
this.apiResp = ApiResp.respCust(code, message);
|
||||
}
|
||||
|
||||
public ApiException(ApiResp<String> apiResp) {
|
||||
this.apiResp = apiResp;
|
||||
}
|
||||
|
||||
public ApiResp<String> getApiResp() {
|
||||
return apiResp;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.tiesheng.util.exception;
|
||||
|
||||
/**
|
||||
* 异常
|
||||
*
|
||||
* @author hao
|
||||
*/
|
||||
|
||||
public enum ApiRespEnum {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 200
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OK(200, "请求成功"),
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 400
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BadRequest(400, ""),
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// 500
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ServerError(500, "服务器忙,请稍后再试"),
|
||||
|
||||
;
|
||||
|
||||
private int code;
|
||||
private String message;
|
||||
|
||||
ApiRespEnum(int code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package com.tiesheng.util.ip2region;
|
||||
|
||||
/**
|
||||
* data block class
|
||||
*
|
||||
* @author chenxin<chenxin619315 @ gmail.com>
|
||||
*/
|
||||
public class DataBlock {
|
||||
/**
|
||||
* city id
|
||||
*/
|
||||
private int cityId;
|
||||
|
||||
/**
|
||||
* region address
|
||||
*/
|
||||
private String region;
|
||||
|
||||
/**
|
||||
* region ptr in the db file
|
||||
*/
|
||||
private int dataPtr;
|
||||
|
||||
/**
|
||||
* construct method
|
||||
*
|
||||
* @param cityId
|
||||
* @param region region string
|
||||
* @param dataPtr data ptr
|
||||
*/
|
||||
public DataBlock(int cityId, String region, int dataPtr) {
|
||||
this.cityId = cityId;
|
||||
this.region = region;
|
||||
this.dataPtr = dataPtr;
|
||||
}
|
||||
|
||||
public DataBlock(int cityId, String region) {
|
||||
this(cityId, region, 0);
|
||||
}
|
||||
|
||||
public int getCityId() {
|
||||
return cityId;
|
||||
}
|
||||
|
||||
public DataBlock setCityId(int cityId) {
|
||||
this.cityId = cityId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public DataBlock setRegion(String region) {
|
||||
this.region = region;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getDataPtr() {
|
||||
return dataPtr;
|
||||
}
|
||||
|
||||
public DataBlock setDataPtr(int dataPtr) {
|
||||
this.dataPtr = dataPtr;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(cityId).append('|').append(region).append('|').append(dataPtr);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.tiesheng.util.ip2region;
|
||||
|
||||
/**
|
||||
* database configuration class
|
||||
*
|
||||
* @author chenxin<chenxin619315 @ gmail.com>
|
||||
*/
|
||||
public class DbConfig {
|
||||
/**
|
||||
* total header data block size
|
||||
*/
|
||||
private int totalHeaderSize;
|
||||
|
||||
/**
|
||||
* max index data block size
|
||||
* u should always choice the fastest read block size
|
||||
*/
|
||||
private int indexBlockSize;
|
||||
|
||||
/**
|
||||
* construct method
|
||||
*
|
||||
* @param totalHeaderSize
|
||||
*/
|
||||
public DbConfig(int totalHeaderSize) {
|
||||
this.totalHeaderSize = totalHeaderSize;
|
||||
this.indexBlockSize = 8192;
|
||||
}
|
||||
|
||||
public DbConfig() {
|
||||
this(8 * 2048);
|
||||
}
|
||||
|
||||
public int getTotalHeaderSize() {
|
||||
return totalHeaderSize;
|
||||
}
|
||||
|
||||
public DbConfig setTotalHeaderSize(int totalHeaderSize) {
|
||||
this.totalHeaderSize = totalHeaderSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getIndexBlockSize() {
|
||||
return indexBlockSize;
|
||||
}
|
||||
|
||||
public DbConfig setIndexBlockSize(int dataBlockSize) {
|
||||
this.indexBlockSize = dataBlockSize;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
package com.tiesheng.util.ip2region;
|
||||
|
||||
/**
|
||||
* item index class
|
||||
*
|
||||
* @author chenxin<chenxin619315 @ gmail.com>
|
||||
*/
|
||||
public class IndexBlock {
|
||||
|
||||
private static int LENGTH = 12;
|
||||
|
||||
/**
|
||||
* start ip address
|
||||
*/
|
||||
private long startIp;
|
||||
|
||||
/**
|
||||
* end ip address
|
||||
*/
|
||||
private long endIp;
|
||||
|
||||
/**
|
||||
* data ptr and data length
|
||||
*/
|
||||
private int dataPtr;
|
||||
|
||||
/**
|
||||
* data length
|
||||
*/
|
||||
private int dataLen;
|
||||
|
||||
public IndexBlock(long startIp, long endIp, int dataPtr, int dataLen) {
|
||||
this.startIp = startIp;
|
||||
this.endIp = endIp;
|
||||
this.dataPtr = dataPtr;
|
||||
this.dataLen = dataLen;
|
||||
}
|
||||
|
||||
public static int getIndexBlockLength() {
|
||||
return LENGTH;
|
||||
}
|
||||
|
||||
public long getStartIp() {
|
||||
return startIp;
|
||||
}
|
||||
|
||||
public IndexBlock setStartIp(long startIp) {
|
||||
this.startIp = startIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getEndIp() {
|
||||
return endIp;
|
||||
}
|
||||
|
||||
public IndexBlock setEndIp(long endIp) {
|
||||
this.endIp = endIp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getDataPtr() {
|
||||
return dataPtr;
|
||||
}
|
||||
|
||||
public IndexBlock setDataPtr(int dataPtr) {
|
||||
this.dataPtr = dataPtr;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getDataLen() {
|
||||
return dataLen;
|
||||
}
|
||||
|
||||
public IndexBlock setDataLen(int dataLen) {
|
||||
this.dataLen = dataLen;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the bytes for storage
|
||||
*
|
||||
* @return byte[]
|
||||
*/
|
||||
public byte[] getBytes() {
|
||||
/*
|
||||
* +------------+-----------+-----------+
|
||||
* | 4bytes | 4bytes | 4bytes |
|
||||
* +------------+-----------+-----------+
|
||||
* start ip end ip data ptr + len
|
||||
*/
|
||||
byte[] b = new byte[12];
|
||||
|
||||
IpUtil.writeIntLong(b, 0, startIp); //start ip
|
||||
IpUtil.writeIntLong(b, 4, endIp); //end ip
|
||||
|
||||
//write the data ptr and the length
|
||||
long mix = dataPtr | ((dataLen << 24) & 0xFF000000L);
|
||||
IpUtil.writeIntLong(b, 8, mix);
|
||||
|
||||
return b;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,416 @@
|
||||
package com.tiesheng.util.ip2region;
|
||||
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import com.tiesheng.util.config.Ip2regionConfig;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* ip db searcher class (Not thread safe)
|
||||
*
|
||||
* @author chenxin<chenxin619315 @ gmail.com>
|
||||
*/
|
||||
public class Ip2Region {
|
||||
|
||||
|
||||
private static Ip2Region ip2Region;
|
||||
/**
|
||||
* db config
|
||||
*/
|
||||
private final DbConfig dbConfig;
|
||||
/**
|
||||
* db file access handler
|
||||
*/
|
||||
private RandomAccessFile raf = null;
|
||||
/**
|
||||
* header blocks buffer
|
||||
*/
|
||||
private long[] headerSip = null;
|
||||
private int[] headerPtr = null;
|
||||
private int headerLength;
|
||||
/**
|
||||
* super blocks info
|
||||
*/
|
||||
private long firstIndexPtr = 0;
|
||||
private long lastIndexPtr = 0;
|
||||
private int totalIndexBlocks = 0;
|
||||
/**
|
||||
* for memory mode
|
||||
* the original db binary string
|
||||
*/
|
||||
private byte[] dbBinStr = null;
|
||||
|
||||
/**
|
||||
* construct class
|
||||
*/
|
||||
public Ip2Region() {
|
||||
this.dbConfig = new DbConfig();
|
||||
try {
|
||||
Ip2regionConfig ip2regionConfig = SpringUtil.getBean(Ip2regionConfig.class);
|
||||
raf = ip2regionConfig.getDbAccessFile();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单例
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static Ip2Region getInstance() {
|
||||
if (ip2Region == null) {
|
||||
synchronized (Ip2Region.class) {
|
||||
if (ip2Region == null) {
|
||||
ip2Region = new Ip2Region();
|
||||
}
|
||||
}
|
||||
}
|
||||
return ip2Region;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region with an int ip address with memory binary search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock memorySearch(long ip) throws IOException {
|
||||
int blen = IndexBlock.getIndexBlockLength();
|
||||
if (dbBinStr == null) {
|
||||
dbBinStr = new byte[(int) raf.length()];
|
||||
raf.seek(0L);
|
||||
raf.readFully(dbBinStr, 0, dbBinStr.length);
|
||||
|
||||
//initialize the global vars
|
||||
firstIndexPtr = IpUtil.getIntLong(dbBinStr, 0);
|
||||
lastIndexPtr = IpUtil.getIntLong(dbBinStr, 4);
|
||||
totalIndexBlocks = (int) ((lastIndexPtr - firstIndexPtr) / blen) + 1;
|
||||
}
|
||||
|
||||
//search the index blocks to define the data
|
||||
int l = 0, h = totalIndexBlocks;
|
||||
long sip, eip, dataptr = 0;
|
||||
while (l <= h) {
|
||||
int m = (l + h) >> 1;
|
||||
int p = (int) (firstIndexPtr + m * blen);
|
||||
|
||||
sip = IpUtil.getIntLong(dbBinStr, p);
|
||||
if (ip < sip) {
|
||||
h = m - 1;
|
||||
} else {
|
||||
eip = IpUtil.getIntLong(dbBinStr, p + 4);
|
||||
if (ip > eip) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
dataptr = IpUtil.getIntLong(dbBinStr, p + 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//not matched
|
||||
if (dataptr == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//get the data
|
||||
int dataLen = (int) ((dataptr >> 24) & 0xFF);
|
||||
int dataPtr = (int) ((dataptr & 0x00FFFFFF));
|
||||
int cityId = (int) IpUtil.getIntLong(dbBinStr, dataPtr);
|
||||
String region = new String(dbBinStr, dataPtr + 4, dataLen - 4, StandardCharsets.UTF_8);
|
||||
|
||||
return new DataBlock(cityId, region, dataPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region throught the ip address with memory binary search algorithm
|
||||
*
|
||||
* @return DataBlock
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock memorySearch() throws IOException {
|
||||
return memorySearch(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region throught the ip address with memory binary search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @return DataBlock
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock memorySearch(String ip) throws IOException {
|
||||
return memorySearch(IpUtil.ip2long(ip));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get by index ptr
|
||||
*
|
||||
* @param ptr
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock getByIndexPtr(long ptr) throws IOException {
|
||||
raf.seek(ptr);
|
||||
byte[] buffer = new byte[12];
|
||||
raf.readFully(buffer, 0, buffer.length);
|
||||
long extra = IpUtil.getIntLong(buffer, 8);
|
||||
|
||||
int dataLen = (int) ((extra >> 24) & 0xFF);
|
||||
int dataPtr = (int) ((extra & 0x00FFFFFF));
|
||||
|
||||
raf.seek(dataPtr);
|
||||
byte[] data = new byte[dataLen];
|
||||
raf.readFully(data, 0, data.length);
|
||||
|
||||
int cityId = (int) IpUtil.getIntLong(data, 0);
|
||||
String region = new String(data, 4, data.length - 4, StandardCharsets.UTF_8);
|
||||
|
||||
return new DataBlock(cityId, region, dataPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region with an int ip address with b-tree algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock btreeSearch(long ip) throws IOException {
|
||||
//check and load the header
|
||||
if (headerSip == null) {
|
||||
raf.seek(8L);
|
||||
byte[] b = new byte[dbConfig.getTotalHeaderSize()];
|
||||
raf.readFully(b, 0, b.length);
|
||||
|
||||
//fill the header
|
||||
int len = b.length >> 3, idx = 0;
|
||||
headerSip = new long[len];
|
||||
headerPtr = new int[len];
|
||||
long startIp, dataPtr;
|
||||
for (int i = 0; i < b.length; i += 8) {
|
||||
startIp = IpUtil.getIntLong(b, i);
|
||||
dataPtr = IpUtil.getIntLong(b, i + 4);
|
||||
if (dataPtr == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
headerSip[idx] = startIp;
|
||||
headerPtr[idx] = (int) dataPtr;
|
||||
idx++;
|
||||
}
|
||||
|
||||
headerLength = idx;
|
||||
}
|
||||
|
||||
//1. define the index block with the binary search
|
||||
if (ip == headerSip[0]) {
|
||||
return getByIndexPtr(headerPtr[0]);
|
||||
} else if (ip == headerSip[headerLength - 1]) {
|
||||
return getByIndexPtr(headerPtr[headerLength - 1]);
|
||||
}
|
||||
|
||||
int l = 0, h = headerLength, sptr = 0, eptr = 0;
|
||||
while (l <= h) {
|
||||
int m = (l + h) >> 1;
|
||||
|
||||
//perfetc matched, just return it
|
||||
if (ip == headerSip[m]) {
|
||||
if (m > 0) {
|
||||
sptr = headerPtr[m - 1];
|
||||
eptr = headerPtr[m];
|
||||
} else {
|
||||
sptr = headerPtr[m];
|
||||
eptr = headerPtr[m + 1];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//less then the middle value
|
||||
if (ip < headerSip[m]) {
|
||||
if (m == 0) {
|
||||
sptr = headerPtr[m];
|
||||
eptr = headerPtr[m + 1];
|
||||
break;
|
||||
} else if (ip > headerSip[m - 1]) {
|
||||
sptr = headerPtr[m - 1];
|
||||
eptr = headerPtr[m];
|
||||
break;
|
||||
}
|
||||
h = m - 1;
|
||||
} else {
|
||||
if (m == headerLength - 1) {
|
||||
sptr = headerPtr[m - 1];
|
||||
eptr = headerPtr[m];
|
||||
break;
|
||||
} else if (ip <= headerSip[m + 1]) {
|
||||
sptr = headerPtr[m];
|
||||
eptr = headerPtr[m + 1];
|
||||
break;
|
||||
}
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
//match nothing just stop it
|
||||
if (sptr == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//2. search the index blocks to define the data
|
||||
int blockLen = eptr - sptr, blen = IndexBlock.getIndexBlockLength();
|
||||
//include the right border block
|
||||
byte[] iBuffer = new byte[blockLen + blen];
|
||||
raf.seek(sptr);
|
||||
raf.readFully(iBuffer, 0, iBuffer.length);
|
||||
|
||||
l = 0;
|
||||
h = blockLen / blen;
|
||||
long sip, eip, dataptr = 0;
|
||||
while (l <= h) {
|
||||
int m = (l + h) >> 1;
|
||||
int p = m * blen;
|
||||
sip = IpUtil.getIntLong(iBuffer, p);
|
||||
if (ip < sip) {
|
||||
h = m - 1;
|
||||
} else {
|
||||
eip = IpUtil.getIntLong(iBuffer, p + 4);
|
||||
if (ip > eip) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
dataptr = IpUtil.getIntLong(iBuffer, p + 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//not matched
|
||||
if (dataptr == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//3. get the data
|
||||
int dataLen = (int) ((dataptr >> 24) & 0xFF);
|
||||
int dataPtr = (int) ((dataptr & 0x00FFFFFF));
|
||||
|
||||
raf.seek(dataPtr);
|
||||
byte[] data = new byte[dataLen];
|
||||
raf.readFully(data, 0, data.length);
|
||||
|
||||
int cityId = (int) IpUtil.getIntLong(data, 0);
|
||||
String region = new String(data, 4, data.length - 4, StandardCharsets.UTF_8);
|
||||
|
||||
return new DataBlock(cityId, region, dataPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region throught the ip address with b-tree search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @return DataBlock
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock btreeSearch(String ip) {
|
||||
try {
|
||||
return btreeSearch(IpUtil.ip2long(ip));
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
return new DataBlock(0, "未知IP");
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region with a int ip address with binary search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock binarySearch(long ip) throws IOException {
|
||||
int blen = IndexBlock.getIndexBlockLength();
|
||||
if (totalIndexBlocks == 0) {
|
||||
raf.seek(0L);
|
||||
byte[] superBytes = new byte[8];
|
||||
raf.readFully(superBytes, 0, superBytes.length);
|
||||
//initialize the global vars
|
||||
firstIndexPtr = IpUtil.getIntLong(superBytes, 0);
|
||||
lastIndexPtr = IpUtil.getIntLong(superBytes, 4);
|
||||
totalIndexBlocks = (int) ((lastIndexPtr - firstIndexPtr) / blen) + 1;
|
||||
}
|
||||
|
||||
//search the index blocks to define the data
|
||||
int l = 0, h = totalIndexBlocks;
|
||||
byte[] buffer = new byte[blen];
|
||||
long sip, eip, dataptr = 0;
|
||||
while (l <= h) {
|
||||
int m = (l + h) >> 1;
|
||||
raf.seek(firstIndexPtr + m * blen);
|
||||
raf.readFully(buffer, 0, buffer.length);
|
||||
sip = IpUtil.getIntLong(buffer, 0);
|
||||
if (ip < sip) {
|
||||
h = m - 1;
|
||||
} else {
|
||||
eip = IpUtil.getIntLong(buffer, 4);
|
||||
if (ip > eip) {
|
||||
l = m + 1;
|
||||
} else {
|
||||
dataptr = IpUtil.getIntLong(buffer, 8);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//not matched
|
||||
if (dataptr == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//get the data
|
||||
int dataLen = (int) ((dataptr >> 24) & 0xFF);
|
||||
int dataPtr = (int) ((dataptr & 0x00FFFFFF));
|
||||
|
||||
raf.seek(dataPtr);
|
||||
byte[] data = new byte[dataLen];
|
||||
raf.readFully(data, 0, data.length);
|
||||
|
||||
int cityId = (int) IpUtil.getIntLong(data, 0);
|
||||
String region = new String(data, 4, data.length - 4, StandardCharsets.UTF_8);
|
||||
|
||||
return new DataBlock(cityId, region, dataPtr);
|
||||
}
|
||||
|
||||
/**
|
||||
* get the region throught the ip address with binary search algorithm
|
||||
*
|
||||
* @param ip
|
||||
* @return DataBlock
|
||||
* @throws IOException
|
||||
*/
|
||||
public DataBlock binarySearch(String ip) throws IOException {
|
||||
return binarySearch(IpUtil.ip2long(ip));
|
||||
}
|
||||
|
||||
/**
|
||||
* get the db config
|
||||
*
|
||||
* @return DbConfig
|
||||
*/
|
||||
public DbConfig getDbConfig() {
|
||||
return dbConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* close the db
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public void close() throws IOException {
|
||||
headerSip = null;
|
||||
headerPtr = null;
|
||||
dbBinStr = null;
|
||||
if (raf != null) {
|
||||
raf.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
package com.tiesheng.util.ip2region;
|
||||
|
||||
/**
|
||||
* util class
|
||||
*
|
||||
* @author chenxin<chenxin619315 @ gmail.com>
|
||||
*/
|
||||
public class IpUtil {
|
||||
/**
|
||||
* write specfield bytes to a byte array start from offset
|
||||
*
|
||||
* @param b
|
||||
* @param offset
|
||||
* @param v
|
||||
* @param bytes
|
||||
*/
|
||||
public static void write(byte[] b, int offset, long v, int bytes) {
|
||||
for (int i = 0; i < bytes; i++) {
|
||||
b[offset++] = (byte) ((v >>> (8 * i)) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* write a int to a byte array
|
||||
*
|
||||
* @param b
|
||||
* @param offset
|
||||
* @param v
|
||||
*/
|
||||
public static void writeIntLong(byte[] b, int offset, long v) {
|
||||
b[offset++] = (byte) ((v >> 0) & 0xFF);
|
||||
b[offset++] = (byte) ((v >> 8) & 0xFF);
|
||||
b[offset++] = (byte) ((v >> 16) & 0xFF);
|
||||
b[offset] = (byte) ((v >> 24) & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a int from a byte array start from the specifiled offset
|
||||
*
|
||||
* @param b
|
||||
* @param offset
|
||||
*/
|
||||
public static long getIntLong(byte[] b, int offset) {
|
||||
return (
|
||||
((b[offset++] & 0x000000FFL)) |
|
||||
((b[offset++] << 8) & 0x0000FF00L) |
|
||||
((b[offset++] << 16) & 0x00FF0000L) |
|
||||
((b[offset] << 24) & 0xFF000000L)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* get a int from a byte array start from the specifield offset
|
||||
*
|
||||
* @param b
|
||||
* @param offset
|
||||
*/
|
||||
public static int getInt3(byte[] b, int offset) {
|
||||
return (
|
||||
(b[offset++] & 0x000000FF) |
|
||||
(b[offset++] & 0x0000FF00) |
|
||||
(b[offset] & 0x00FF0000)
|
||||
);
|
||||
}
|
||||
|
||||
public static int getInt2(byte[] b, int offset) {
|
||||
return (
|
||||
(b[offset++] & 0x000000FF) |
|
||||
(b[offset] & 0x0000FF00)
|
||||
);
|
||||
}
|
||||
|
||||
public static int getInt1(byte[] b, int offset) {
|
||||
return (
|
||||
(b[offset] & 0x000000FF)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* string ip to long ip
|
||||
*
|
||||
* @param ip
|
||||
* @return long
|
||||
*/
|
||||
public static long ip2long(String ip) {
|
||||
String[] p = ip.split("\\.");
|
||||
if (p.length != 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int p1 = ((Integer.valueOf(p[0]) << 24) & 0xFF000000);
|
||||
int p2 = ((Integer.valueOf(p[1]) << 16) & 0x00FF0000);
|
||||
int p3 = ((Integer.valueOf(p[2]) << 8) & 0x0000FF00);
|
||||
int p4 = ((Integer.valueOf(p[3]) << 0) & 0x000000FF);
|
||||
|
||||
return ((p1 | p2 | p3 | p4) & 0xFFFFFFFFL);
|
||||
}
|
||||
|
||||
/**
|
||||
* int to ip string
|
||||
*
|
||||
* @param ip
|
||||
* @return string
|
||||
*/
|
||||
public static String long2ip(long ip) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb
|
||||
.append((ip >> 24) & 0xFF).append('.')
|
||||
.append((ip >> 16) & 0xFF).append('.')
|
||||
.append((ip >> 8) & 0xFF).append('.')
|
||||
.append((ip >> 0) & 0xFF);
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.tiesheng.util.pojos;
|
||||
|
||||
import com.tiesheng.util.exception.ApiRespEnum;
|
||||
|
||||
/**
|
||||
* @author huang
|
||||
* @ProjectName health
|
||||
* @Copyright Hangzhou ShuoChuang Technology Co.,Ltd All Right Reserved
|
||||
* @Description 这里是对文件的描述
|
||||
* @data 2017/9/4
|
||||
* @note 这里写文件的详细功能和改动
|
||||
* @note
|
||||
*/
|
||||
public class ApiResp<T> {
|
||||
|
||||
public static int CODE_OK = 200;
|
||||
|
||||
private int code;
|
||||
private String message;
|
||||
private Throwable exception;
|
||||
private T data;
|
||||
private long recordsTotal = 0;
|
||||
private boolean encrypt = false;
|
||||
|
||||
/**
|
||||
* 请求成功
|
||||
*
|
||||
* @param data
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respOK(T data) {
|
||||
ApiRespEnum okResp = ApiRespEnum.OK;
|
||||
ApiResp<T> result = new ApiResp<>();
|
||||
result.code = okResp.getCode();
|
||||
result.message = okResp.getMessage();
|
||||
result.data = data;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 请求成功,返回总条数
|
||||
*
|
||||
* @param data
|
||||
* @param recordsTotal
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respOK(T data, long recordsTotal) {
|
||||
ApiRespEnum okResp = ApiRespEnum.OK;
|
||||
ApiResp<T> result = new ApiResp<>();
|
||||
result.code = okResp.getCode();
|
||||
result.message = okResp.getMessage();
|
||||
result.data = data;
|
||||
result.recordsTotal = recordsTotal;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 自定义的错误
|
||||
*
|
||||
* @param code
|
||||
* @param msg
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respCust(int code, String msg) {
|
||||
ApiResp<T> result = new ApiResp<>();
|
||||
result.code = code;
|
||||
result.message = msg;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义的错误
|
||||
*
|
||||
* @param respEnum
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respCust(ApiRespEnum respEnum) {
|
||||
ApiResp<T> result = new ApiResp<>();
|
||||
result.code = respEnum.getCode();
|
||||
result.message = respEnum.getMessage();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户未登录
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respNeedLogin(String msg) {
|
||||
ApiResp<T> result = new ApiResp<>();
|
||||
result.code = 110;
|
||||
result.message = msg;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 操作失败
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respDoFail() {
|
||||
ApiResp<T> result = new ApiResp<>();
|
||||
result.code = 121;
|
||||
result.message = "操作失败";
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据bool返回数据
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> ApiResp<T> respBool(T data, boolean isOk) {
|
||||
ApiResp<T> result = respOK(data);
|
||||
if (!isOk) {
|
||||
result = respDoFail();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(T data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public long getRecordsTotal() {
|
||||
return recordsTotal;
|
||||
}
|
||||
|
||||
public void setRecordsTotal(long recordsTotal) {
|
||||
this.recordsTotal = recordsTotal;
|
||||
}
|
||||
|
||||
public boolean isEncrypt() {
|
||||
return encrypt;
|
||||
}
|
||||
|
||||
public void setEncrypt(boolean encrypt) {
|
||||
this.encrypt = encrypt;
|
||||
}
|
||||
|
||||
public Throwable getException() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public void setException(Throwable exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
package com.tiesheng.util.pojos;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.IdUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
public class FileUploadPath {
|
||||
|
||||
public static String UPLOAD_FOLDER = "/upload/";
|
||||
|
||||
/**
|
||||
* 绝对路径
|
||||
*/
|
||||
private String absolutePath;
|
||||
|
||||
/**
|
||||
* 访问路径
|
||||
*/
|
||||
private String httpPath;
|
||||
|
||||
private FileUploadPath() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得一个文件路径
|
||||
*
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
public static FileUploadPath get(String fileName) {
|
||||
FileUploadPath pathBean = new FileUploadPath();
|
||||
|
||||
String tempPath = fileName;
|
||||
if (!StrUtil.startWith(tempPath, UPLOAD_FOLDER)) {
|
||||
tempPath = UPLOAD_FOLDER + DateUtil.format(DateUtil.date(), "yyyy-MM") + "/" + fileName;
|
||||
}
|
||||
pathBean.setHttpPath(tempPath);
|
||||
pathBean.setAbsolutePath(String.format("%s/static%s", System.getProperty("user.dir"), tempPath));
|
||||
FileUtil.mkParentDirs(pathBean.getAbsolutePath());
|
||||
|
||||
return pathBean;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 随机生成一个文件路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static FileUploadPath random() {
|
||||
return get(IdUtil.simpleUUID());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 随机生成一个文件路径
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static FileUploadPath random(String fileExt) {
|
||||
return get(IdUtil.simpleUUID() + "." + fileExt);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取一个目录
|
||||
*
|
||||
* @param folder
|
||||
* @return
|
||||
*/
|
||||
public static FileUploadPath folder(String folder) {
|
||||
FileUploadPath pathBean = new FileUploadPath();
|
||||
|
||||
String tempFolder = folder;
|
||||
if (!StrUtil.startWith(tempFolder, UPLOAD_FOLDER)) {
|
||||
tempFolder = UPLOAD_FOLDER + tempFolder;
|
||||
}
|
||||
if (!StrUtil.endWith(folder, "/")) {
|
||||
tempFolder = tempFolder + "/";
|
||||
}
|
||||
pathBean.setHttpPath(tempFolder);
|
||||
pathBean.setAbsolutePath(String.format("%s/static%s", System.getProperty("user.dir"), tempFolder));
|
||||
FileUtil.mkParentDirs(pathBean.getAbsolutePath());
|
||||
|
||||
return pathBean;
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// setter\getter
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public String getAbsolutePath() {
|
||||
return absolutePath;
|
||||
}
|
||||
|
||||
public void setAbsolutePath(String absolutePath) {
|
||||
this.absolutePath = absolutePath;
|
||||
}
|
||||
|
||||
public String getHttpPath() {
|
||||
return httpPath;
|
||||
}
|
||||
|
||||
public void setHttpPath(String httpPath) {
|
||||
this.httpPath = httpPath;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user