mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
add YamlUtil
This commit is contained in:
parent
ba00f03026
commit
7b6593fe68
@ -3,14 +3,17 @@
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
# 5.7.14 (2021-09-23)
|
||||
# 5.7.14 (2021-09-24)
|
||||
|
||||
### 🐣新特性
|
||||
* 【extra 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(issue#I4B70D@Gitee)
|
||||
* 【http 】 优化Browser版本正则判断
|
||||
* 【setting】 增加YamlUtil
|
||||
* 【extra 】 SenvenZExtractor改名为SevenZExtractor,增加getFirst、get方法
|
||||
|
||||
### 🐞Bug修复
|
||||
* 【http 】 修复HttpCookie设置cookies的方法,不符合RFC6265规范问题(pr#418@Gitee)
|
||||
* 【http 】 修复Extractor中filter无效问题
|
||||
|
||||
-------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -147,8 +147,8 @@ public class AnimatedGifEncoder {
|
||||
/**
|
||||
* Adds next GIF frame. The frame is not written immediately, but is
|
||||
* actually deferred until the next frame is received so that timing
|
||||
* data can be inserted. Invoking <code>finish()</code> flushes all
|
||||
* frames. If <code>setSize</code> was not invoked, the size of the
|
||||
* data can be inserted. Invoking {@code finish()} flushes all
|
||||
* frames. If {@code setSize} was not invoked, the size of the
|
||||
* first image is used for all subsequent frames.
|
||||
*
|
||||
* @param im BufferedImage containing frame to write.
|
||||
@ -225,7 +225,7 @@ public class AnimatedGifEncoder {
|
||||
|
||||
/**
|
||||
* Sets frame rate in frames per second. Equivalent to
|
||||
* <code>setDelay(1000/fps)</code>.
|
||||
* {@code setDelay(1000/fps)}.
|
||||
*
|
||||
* @param fps float frame rate (frames per second)
|
||||
*/
|
||||
|
@ -25,6 +25,8 @@ import java.io.PushbackInputStream;
|
||||
* </code>
|
||||
* <br><br>
|
||||
* 参考: http://akini.mbnet.fi/java/unicodereader/UnicodeInputStream.java.txt
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class BOMInputStream extends InputStream {
|
||||
|
||||
@ -36,10 +38,21 @@ public class BOMInputStream extends InputStream {
|
||||
private static final int BOM_SIZE = 4;
|
||||
|
||||
// ----------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param in 流
|
||||
*/
|
||||
public BOMInputStream(InputStream in) {
|
||||
this(in, CharsetUtil.UTF_8);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param in 流
|
||||
* @param defaultCharset 默认编码
|
||||
*/
|
||||
public BOMInputStream(InputStream in, String defaultCharset) {
|
||||
this.in = new PushbackInputStream(in, BOM_SIZE);
|
||||
this.defaultCharset = defaultCharset;
|
||||
@ -61,7 +74,7 @@ public class BOMInputStream extends InputStream {
|
||||
* @return 编码
|
||||
*/
|
||||
public String getCharset() {
|
||||
if (!isInited) {
|
||||
if (false == isInited) {
|
||||
try {
|
||||
init();
|
||||
} catch (IOException ex) {
|
||||
@ -117,7 +130,6 @@ public class BOMInputStream extends InputStream {
|
||||
charset = defaultCharset;
|
||||
unread = n;
|
||||
}
|
||||
// System.out.println("read=" + n + ", unread=" + unread);
|
||||
|
||||
if (unread > 0) {
|
||||
in.unread(bom, (n - unread), unread);
|
||||
|
58
hutool-core/src/main/java/cn/hutool/core/io/BomReader.java
Normal file
58
hutool-core/src/main/java/cn/hutool/core/io/BomReader.java
Normal file
@ -0,0 +1,58 @@
|
||||
package cn.hutool.core.io;
|
||||
|
||||
import cn.hutool.core.lang.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
/**
|
||||
* 读取带BOM头的流内容的Reader,如果非bom的流或无法识别的编码,则默认UTF-8<br>
|
||||
* BOM定义:http://www.unicode.org/unicode/faq/utf_bom.html
|
||||
*
|
||||
* <ul>
|
||||
* <li>00 00 FE FF = UTF-32, big-endian</li>
|
||||
* <li>FF FE 00 00 = UTF-32, little-endian</li>
|
||||
* <li>EF BB BF = UTF-8</li>
|
||||
* <li>FE FF = UTF-16, big-endian</li>
|
||||
* <li>FF FE = UTF-16, little-endian</li>
|
||||
* </ul>
|
||||
* 使用: <br>
|
||||
* <code>
|
||||
* FileInputStream fis = new FileInputStream(file); <br>
|
||||
* BomReader uin = new BomReader(fis); <br>
|
||||
* </code>
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public class BomReader extends Reader {
|
||||
|
||||
private InputStreamReader reader;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param in 流
|
||||
*/
|
||||
public BomReader(InputStream in) {
|
||||
Assert.notNull(in, "InputStream must be not null!");
|
||||
final BOMInputStream bin = (in instanceof BOMInputStream) ? (BOMInputStream) in : new BOMInputStream(in);
|
||||
try {
|
||||
this.reader = new InputStreamReader(bin, bin.getCharset());
|
||||
} catch (UnsupportedEncodingException ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char[] cbuf, int off, int len) throws IOException {
|
||||
return reader.read(cbuf, off, len);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
reader.close();
|
||||
}
|
||||
}
|
@ -224,6 +224,17 @@ public class IoUtil extends NioUtil {
|
||||
return getReader(in, in.getCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* 从{@link InputStream}中获取{@link BomReader}
|
||||
*
|
||||
* @param in {@link InputStream}
|
||||
* @return {@link BomReader}
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public static BomReader getBomReader(InputStream in) {
|
||||
return new BomReader(in);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得一个Reader
|
||||
*
|
||||
|
@ -1,5 +1,6 @@
|
||||
package cn.hutool.core.lang;
|
||||
|
||||
import cn.hutool.core.bean.BeanPath;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
@ -76,7 +77,7 @@ public class Dict extends LinkedHashMap<String, Object> implements BasicTypeGett
|
||||
* <p>奇数参数必须为value,可以为任意类型。</p>
|
||||
*
|
||||
* <pre>
|
||||
Dict dict = Dict.of(
|
||||
* Dict dict = Dict.of(
|
||||
* "RED", "#FF0000",
|
||||
* "GREEN", "#00FF00",
|
||||
* "BLUE", "#0000FF"
|
||||
@ -91,10 +92,10 @@ public class Dict extends LinkedHashMap<String, Object> implements BasicTypeGett
|
||||
final Dict dict = create();
|
||||
|
||||
String key = null;
|
||||
for(int i = 0; i < keysAndValues.length; i++){
|
||||
if(i % 2 == 0){
|
||||
for (int i = 0; i < keysAndValues.length; i++) {
|
||||
if (i % 2 == 0) {
|
||||
key = Convert.toStr(keysAndValues[i]);
|
||||
} else{
|
||||
} else {
|
||||
dict.put(key, keysAndValues[i]);
|
||||
}
|
||||
}
|
||||
@ -504,6 +505,61 @@ public class Dict extends LinkedHashMap<String, Object> implements BasicTypeGett
|
||||
public Number getNumber(String attr) {
|
||||
return get(attr, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过表达式获取JSON中嵌套的对象<br>
|
||||
* <ol>
|
||||
* <li>.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值</li>
|
||||
* <li>[]表达式,可以获取集合等对象中对应index的值</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* 表达式栗子:
|
||||
*
|
||||
* <pre>
|
||||
* persion
|
||||
* persion.name
|
||||
* persons[3]
|
||||
* person.friends[5].name
|
||||
* </pre>
|
||||
*
|
||||
* @param expression 表达式
|
||||
* @return 对象
|
||||
* @see BeanPath#get(Object)
|
||||
* @since 5.7.14
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T getByPath(String expression) {
|
||||
return (T) BeanPath.create(expression).get(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过表达式获取JSON中嵌套的对象<br>
|
||||
* <ol>
|
||||
* <li>.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值</li>
|
||||
* <li>[]表达式,可以获取集合等对象中对应index的值</li>
|
||||
* </ol>
|
||||
* <p>
|
||||
* 表达式栗子:
|
||||
*
|
||||
* <pre>
|
||||
* persion
|
||||
* persion.name
|
||||
* persons[3]
|
||||
* person.friends[5].name
|
||||
* </pre>
|
||||
* <p>
|
||||
* 获取表达式对应值后转换为对应类型的值
|
||||
*
|
||||
* @param <T> 返回值类型
|
||||
* @param expression 表达式
|
||||
* @param resultType 返回值类型
|
||||
* @return 对象
|
||||
* @see BeanPath#get(Object)
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public <T> T getByPath(String expression, Class<T> resultType) {
|
||||
return Convert.convert(resultType, getByPath(expression));
|
||||
}
|
||||
// -------------------------------------------------------------------- Get end
|
||||
|
||||
@Override
|
||||
|
@ -14,45 +14,61 @@ import java.util.List;
|
||||
* 此模板用于简化对指定表的操作,简化的操作如下:<br>
|
||||
* 1、在初始化时指定了表名,CRUD操作时便不需要表名<br>
|
||||
* 2、在初始化时指定了主键,某些需要主键的操作便不需要指定主键类型
|
||||
* @author Looly
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class DaoTemplate {
|
||||
|
||||
/** 表名 */
|
||||
/**
|
||||
* 表名
|
||||
*/
|
||||
protected String tableName;
|
||||
/** 本表的主键字段,请在子类中覆盖或构造方法中指定,默认为id */
|
||||
/**
|
||||
* 本表的主键字段,请在子类中覆盖或构造方法中指定,默认为id
|
||||
*/
|
||||
protected String primaryKeyField = "id";
|
||||
/** SQL运行器 */
|
||||
/**
|
||||
* SQL运行器
|
||||
*/
|
||||
protected Db db;
|
||||
|
||||
//--------------------------------------------------------------- Constructor start
|
||||
|
||||
/**
|
||||
* 构造,此构造需要自定义SqlRunner,主键默认为id
|
||||
*
|
||||
* @param tableName 数据库表名
|
||||
*/
|
||||
public DaoTemplate(String tableName) {
|
||||
this(tableName, (String)null);
|
||||
this(tableName, (String) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造,使用默认的池化连接池,读取默认配置文件的空分组,适用于只有一个数据库的情况
|
||||
* @param tableName 数据库表名
|
||||
*
|
||||
* @param tableName 数据库表名
|
||||
* @param primaryKeyField 主键字段名
|
||||
*/
|
||||
public DaoTemplate(String tableName, String primaryKeyField) {
|
||||
this(tableName, primaryKeyField, DSFactory.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param tableName 表
|
||||
* @param ds 数据源
|
||||
*/
|
||||
public DaoTemplate(String tableName, DataSource ds) {
|
||||
this(tableName, null, ds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param tableName 表名
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param primaryKeyField 主键字段名
|
||||
* @param ds 数据源
|
||||
* @param ds 数据源
|
||||
*/
|
||||
public DaoTemplate(String tableName, String primaryKeyField, DataSource ds) {
|
||||
this(tableName, primaryKeyField, Db.use(ds));
|
||||
@ -60,13 +76,14 @@ public class DaoTemplate {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
* @param tableName 表名
|
||||
*
|
||||
* @param tableName 表名
|
||||
* @param primaryKeyField 主键字段名
|
||||
* @param db Db对象
|
||||
* @param db Db对象
|
||||
*/
|
||||
public DaoTemplate(String tableName, String primaryKeyField, Db db) {
|
||||
this.tableName = tableName;
|
||||
if(StrUtil.isNotBlank(primaryKeyField)){
|
||||
if (StrUtil.isNotBlank(primaryKeyField)) {
|
||||
this.primaryKeyField = primaryKeyField;
|
||||
}
|
||||
this.db = db;
|
||||
@ -74,8 +91,10 @@ public class DaoTemplate {
|
||||
//--------------------------------------------------------------- Constructor end
|
||||
|
||||
//------------------------------------------------------------- Add start
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return 插入行数
|
||||
* @throws SQLException SQL执行异常
|
||||
@ -86,6 +105,7 @@ public class DaoTemplate {
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return 主键列表
|
||||
* @throws SQLException SQL执行异常
|
||||
@ -96,6 +116,7 @@ public class DaoTemplate {
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param entity 实体对象
|
||||
* @return 自增主键
|
||||
* @throws SQLException SQL执行异常
|
||||
@ -106,11 +127,12 @@ public class DaoTemplate {
|
||||
//------------------------------------------------------------- Add end
|
||||
|
||||
//------------------------------------------------------------- Delete start
|
||||
|
||||
/**
|
||||
* 删除
|
||||
* @param <T> 主键类型
|
||||
*
|
||||
* @param pk 主键
|
||||
* @param <T> 主键类型
|
||||
* @param pk 主键
|
||||
* @return 删除行数
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
@ -124,7 +146,7 @@ public class DaoTemplate {
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param <T> 主键类型
|
||||
* @param <T> 主键类型
|
||||
* @param field 字段名
|
||||
* @param value 字段值
|
||||
* @return 删除行数
|
||||
@ -141,7 +163,7 @@ public class DaoTemplate {
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @param <T> 主键类型
|
||||
* @param <T> 主键类型
|
||||
* @param where 删除条件,当条件为空时,返回0(防止误删全表)
|
||||
* @return 删除行数
|
||||
* @throws SQLException SQL执行异常
|
||||
@ -155,14 +177,16 @@ public class DaoTemplate {
|
||||
//------------------------------------------------------------- Delete end
|
||||
|
||||
//------------------------------------------------------------- Update start
|
||||
|
||||
/**
|
||||
* 按照条件更新
|
||||
*
|
||||
* @param record 更新的内容
|
||||
* @param where 条件
|
||||
* @param where 条件
|
||||
* @return 更新条目数
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public int update(Entity record, Entity where) throws SQLException{
|
||||
public int update(Entity record, Entity where) throws SQLException {
|
||||
if (MapUtil.isEmpty(record)) {
|
||||
return 0;
|
||||
}
|
||||
@ -171,6 +195,7 @@ public class DaoTemplate {
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*
|
||||
* @param entity 实体对象,必须包含主键
|
||||
* @return 更新行数
|
||||
* @throws SQLException SQL执行异常
|
||||
@ -194,6 +219,7 @@ public class DaoTemplate {
|
||||
|
||||
/**
|
||||
* 增加或者更新实体
|
||||
*
|
||||
* @param entity 实体,当包含主键时更新,否则新增
|
||||
* @return 新增或更新条数
|
||||
* @throws SQLException SQL执行异常
|
||||
@ -204,11 +230,12 @@ public class DaoTemplate {
|
||||
//------------------------------------------------------------- Update end
|
||||
|
||||
//------------------------------------------------------------- Get start
|
||||
|
||||
/**
|
||||
* 根据主键获取单个记录
|
||||
*
|
||||
* @param <T> 主键类型
|
||||
* @param pk 主键值
|
||||
* @param pk 主键值
|
||||
* @return 记录
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
@ -220,7 +247,7 @@ public class DaoTemplate {
|
||||
* 根据某个字段(最好是唯一字段)查询单个记录<br>
|
||||
* 当有多条返回时,只显示查询到的第一条
|
||||
*
|
||||
* @param <T> 字段值类型
|
||||
* @param <T> 字段值类型
|
||||
* @param field 字段名
|
||||
* @param value 字段值
|
||||
* @return 记录
|
||||
@ -243,10 +270,11 @@ public class DaoTemplate {
|
||||
//------------------------------------------------------------- Get end
|
||||
|
||||
//------------------------------------------------------------- Find start
|
||||
|
||||
/**
|
||||
* 根据某个字段值查询结果
|
||||
*
|
||||
* @param <T> 字段值类型
|
||||
* @param <T> 字段值类型
|
||||
* @param field 字段名
|
||||
* @param value 字段值
|
||||
* @return 记录
|
||||
@ -258,6 +286,7 @@ public class DaoTemplate {
|
||||
|
||||
/**
|
||||
* 查询当前表的所有记录
|
||||
*
|
||||
* @return 记录
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
@ -281,14 +310,14 @@ public class DaoTemplate {
|
||||
* SQL语句可以是非完整SQL语句,可以只提供查询的条件部分(例如WHERE部分)<br>
|
||||
* 此方法会自动补全SELECT * FROM [tableName] 部分,这样就无需关心表名,直接提供条件即可
|
||||
*
|
||||
* @param sql SQL语句
|
||||
* @param sql SQL语句
|
||||
* @param params SQL占位符中对应的参数
|
||||
* @return 记录
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public List<Entity> findBySql(String sql, Object... params) throws SQLException {
|
||||
String selectKeyword = StrUtil.subPre(sql.trim(), 6).toLowerCase();
|
||||
if(false == "select".equals(selectKeyword)){
|
||||
if (false == "select".equals(selectKeyword)) {
|
||||
sql = "SELECT * FROM " + this.tableName + " " + sql;
|
||||
}
|
||||
return db.query(sql, params);
|
||||
@ -297,13 +326,13 @@ public class DaoTemplate {
|
||||
/**
|
||||
* 分页
|
||||
*
|
||||
* @param where 条件
|
||||
* @param page 分页对象
|
||||
* @param where 条件
|
||||
* @param page 分页对象
|
||||
* @param selectFields 查询的字段列表
|
||||
* @return 分页结果集
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public PageResult<Entity> page(Entity where, Page page, String... selectFields) throws SQLException{
|
||||
public PageResult<Entity> page(Entity where, Page page, String... selectFields) throws SQLException {
|
||||
return db.page(Arrays.asList(selectFields), fixEntity(where), page);
|
||||
}
|
||||
|
||||
@ -311,11 +340,11 @@ public class DaoTemplate {
|
||||
* 分页
|
||||
*
|
||||
* @param where 条件
|
||||
* @param page 分页对象
|
||||
* @param page 分页对象
|
||||
* @return 分页结果集
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public PageResult<Entity> page(Entity where, Page page) throws SQLException{
|
||||
public PageResult<Entity> page(Entity where, Page page) throws SQLException {
|
||||
return db.page(fixEntity(where), page);
|
||||
}
|
||||
|
||||
@ -326,7 +355,7 @@ public class DaoTemplate {
|
||||
* @return 数量
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public long count(Entity where) throws SQLException{
|
||||
public long count(Entity where) throws SQLException {
|
||||
return db.count(fixEntity(where));
|
||||
}
|
||||
|
||||
@ -337,20 +366,21 @@ public class DaoTemplate {
|
||||
* @return 是否存在
|
||||
* @throws SQLException SQL执行异常
|
||||
*/
|
||||
public boolean exist(Entity where) throws SQLException{
|
||||
public boolean exist(Entity where) throws SQLException {
|
||||
return this.count(where) > 0;
|
||||
}
|
||||
//------------------------------------------------------------- Find end
|
||||
|
||||
/**
|
||||
* 修正Entity对象,避免null和填充表名
|
||||
*
|
||||
* @param entity 实体类
|
||||
* @return 修正后的实体类
|
||||
*/
|
||||
private Entity fixEntity(Entity entity){
|
||||
if(null == entity){
|
||||
private Entity fixEntity(Entity entity) {
|
||||
if (null == entity) {
|
||||
entity = Entity.create(tableName);
|
||||
}else if(StrUtil.isBlank(entity.getTableName())){
|
||||
} else if (StrUtil.isBlank(entity.getTableName())) {
|
||||
entity.setTableName(tableName);
|
||||
}
|
||||
return entity;
|
||||
|
34
hutool-db/src/test/java/cn/hutool/db/PicTransferTest.java
Normal file
34
hutool-db/src/test/java/cn/hutool/db/PicTransferTest.java
Normal file
@ -0,0 +1,34 @@
|
||||
package cn.hutool.db;
|
||||
|
||||
import cn.hutool.core.collection.ListUtil;
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class PicTransferTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void findTest() throws SQLException {
|
||||
Db.use().find(
|
||||
ListUtil.of("NAME", "TYPE", "GROUP", "PIC"),
|
||||
Entity.create("PIC_INFO").set("TYPE", 1),
|
||||
rs -> {
|
||||
while(rs.next()){
|
||||
save(rs);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
private static void save(ResultSet rs) throws SQLException{
|
||||
String destDir = "d:/test/pic";
|
||||
String path = StrUtil.format("{}/{}-{}.jpg", destDir, rs.getString("NAME"), rs.getString("GROUP"));
|
||||
FileUtil.writeFromStream(rs.getBlob("PIC").getBinaryStream(), path);
|
||||
}
|
||||
}
|
@ -451,11 +451,5 @@
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tukaani</groupId>
|
||||
<artifactId>xz</artifactId>
|
||||
<version>1.9</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -6,7 +6,7 @@ import cn.hutool.extra.compress.archiver.Archiver;
|
||||
import cn.hutool.extra.compress.archiver.SevenZArchiver;
|
||||
import cn.hutool.extra.compress.archiver.StreamArchiver;
|
||||
import cn.hutool.extra.compress.extractor.Extractor;
|
||||
import cn.hutool.extra.compress.extractor.SenvenZExtractor;
|
||||
import cn.hutool.extra.compress.extractor.SevenZExtractor;
|
||||
import cn.hutool.extra.compress.extractor.StreamExtractor;
|
||||
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
|
||||
import org.apache.commons.compress.archivers.StreamingNotSupportedException;
|
||||
@ -168,14 +168,14 @@ public class CompressUtil {
|
||||
*/
|
||||
public static Extractor createExtractor(Charset charset, String archiverName, File file) {
|
||||
if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(archiverName)) {
|
||||
return new SenvenZExtractor(file);
|
||||
return new SevenZExtractor(file);
|
||||
}
|
||||
try {
|
||||
return new StreamExtractor(charset, archiverName, file);
|
||||
} catch (CompressException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause instanceof StreamingNotSupportedException && cause.getMessage().contains("7z")) {
|
||||
return new SenvenZExtractor(file);
|
||||
return new SevenZExtractor(file);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
@ -218,14 +218,15 @@ public class CompressUtil {
|
||||
*/
|
||||
public static Extractor createExtractor(Charset charset, String archiverName, InputStream in) {
|
||||
if (ArchiveStreamFactory.SEVEN_Z.equalsIgnoreCase(archiverName)) {
|
||||
return new SenvenZExtractor(in);
|
||||
return new SevenZExtractor(in);
|
||||
}
|
||||
|
||||
try {
|
||||
return new StreamExtractor(charset, archiverName, in);
|
||||
} catch (CompressException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (cause instanceof StreamingNotSupportedException && cause.getMessage().contains("7z")) {
|
||||
return new SenvenZExtractor(in);
|
||||
return new SevenZExtractor(in);
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public interface Extractor extends Closeable {
|
||||
* 释放(解压)到指定目录,结束后自动关闭流,此方法只能调用一次
|
||||
*
|
||||
* @param targetDir 目标目录
|
||||
* @param filter 解压文件过滤器,用于指定需要释放的文件,null表示不过滤。当{@link Filter#accept(Object)}为true时释放。
|
||||
* @param filter 解压文件过滤器,用于指定需要释放的文件,{@code null}表示不过滤。当{@link Filter#accept(Object)}为true时释放。
|
||||
*/
|
||||
void extract(File targetDir, Filter<ArchiveEntry> filter);
|
||||
|
||||
|
@ -20,8 +20,9 @@ public class Seven7EntryInputStream extends InputStream {
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param sevenZFile {@link SevenZFile}
|
||||
* @param entry {@link SevenZArchiveEntry}
|
||||
* @param entry {@link SevenZArchiveEntry}
|
||||
*/
|
||||
public Seven7EntryInputStream(SevenZFile sevenZFile, SevenZArchiveEntry entry) {
|
||||
this.sevenZFile = sevenZFile;
|
||||
@ -30,13 +31,23 @@ public class Seven7EntryInputStream extends InputStream {
|
||||
|
||||
@Override
|
||||
public int available() throws IOException {
|
||||
try{
|
||||
try {
|
||||
return Math.toIntExact(this.size);
|
||||
} catch (ArithmeticException e){
|
||||
} catch (ArithmeticException e) {
|
||||
throw new IOException("Entry size is too large!(max than Integer.MAX)", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取读取的长度(字节数)
|
||||
*
|
||||
* @return 读取的字节数
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public long getReadSize() {
|
||||
return this.readSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
this.readSize++;
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Filter;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
|
||||
@ -14,6 +15,7 @@ import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.channels.SeekableByteChannel;
|
||||
import java.util.RandomAccess;
|
||||
|
||||
/**
|
||||
* 7z格式数据解压器,即将归档打包的数据释放
|
||||
@ -21,7 +23,7 @@ import java.nio.channels.SeekableByteChannel;
|
||||
* @author looly
|
||||
* @since 5.5.0
|
||||
*/
|
||||
public class SenvenZExtractor implements Extractor {
|
||||
public class SevenZExtractor implements Extractor, RandomAccess {
|
||||
|
||||
private final SevenZFile sevenZFile;
|
||||
|
||||
@ -30,7 +32,7 @@ public class SenvenZExtractor implements Extractor {
|
||||
*
|
||||
* @param file 包文件
|
||||
*/
|
||||
public SenvenZExtractor(File file) {
|
||||
public SevenZExtractor(File file) {
|
||||
this(file, null);
|
||||
}
|
||||
|
||||
@ -40,7 +42,7 @@ public class SenvenZExtractor implements Extractor {
|
||||
* @param file 包文件
|
||||
* @param password 密码,null表示无密码
|
||||
*/
|
||||
public SenvenZExtractor(File file, char[] password) {
|
||||
public SevenZExtractor(File file, char[] password) {
|
||||
try {
|
||||
this.sevenZFile = new SevenZFile(file, password);
|
||||
} catch (IOException e) {
|
||||
@ -53,7 +55,7 @@ public class SenvenZExtractor implements Extractor {
|
||||
*
|
||||
* @param in 包流
|
||||
*/
|
||||
public SenvenZExtractor(InputStream in) {
|
||||
public SevenZExtractor(InputStream in) {
|
||||
this(in, null);
|
||||
}
|
||||
|
||||
@ -63,7 +65,7 @@ public class SenvenZExtractor implements Extractor {
|
||||
* @param in 包流
|
||||
* @param password 密码,null表示无密码
|
||||
*/
|
||||
public SenvenZExtractor(InputStream in, char[] password) {
|
||||
public SevenZExtractor(InputStream in, char[] password) {
|
||||
this(new SeekableInMemoryByteChannel(IoUtil.readBytes(in)), password);
|
||||
}
|
||||
|
||||
@ -72,7 +74,7 @@ public class SenvenZExtractor implements Extractor {
|
||||
*
|
||||
* @param channel {@link SeekableByteChannel}
|
||||
*/
|
||||
public SenvenZExtractor(SeekableByteChannel channel) {
|
||||
public SevenZExtractor(SeekableByteChannel channel) {
|
||||
this(channel, null);
|
||||
}
|
||||
|
||||
@ -82,7 +84,7 @@ public class SenvenZExtractor implements Extractor {
|
||||
* @param channel {@link SeekableByteChannel}
|
||||
* @param password 密码,null表示无密码
|
||||
*/
|
||||
public SenvenZExtractor(SeekableByteChannel channel, char[] password) {
|
||||
public SevenZExtractor(SeekableByteChannel channel, char[] password) {
|
||||
try {
|
||||
this.sevenZFile = new SevenZFile(channel, password);
|
||||
} catch (IOException e) {
|
||||
@ -107,6 +109,44 @@ public class SenvenZExtractor implements Extractor {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取满足指定过滤要求的压缩包内的第一个文件流
|
||||
*
|
||||
* @param filter 用于指定需要释放的文件,null表示不过滤。当{@link Filter#accept(Object)}为true时返回对应流。
|
||||
* @return 满足过滤要求的第一个文件的流,无满足条件的文件返回{@code null}
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public InputStream getFirst(Filter<ArchiveEntry> filter) {
|
||||
final SevenZFile sevenZFile = this.sevenZFile;
|
||||
for(SevenZArchiveEntry entry : sevenZFile.getEntries()){
|
||||
if(null != filter && false == filter.accept(entry)){
|
||||
continue;
|
||||
}
|
||||
if(entry.isDirectory()){
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
return sevenZFile.getInputStream(entry);
|
||||
} catch (IOException e) {
|
||||
throw new IORuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定名称的文件流
|
||||
*
|
||||
* @param entryName entry名称
|
||||
* @return 文件流,无文件返回{@code null}
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public InputStream get(String entryName){
|
||||
return getFirst((entry)-> StrUtil.equals(entryName, entry.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 释放(解压)到指定目录
|
||||
*
|
||||
@ -120,6 +160,9 @@ public class SenvenZExtractor implements Extractor {
|
||||
SevenZArchiveEntry entry;
|
||||
File outItemFile;
|
||||
while (null != (entry = this.sevenZFile.getNextEntry())) {
|
||||
if(null != filter && false == filter.accept(entry)){
|
||||
continue;
|
||||
}
|
||||
outItemFile = FileUtil.file(targetDir, entry.getName());
|
||||
if (entry.isDirectory()) {
|
||||
// 创建对应目录
|
@ -109,6 +109,9 @@ public class StreamExtractor implements Extractor{
|
||||
ArchiveEntry entry;
|
||||
File outItemFile;
|
||||
while (null != (entry = in.getNextEntry())) {
|
||||
if(null != filter && false == filter.accept(entry)){
|
||||
continue;
|
||||
}
|
||||
if (false == in.canReadEntryData(entry)) {
|
||||
// 无法读取的文件直接跳过
|
||||
continue;
|
||||
|
@ -50,7 +50,7 @@ public class ArchiverTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void senvenZTest(){
|
||||
public void sevenZTest(){
|
||||
final File file = FileUtil.file("d:/test/compress/test.7z");
|
||||
CompressUtil.createArchiver(CharsetUtil.CHARSET_UTF_8, ArchiveStreamFactory.SEVEN_Z, file)
|
||||
.add(FileUtil.file("d:/Java/apache-maven-3.6.3"), (f)->{
|
||||
|
@ -21,7 +21,7 @@ public class ExtractorTest {
|
||||
@Test
|
||||
@Ignore
|
||||
public void sevenZTest(){
|
||||
Extractor extractor = CompressUtil.createExtractor(
|
||||
Extractor extractor = CompressUtil.createExtractor(
|
||||
CharsetUtil.defaultCharset(),
|
||||
FileUtil.file("d:/test/compress/test.7z"));
|
||||
|
||||
|
@ -1,14 +1,6 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
@lombok.Data
|
||||
public class Data {
|
||||
|
||||
private Price Price;
|
||||
|
||||
public void setPrice(Price Price) {
|
||||
this.Price = Price;
|
||||
}
|
||||
|
||||
public Price getPrice() {
|
||||
return Price;
|
||||
}
|
||||
}
|
||||
|
@ -1,63 +1,22 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author 质量过关
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class ExamInfoDict implements Serializable {
|
||||
private static final long serialVersionUID = 3640936499125004525L;
|
||||
|
||||
|
||||
// 主键
|
||||
private Integer id; // 可当作题号
|
||||
// 试题类型 客观题 0主观题 1
|
||||
private Integer examType;
|
||||
// 试题是否作答
|
||||
private Integer answerIs;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getExamType() {
|
||||
return examType;
|
||||
}
|
||||
public void setExamType(Integer examType) {
|
||||
this.examType = examType;
|
||||
}
|
||||
|
||||
public Integer getAnswerIs() {
|
||||
return answerIs;
|
||||
}
|
||||
public void setAnswerIs(Integer answerIs) {
|
||||
this.answerIs = answerIs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
ExamInfoDict that = (ExamInfoDict) o;
|
||||
return Objects.equals(id, that.id) && Objects.equals(examType, that.examType) && Objects.equals(answerIs, that.answerIs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, examType, answerIs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ExamInfoDict{" + "id=" + id + ", examType=" + examType + ", answerIs=" + answerIs + '}';
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,10 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import cn.hutool.json.JSONObject;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class JSONBean {
|
||||
|
||||
private int code;
|
||||
private JSONObject data;
|
||||
|
||||
public int getCode() {
|
||||
return code;
|
||||
}
|
||||
public void setCode(int code) {
|
||||
this.code = code;
|
||||
}
|
||||
public JSONObject getData() {
|
||||
return data;
|
||||
}
|
||||
public void setData(JSONObject data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class JsonNode implements Serializable {
|
||||
private static final long serialVersionUID = -2280206942803550272L;
|
||||
|
||||
@ -17,33 +20,4 @@ public class JsonNode implements Serializable {
|
||||
this.parentId = parentId;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getParentId() {
|
||||
return parentId;
|
||||
}
|
||||
|
||||
public void setParentId(Integer parentId) {
|
||||
this.parentId = parentId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "JsonNode{" + "id=" + id + ", parentId=" + parentId + ", name='" + name + '\'' + '}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,61 +0,0 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JsonRootBean {
|
||||
|
||||
private int statusCode;
|
||||
private String message;
|
||||
private int skip;
|
||||
private int limit;
|
||||
private int total;
|
||||
private List<Data> data;
|
||||
|
||||
public void setStatusCode(int statusCode) {
|
||||
this.statusCode = statusCode;
|
||||
}
|
||||
|
||||
public int getStatusCode() {
|
||||
return statusCode;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setSkip(int skip) {
|
||||
this.skip = skip;
|
||||
}
|
||||
|
||||
public int getSkip() {
|
||||
return skip;
|
||||
}
|
||||
|
||||
public void setLimit(int limit) {
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
public int getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
public void setTotal(int total) {
|
||||
this.total = total;
|
||||
}
|
||||
|
||||
public int getTotal() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public void setData(List<Data> data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public List<Data> getData() {
|
||||
return data;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,13 +1,15 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author wangyan E-mail:wangyan@pospt.cn
|
||||
* @version 创建时间:2017年9月11日 上午9:33:01 类说明
|
||||
*/
|
||||
@Data
|
||||
public class ProductResBase implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -6708040074002451511L;
|
||||
/**
|
||||
* 请求结果成功0
|
||||
@ -21,6 +23,7 @@ public class ProductResBase implements Serializable {
|
||||
* 成功code
|
||||
*/
|
||||
public static final String REQUEST_CODE_SUCCESS = "0000";
|
||||
|
||||
/**
|
||||
* 结果 成功0 失败1
|
||||
*/
|
||||
@ -32,40 +35,4 @@ public class ProductResBase implements Serializable {
|
||||
* 成本总计
|
||||
*/
|
||||
private Integer costTotal;
|
||||
|
||||
public Integer getCostTotal() {
|
||||
return costTotal;
|
||||
}
|
||||
|
||||
public ProductResBase setCostTotal(Integer costTotal) {
|
||||
this.costTotal = costTotal;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getResResult() {
|
||||
return resResult;
|
||||
}
|
||||
|
||||
public String getResCode() {
|
||||
return resCode;
|
||||
}
|
||||
|
||||
public String getResMsg() {
|
||||
return resMsg;
|
||||
}
|
||||
|
||||
public ProductResBase setResResult(int resResult) {
|
||||
this.resResult = resResult;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProductResBase setResCode(String resCode) {
|
||||
this.resCode = resCode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProductResBase setResMsg(String resMsg) {
|
||||
this.resMsg = resMsg;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class ResultDto<T> implements Serializable {
|
||||
private static final long serialVersionUID = -1417999729205654379L;
|
||||
|
||||
@ -128,28 +131,4 @@ public class ResultDto<T> implements Serializable {
|
||||
public boolean error() {
|
||||
return !success();
|
||||
}
|
||||
|
||||
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 getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(T result) {
|
||||
this.result = result;
|
||||
}
|
||||
}
|
||||
|
@ -1,25 +1,15 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class Seq {
|
||||
private String seq;
|
||||
|
||||
|
||||
public Seq() {
|
||||
}
|
||||
|
||||
|
||||
public Seq(String seq) {
|
||||
this.seq = seq;
|
||||
}
|
||||
|
||||
public String getSeq() {
|
||||
return seq;
|
||||
}
|
||||
|
||||
public void setSeq(String seq) {
|
||||
this.seq = seq;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Seq [seq=" + seq + "]";
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,9 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class TokenAuthResponse {
|
||||
private String token;
|
||||
private String userId;
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public void setToken(String token) {
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
public String getUserId() {
|
||||
return userId;
|
||||
}
|
||||
|
||||
public void setUserId(String userId) {
|
||||
this.userId = userId;
|
||||
}
|
||||
}
|
||||
|
@ -1,24 +1,13 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class TokenAuthWarp extends UUMap<TokenAuthResponse> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private String targetUrl;
|
||||
private String success;
|
||||
|
||||
public String getTargetUrl() {
|
||||
return targetUrl;
|
||||
}
|
||||
|
||||
public void setTargetUrl(String targetUrl) {
|
||||
this.targetUrl = targetUrl;
|
||||
}
|
||||
|
||||
public String getSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setSuccess(String success) {
|
||||
this.success = success;
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,5 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
public class TokenAuthWarp2 extends TokenAuthWarp {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
}
|
||||
|
@ -1,20 +1,15 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class UUMap<T> implements Serializable{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
private T result;
|
||||
|
||||
public T getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(T result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public static long getSerialversionuid() {
|
||||
return serialVersionUID;
|
||||
}
|
||||
|
@ -1,28 +1,12 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Data
|
||||
public class UserB {
|
||||
private String name;
|
||||
private String b;
|
||||
private Date date;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getB() {
|
||||
return b;
|
||||
}
|
||||
public void setB(String a) {
|
||||
this.b = a;
|
||||
}
|
||||
public Date getDate() {
|
||||
return date;
|
||||
}
|
||||
public void setDate(Date date) {
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +1,10 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class UserC {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String prop;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getProp() {
|
||||
return prop;
|
||||
}
|
||||
|
||||
public void setProp(String prop) {
|
||||
this.prop = prop;
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,16 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
* @author 质量过关
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class UserInfoDict implements Serializable {
|
||||
private static final long serialVersionUID = -936213991463284306L;
|
||||
// 用户Id
|
||||
@ -19,61 +21,4 @@ public class UserInfoDict implements Serializable {
|
||||
private String photoPath;
|
||||
private List<ExamInfoDict> examInfoDict;
|
||||
private UserInfoRedundCount userInfoRedundCount;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getRealName() {
|
||||
return realName;
|
||||
}
|
||||
public void setRealName(String realName) {
|
||||
this.realName = realName;
|
||||
}
|
||||
|
||||
public String getPhotoPath() {
|
||||
return photoPath;
|
||||
}
|
||||
public void setPhotoPath(String photoPath) {
|
||||
this.photoPath = photoPath;
|
||||
}
|
||||
|
||||
public List<ExamInfoDict> getExamInfoDict() {
|
||||
return examInfoDict;
|
||||
}
|
||||
public void setExamInfoDict(List<ExamInfoDict> examInfoDict) {
|
||||
this.examInfoDict = examInfoDict;
|
||||
}
|
||||
|
||||
public UserInfoRedundCount getUserInfoRedundCount() {
|
||||
return userInfoRedundCount;
|
||||
}
|
||||
public void setUserInfoRedundCount(UserInfoRedundCount userInfoRedundCount) {
|
||||
this.userInfoRedundCount = userInfoRedundCount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o == null || getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
UserInfoDict that = (UserInfoDict) o;
|
||||
return Objects.equals(id, that.id) && Objects.equals(realName, that.realName) && Objects.equals(photoPath, that.photoPath) && Objects.equals(examInfoDict, that.examInfoDict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, realName, photoPath, examInfoDict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "UserInfoDict [id=" + id + ", realName=" + realName + ", photoPath=" + photoPath + ", examInfoDict=" + examInfoDict + ", userInfoRedundCount=" + userInfoRedundCount + "]";
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +1,14 @@
|
||||
package cn.hutool.json.test.bean;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class UserInfoRedundCount implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -8397291070139255181L;
|
||||
|
||||
private String finishedRatio; // 完成率
|
||||
|
||||
private Integer ownershipExamCount; // 自己有多少道题
|
||||
|
||||
private Integer answeredExamCount; // 当前回答了多少道题
|
||||
|
||||
public Integer getOwnershipExamCount() {
|
||||
return ownershipExamCount;
|
||||
}
|
||||
|
||||
public void setOwnershipExamCount(Integer ownershipExamCount) {
|
||||
this.ownershipExamCount = ownershipExamCount;
|
||||
}
|
||||
|
||||
public Integer getAnsweredExamCount() {
|
||||
return answeredExamCount;
|
||||
}
|
||||
|
||||
public void setAnsweredExamCount(Integer answeredExamCount) {
|
||||
this.answeredExamCount = answeredExamCount;
|
||||
}
|
||||
|
||||
public String getFinishedRatio() {
|
||||
return finishedRatio;
|
||||
}
|
||||
|
||||
public void setFinishedRatio(String finishedRatio) {
|
||||
this.finishedRatio = finishedRatio;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,5 +27,11 @@
|
||||
<artifactId>hutool-log</artifactId>
|
||||
<version>${project.parent.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>1.29</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
@ -0,0 +1,133 @@
|
||||
package cn.hutool.setting.yaml;
|
||||
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.io.resource.ResourceUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.io.Writer;
|
||||
|
||||
/**
|
||||
* 基于Snakeyaml的的YAML读写工具
|
||||
*
|
||||
* @author looly
|
||||
* @since 5.7.14
|
||||
*/
|
||||
public class YamlUtil {
|
||||
|
||||
/**
|
||||
* 从classpath或绝对路径加载YAML文件
|
||||
*
|
||||
* @param path YAML路径,相对路径相对classpath
|
||||
* @return 加载的内容,默认Map
|
||||
*/
|
||||
public static Dict loadByPath(String path) {
|
||||
return loadByPath(path, Dict.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从classpath或绝对路径加载YAML文件
|
||||
*
|
||||
* @param <T> Bean类型,默认map
|
||||
* @param path YAML路径,相对路径相对classpath
|
||||
* @param type 加载的Bean类型,即转换为的bean
|
||||
* @return 加载的内容,默认Map
|
||||
*/
|
||||
public static <T> T loadByPath(String path, Class<T> type) {
|
||||
return load(ResourceUtil.getStream(path), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从流中加载YAML
|
||||
*
|
||||
* @param <T> Bean类型,默认map
|
||||
* @param in 流
|
||||
* @param type 加载的Bean类型,即转换为的bean
|
||||
* @return 加载的内容,默认Map
|
||||
*/
|
||||
public static <T> T load(InputStream in, Class<T> type) {
|
||||
return load(IoUtil.getBomReader(in), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载YAML,加载完毕后关闭{@link Reader}
|
||||
*
|
||||
* @param reader {@link Reader}
|
||||
* @return 加载的Map
|
||||
*/
|
||||
public static Dict load(Reader reader) {
|
||||
return load(reader, Dict.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载YAML,加载完毕后关闭{@link Reader}
|
||||
*
|
||||
* @param <T> Bean类型,默认map
|
||||
* @param reader {@link Reader}
|
||||
* @param type 加载的Bean类型,即转换为的bean
|
||||
* @return 加载的内容,默认Map
|
||||
*/
|
||||
public static <T> T load(Reader reader, Class<T> type) {
|
||||
return load(reader, type, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载YAML
|
||||
*
|
||||
* @param <T> Bean类型,默认map
|
||||
* @param reader {@link Reader}
|
||||
* @param type 加载的Bean类型,即转换为的bean
|
||||
* @param isCloseReader 加载完毕后是否关闭{@link Reader}
|
||||
* @return 加载的内容,默认Map
|
||||
*/
|
||||
public static <T> T load(Reader reader, Class<T> type, boolean isCloseReader) {
|
||||
Assert.notNull(reader, "Reader must be not null !");
|
||||
if (null == type) {
|
||||
//noinspection unchecked
|
||||
type = (Class<T>) Object.class;
|
||||
}
|
||||
|
||||
final Yaml yaml = new Yaml();
|
||||
try {
|
||||
return yaml.loadAs(reader, type);
|
||||
} finally {
|
||||
if (isCloseReader) {
|
||||
IoUtil.close(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Bean对象或者Map写出到{@link Writer}
|
||||
*
|
||||
* @param object 对象
|
||||
* @param writer {@link Writer}
|
||||
*/
|
||||
public static void dump(Object object, Writer writer) {
|
||||
final DumperOptions options = new DumperOptions();
|
||||
options.setIndent(2);
|
||||
options.setPrettyFlow(true);
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
|
||||
dump(object, writer, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将Bean对象或者Map写出到{@link Writer}
|
||||
*
|
||||
* @param object 对象
|
||||
* @param writer {@link Writer}
|
||||
* @param dumperOptions 输出风格
|
||||
*/
|
||||
public static void dump(Object object, Writer writer, DumperOptions dumperOptions) {
|
||||
if (null == dumperOptions) {
|
||||
dumperOptions = new DumperOptions();
|
||||
}
|
||||
final Yaml yaml = new Yaml(dumperOptions);
|
||||
yaml.dump(object, writer);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
/**
|
||||
* YAML文件的读写封装,基于snakeyaml
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.setting.yaml;
|
@ -1,4 +1,4 @@
|
||||
package cn.hutool.setting.test;
|
||||
package cn.hutool.setting;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.log.LogFactory;
|
||||
@ -17,7 +17,7 @@ import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Setting单元测试
|
||||
*
|
||||
*
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
@ -50,23 +50,23 @@ public class PropsTest {
|
||||
String driver = props.getStr("driver");
|
||||
Assert.assertEquals(driver, "com.mysql.jdbc.Driver");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void toBeanTest() {
|
||||
Props props = Props.getProp("to_bean_test.properties");
|
||||
|
||||
|
||||
ConfigProperties cfg = props.toBean(ConfigProperties.class, "mail");
|
||||
Assert.assertEquals("mailer@mail.com", cfg.getHost());
|
||||
Assert.assertEquals(9000, cfg.getPort());
|
||||
Assert.assertEquals("mailer@mail.com", cfg.getFrom());
|
||||
|
||||
|
||||
Assert.assertEquals("john", cfg.getCredentials().getUsername());
|
||||
Assert.assertEquals("password", cfg.getCredentials().getPassword());
|
||||
Assert.assertEquals("SHA1", cfg.getCredentials().getAuthMethod());
|
||||
|
||||
|
||||
Assert.assertEquals("true", cfg.getAdditionalHeaders().get("redelivery"));
|
||||
Assert.assertEquals("true", cfg.getAdditionalHeaders().get("secure"));
|
||||
|
||||
|
||||
Assert.assertEquals("admin@mail.com", cfg.getDefaultRecipients().get(0));
|
||||
Assert.assertEquals("owner@mail.com", cfg.getDefaultRecipients().get(1));
|
||||
}
|
||||
@ -98,7 +98,7 @@ public class PropsTest {
|
||||
private List<String> defaultRecipients;
|
||||
private Map<String, String> additionalHeaders;
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
public static class Credentials {
|
||||
private String authMethod;
|
@ -1,4 +1,4 @@
|
||||
package cn.hutool.setting.test;
|
||||
package cn.hutool.setting;
|
||||
|
||||
import cn.hutool.setting.dialect.PropsUtil;
|
||||
import org.junit.Assert;
|
||||
@ -7,7 +7,7 @@ import org.junit.Test;
|
||||
import java.util.Objects;
|
||||
|
||||
public class PropsUtilTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void getTest() {
|
||||
String driver = PropsUtil.get("test").getStr("driver");
|
@ -1,12 +1,10 @@
|
||||
package cn.hutool.setting.test;
|
||||
package cn.hutool.setting;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.setting.Setting;
|
||||
|
||||
/**
|
||||
* Setting单元测试
|
||||
*
|
@ -1,12 +1,10 @@
|
||||
package cn.hutool.setting.test;
|
||||
package cn.hutool.setting;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import cn.hutool.setting.SettingUtil;
|
||||
|
||||
public class SettingUtilTest {
|
||||
|
||||
|
||||
@Test
|
||||
public void getTest() {
|
||||
String driver = SettingUtil.get("test").get("demo", "driver");
|
@ -0,0 +1,36 @@
|
||||
package cn.hutool.setting.yaml;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class YamlUtilTest {
|
||||
|
||||
@Test
|
||||
public void loadByPathTest() {
|
||||
final Dict result = YamlUtil.loadByPath("test.yaml", Dict.class);
|
||||
|
||||
Assert.assertEquals("John", result.getStr("firstName"));
|
||||
|
||||
final List<Integer> numbers = result.getByPath("contactDetails.number");
|
||||
Assert.assertEquals(123456789, (int) numbers.get(0));
|
||||
Assert.assertEquals(456786868, (int) numbers.get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void dumpTest() {
|
||||
final Dict dict = Dict.create()
|
||||
.set("name", "hutool")
|
||||
.set("count", 1000);
|
||||
|
||||
YamlUtil.dump(
|
||||
dict
|
||||
, FileUtil.getWriter("d:/test/dump.yaml", CharsetUtil.CHARSET_UTF_8, false));
|
||||
}
|
||||
}
|
13
hutool-setting/src/test/resources/test.yaml
Normal file
13
hutool-setting/src/test/resources/test.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
firstName: "John"
|
||||
lastName: "Doe"
|
||||
age: 31
|
||||
contactDetails:
|
||||
- type: "mobile"
|
||||
number: 123456789
|
||||
- type: "landline"
|
||||
number: 456786868
|
||||
homeAddress:
|
||||
line: "Xyz, DEF Street"
|
||||
city: "City Y"
|
||||
state: "State Y"
|
||||
zip: 345657
|
@ -9,6 +9,7 @@ import org.junit.Test;
|
||||
public class OshiPrintTest {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void printCpuInfo(){
|
||||
Console.log(OshiUtil.getCpuInfo());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user