mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
修改JSON的过滤接口,实现多层过滤
This commit is contained in:
@@ -1,12 +1,14 @@
|
|||||||
package cn.hutool.json;
|
package cn.hutool.json;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanPath;
|
import cn.hutool.core.bean.BeanPath;
|
||||||
|
import cn.hutool.core.lang.mutable.MutableEntry;
|
||||||
import cn.hutool.json.convert.JSONConverterOld;
|
import cn.hutool.json.convert.JSONConverterOld;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.lang.reflect.Type;
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON接口
|
* JSON接口
|
||||||
@@ -23,6 +25,13 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
*/
|
*/
|
||||||
JSONConfig getConfig();
|
JSONConfig getConfig();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON大小,对于JSONObject,是键值对的多少,JSONArray则是元素的个数
|
||||||
|
*
|
||||||
|
* @return 大小
|
||||||
|
*/
|
||||||
|
int size();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过表达式获取JSON中嵌套的对象<br>
|
* 通过表达式获取JSON中嵌套的对象<br>
|
||||||
* <ol>
|
* <ol>
|
||||||
@@ -44,7 +53,7 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
* @see BeanPath#get(Object)
|
* @see BeanPath#get(Object)
|
||||||
* @since 4.0.6
|
* @since 4.0.6
|
||||||
*/
|
*/
|
||||||
default Object getByPath(final String expression){
|
default Object getByPath(final String expression) {
|
||||||
return BeanPath.of(expression).get(this);
|
return BeanPath.of(expression).get(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,7 +78,7 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
* @param expression 表达式
|
* @param expression 表达式
|
||||||
* @param value 值
|
* @param value 值
|
||||||
*/
|
*/
|
||||||
default void putByPath(final String expression, final Object value){
|
default void putByPath(final String expression, final Object value) {
|
||||||
BeanPath.of(expression).set(this, value);
|
BeanPath.of(expression).set(this, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +130,7 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
default String toJSONString(final int indentFactor) throws JSONException {
|
default String toJSONString(final int indentFactor) throws JSONException {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
synchronized (sw.getBuffer()) {
|
synchronized (sw.getBuffer()) {
|
||||||
return this.write(sw, indentFactor, 0).toString();
|
return this.write(sw, indentFactor, 0, null).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +143,7 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
* @throws JSONException JSON相关异常
|
* @throws JSONException JSON相关异常
|
||||||
*/
|
*/
|
||||||
default Writer write(final Writer writer) throws JSONException {
|
default Writer write(final Writer writer) throws JSONException {
|
||||||
return this.write(writer, 0, 0);
|
return this.write(writer, 0, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,10 +153,11 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
* @param writer writer
|
* @param writer writer
|
||||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
||||||
* @param indent 本级别缩进量
|
* @param indent 本级别缩进量
|
||||||
|
* @param predicate 过滤器,可以修改值,key(index)无法修改,{@link Predicate#test(Object)}为{@code true}保留
|
||||||
* @return Writer
|
* @return Writer
|
||||||
* @throws JSONException JSON相关异常
|
* @throws JSONException JSON相关异常
|
||||||
*/
|
*/
|
||||||
Writer write(Writer writer, int indentFactor, int indent) throws JSONException;
|
Writer write(Writer writer, int indentFactor, int indent, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转为实体类对象,转换异常将被抛出
|
* 转为实体类对象,转换异常将被抛出
|
||||||
@@ -163,8 +173,8 @@ public interface JSON extends Cloneable, Serializable {
|
|||||||
/**
|
/**
|
||||||
* 转为实体类对象
|
* 转为实体类对象
|
||||||
*
|
*
|
||||||
* @param <T> Bean类型
|
* @param <T> Bean类型
|
||||||
* @param type {@link Type}
|
* @param type {@link Type}
|
||||||
* @return 实体类对象
|
* @return 实体类对象
|
||||||
* @since 4.3.2
|
* @since 4.3.2
|
||||||
*/
|
*/
|
||||||
|
@@ -533,7 +533,7 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
* @return JSON字符串
|
* @return JSON字符串
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public String toJSONString(final int indentFactor, final Predicate<MutableEntry<Integer, Object>> predicate) {
|
public String toJSONString(final int indentFactor, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
synchronized (sw.getBuffer()) {
|
synchronized (sw.getBuffer()) {
|
||||||
return this.write(sw, indentFactor, 0, predicate).toString();
|
return this.write(sw, indentFactor, 0, predicate).toString();
|
||||||
@@ -541,32 +541,10 @@ public class JSONArray implements JSON, JSONGetter<Integer>, List<Object>, Rando
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Writer write(final Writer writer, final int indentFactor, final int indent) throws JSONException {
|
public Writer write(final Writer writer, final int indentFactor, final int indent, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
||||||
return write(writer, indentFactor, indent, null);
|
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config).beginArray();
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
CollUtil.forEach(this, (value, index) -> jsonWriter.writeField(new MutableEntry<>(index, value), predicate));
|
||||||
* 将JSON内容写入Writer<br>
|
|
||||||
* 支持过滤器,即选择哪些字段或值不写出
|
|
||||||
*
|
|
||||||
* @param writer writer
|
|
||||||
* @param indentFactor 缩进因子,定义每一级别增加的缩进量
|
|
||||||
* @param indent 本级别缩进量
|
|
||||||
* @param predicate 过滤器,可以修改值,key(index)无法修改,{@link Predicate#test(Object)}为{@code true}保留
|
|
||||||
* @return Writer
|
|
||||||
* @throws JSONException JSON相关异常
|
|
||||||
* @since 5.7.15
|
|
||||||
*/
|
|
||||||
public Writer write(final Writer writer, final int indentFactor, final int indent, final Predicate<MutableEntry<Integer, Object>> predicate) throws JSONException {
|
|
||||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
|
||||||
.beginArray();
|
|
||||||
|
|
||||||
CollUtil.forEach(this, (value, index) -> {
|
|
||||||
final MutableEntry<Integer, Object> pair = new MutableEntry<>(index, value);
|
|
||||||
if (null == predicate || predicate.test(pair)) {
|
|
||||||
jsonWriter.writeValue(pair.getValue());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jsonWriter.end();
|
jsonWriter.end();
|
||||||
// 此处不关闭Writer,考虑writer后续还需要填内容
|
// 此处不关闭Writer,考虑writer后续还需要填内容
|
||||||
return writer;
|
return writer;
|
||||||
|
@@ -341,18 +341,13 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @return JSON字符串
|
* @return JSON字符串
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public String toJSONString(final int indentFactor, final Predicate<MutableEntry<String, Object>> predicate) {
|
public String toJSONString(final int indentFactor, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
synchronized (sw.getBuffer()) {
|
synchronized (sw.getBuffer()) {
|
||||||
return this.write(sw, indentFactor, 0, predicate).toString();
|
return this.write(sw, indentFactor, 0, predicate).toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Writer write(final Writer writer, final int indentFactor, final int indent) throws JSONException {
|
|
||||||
return write(writer, indentFactor, indent, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将JSON内容写入Writer<br>
|
* 将JSON内容写入Writer<br>
|
||||||
* 支持过滤器,即选择哪些字段或值不写出
|
* 支持过滤器,即选择哪些字段或值不写出
|
||||||
@@ -365,20 +360,11 @@ public class JSONObject extends MapWrapper<String, Object> implements JSON, JSON
|
|||||||
* @throws JSONException JSON相关异常
|
* @throws JSONException JSON相关异常
|
||||||
* @since 5.7.15
|
* @since 5.7.15
|
||||||
*/
|
*/
|
||||||
public Writer write(final Writer writer, final int indentFactor, final int indent, final Predicate<MutableEntry<String, Object>> predicate) throws JSONException {
|
@Override
|
||||||
|
public Writer write(final Writer writer, final int indentFactor, final int indent, final Predicate<MutableEntry<Object, Object>> predicate) throws JSONException {
|
||||||
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
final JSONWriter jsonWriter = JSONWriter.of(writer, indentFactor, indent, config)
|
||||||
.beginObj();
|
.beginObj();
|
||||||
this.forEach((key, value) -> {
|
this.forEach((key, value) -> jsonWriter.writeField(new MutableEntry<>(key, value), predicate));
|
||||||
if (null != predicate) {
|
|
||||||
final MutableEntry<String, Object> pair = new MutableEntry<>(key, value);
|
|
||||||
if (predicate.test(pair)) {
|
|
||||||
// 使用修改后的键值对
|
|
||||||
jsonWriter.writeField(pair.getKey(), pair.getValue());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
jsonWriter.writeField(key, value);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
jsonWriter.end();
|
jsonWriter.end();
|
||||||
// 此处不关闭Writer,考虑writer后续还需要填内容
|
// 此处不关闭Writer,考虑writer后续还需要填内容
|
||||||
return writer;
|
return writer;
|
||||||
|
@@ -530,32 +530,6 @@ public class JSONUtil {
|
|||||||
return (T) json.getByPath(expression);
|
return (T) json.getByPath(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置表达式指定位置(或filed对应)的值<br>
|
|
||||||
* 若表达式指向一个JSONArray则设置其坐标对应位置的值,若指向JSONObject则put对应key的值<br>
|
|
||||||
* 注意:如果为JSONArray,则设置值得下标不能大于已有JSONArray的长度<br>
|
|
||||||
* <ol>
|
|
||||||
* <li>.表达式,可以获取Bean对象中的属性(字段)值或者Map中key对应的值</li>
|
|
||||||
* <li>[]表达式,可以获取集合等对象中对应index的值</li>
|
|
||||||
* </ol>
|
|
||||||
* <p>
|
|
||||||
* 表达式栗子:
|
|
||||||
*
|
|
||||||
* <pre>
|
|
||||||
* persion
|
|
||||||
* persion.name
|
|
||||||
* persons[3]
|
|
||||||
* person.friends[5].name
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param json JSON,可以为JSONObject或JSONArray
|
|
||||||
* @param expression 表达式
|
|
||||||
* @param value 值
|
|
||||||
*/
|
|
||||||
public static void putByPath(final JSON json, final String expression, final Object value) {
|
|
||||||
json.putByPath(expression, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 格式化JSON字符串,此方法并不严格检查JSON的格式正确与否
|
* 格式化JSON字符串,此方法并不严格检查JSON的格式正确与否
|
||||||
*
|
*
|
||||||
|
@@ -23,6 +23,10 @@ public class AlgorithmUtil {
|
|||||||
map.put("HS384", HmacAlgorithm.HmacSHA384.getValue());
|
map.put("HS384", HmacAlgorithm.HmacSHA384.getValue());
|
||||||
map.put("HS512", HmacAlgorithm.HmacSHA512.getValue());
|
map.put("HS512", HmacAlgorithm.HmacSHA512.getValue());
|
||||||
|
|
||||||
|
map.put("HMD5", HmacAlgorithm.HmacMD5.getValue());
|
||||||
|
map.put("HSHA1", HmacAlgorithm.HmacSHA1.getValue());
|
||||||
|
map.put("SM4CMAC", HmacAlgorithm.SM4CMAC.getValue());
|
||||||
|
|
||||||
map.put("RS256", SignAlgorithm.SHA256withRSA.getValue());
|
map.put("RS256", SignAlgorithm.SHA256withRSA.getValue());
|
||||||
map.put("RS384", SignAlgorithm.SHA384withRSA.getValue());
|
map.put("RS384", SignAlgorithm.SHA384withRSA.getValue());
|
||||||
map.put("RS512", SignAlgorithm.SHA512withRSA.getValue());
|
map.put("RS512", SignAlgorithm.SHA512withRSA.getValue());
|
||||||
@@ -34,6 +38,14 @@ public class AlgorithmUtil {
|
|||||||
map.put("PS256", SignAlgorithm.SHA256withRSA_PSS.getValue());
|
map.put("PS256", SignAlgorithm.SHA256withRSA_PSS.getValue());
|
||||||
map.put("PS384", SignAlgorithm.SHA384withRSA_PSS.getValue());
|
map.put("PS384", SignAlgorithm.SHA384withRSA_PSS.getValue());
|
||||||
map.put("PS512", SignAlgorithm.SHA512withRSA_PSS.getValue());
|
map.put("PS512", SignAlgorithm.SHA512withRSA_PSS.getValue());
|
||||||
|
|
||||||
|
map.put("RMD2", SignAlgorithm.MD2withRSA.getValue());
|
||||||
|
map.put("RMD5", SignAlgorithm.MD5withRSA.getValue());
|
||||||
|
map.put("RSHA1", SignAlgorithm.SHA1withRSA.getValue());
|
||||||
|
map.put("DNONE", SignAlgorithm.NONEwithDSA.getValue());
|
||||||
|
map.put("DSHA1", SignAlgorithm.SHA1withDSA.getValue());
|
||||||
|
map.put("ENONE", SignAlgorithm.NONEwithECDSA.getValue());
|
||||||
|
map.put("ESHA1", SignAlgorithm.SHA1withECDSA.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -120,6 +120,106 @@ public class JWTSignerUtil {
|
|||||||
return createSigner("ES512", key);
|
return createSigner("ES512", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HMD5(HmacMD5)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner hmd5(final Key key) {
|
||||||
|
return createSigner("HMD5",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSHA1(HmacSHA1)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner hsha1(final Key key) {
|
||||||
|
return createSigner("HSHA1",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SM4CMAC(SM4CMAC)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner sm4cmac(final Key key) {
|
||||||
|
return createSigner("SM4CMAC",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RMD2(MD2withRSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner rmd2(final Key key) {
|
||||||
|
return createSigner("RMD2",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RMD5(MD5withRSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner rmd5(final Key key) {
|
||||||
|
return createSigner("RMD5",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RSHA1(SHA1withRSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner rsha1(final Key key) {
|
||||||
|
return createSigner("RSHA1",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DNONE(NONEwithDSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner dnone(final Key key) {
|
||||||
|
return createSigner("DNONE",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSHA1(SHA1withDSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner dsha1(final Key key) {
|
||||||
|
return createSigner("DSHA1",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ENONE(NONEwithECDSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner enone(final Key key) {
|
||||||
|
return createSigner("ENONE",key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ESHA1(SHA1withECDSA)签名器
|
||||||
|
*
|
||||||
|
* @param key 密钥
|
||||||
|
* @return 签名器
|
||||||
|
*/
|
||||||
|
public static JWTSigner esha1(final Key key) {
|
||||||
|
return createSigner("ESHA1",key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建签名器
|
* 创建签名器
|
||||||
*
|
*
|
||||||
|
@@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil;
|
|||||||
import cn.hutool.core.date.TemporalAccessorUtil;
|
import cn.hutool.core.date.TemporalAccessorUtil;
|
||||||
import cn.hutool.core.date.format.GlobalCustomFormat;
|
import cn.hutool.core.date.format.GlobalCustomFormat;
|
||||||
import cn.hutool.core.io.IORuntimeException;
|
import cn.hutool.core.io.IORuntimeException;
|
||||||
|
import cn.hutool.core.lang.mutable.MutableEntry;
|
||||||
import cn.hutool.core.math.NumberUtil;
|
import cn.hutool.core.math.NumberUtil;
|
||||||
import cn.hutool.core.text.StrUtil;
|
import cn.hutool.core.text.StrUtil;
|
||||||
import cn.hutool.core.util.CharUtil;
|
import cn.hutool.core.util.CharUtil;
|
||||||
@@ -18,6 +19,7 @@ import java.io.Writer;
|
|||||||
import java.time.temporal.TemporalAccessor;
|
import java.time.temporal.TemporalAccessor;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JSON数据写出器<br>
|
* JSON数据写出器<br>
|
||||||
@@ -123,54 +125,56 @@ public class JSONWriter extends Writer {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 写出字段名及字段值,如果字段值是{@code null}且忽略null值,则不写出任何内容<br>
|
||||||
|
* 在{@link #arrayMode} 为 {@code true} 时,key是数字,此时不写出键,只写值
|
||||||
|
*
|
||||||
|
* @param pair 键值对
|
||||||
|
* @param predicate 过滤修改器
|
||||||
|
* @return this
|
||||||
|
* @since 6.0.0
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"UnusedReturnValue", "resource"})
|
||||||
|
public JSONWriter writeField(final MutableEntry<Object, Object> pair, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
|
final Object value = pair.getValue();
|
||||||
|
if (null == value && config.isIgnoreNullValue()) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (null != predicate) {
|
||||||
|
if (false == predicate.test(pair)) {
|
||||||
|
// 使用修改后的键值对
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object key = pair.getKey();
|
||||||
|
if(false == arrayMode){
|
||||||
|
// JSONObject模式,写出键,否则只输出值
|
||||||
|
writeKey(StrUtil.toString(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeValueDirect(value, predicate);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写出键,自动处理分隔符和缩进,并包装键名
|
* 写出键,自动处理分隔符和缩进,并包装键名
|
||||||
*
|
*
|
||||||
* @param key 键名
|
* @param key 键名
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings({"resource", "UnusedReturnValue"})
|
||||||
public JSONWriter writeKey(final String key) {
|
public JSONWriter writeKey(final String key) {
|
||||||
if (needSeparator) {
|
if (needSeparator) {
|
||||||
//noinspection resource
|
//noinspection resource
|
||||||
writeRaw(CharUtil.COMMA);
|
writeRaw(CharUtil.COMMA);
|
||||||
}
|
}
|
||||||
// 换行缩进
|
// 换行缩进
|
||||||
//noinspection resource
|
|
||||||
writeLF().writeSpace(indentFactor + indent);
|
writeLF().writeSpace(indentFactor + indent);
|
||||||
return writeRaw(InternalJSONUtil.quote(key));
|
return writeRaw(InternalJSONUtil.quote(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@SuppressWarnings({"SpellCheckingInspection", "NullableProblems"})
|
||||||
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值<br>
|
|
||||||
* 如果写出的值为{@code null},且配置忽略null,则跳过。
|
|
||||||
*
|
|
||||||
* @param value 值
|
|
||||||
* @return this
|
|
||||||
*/
|
|
||||||
public JSONWriter writeValue(final Object value) {
|
|
||||||
if (null == value && config.isIgnoreNullValue()) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
return writeValueDirect(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 写出字段名及字段值,如果字段值是{@code null}且忽略null值,则不写出任何内容
|
|
||||||
*
|
|
||||||
* @param key 字段名
|
|
||||||
* @param value 字段值
|
|
||||||
* @return this
|
|
||||||
* @since 5.7.6
|
|
||||||
*/
|
|
||||||
public JSONWriter writeField(final String key, final Object value) {
|
|
||||||
if (null == value && config.isIgnoreNullValue()) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//noinspection resource
|
|
||||||
return writeKey(key).writeValueDirect(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(final char[] cbuf, final int off, final int len) throws IOException {
|
public void write(final char[] cbuf, final int off, final int len) throws IOException {
|
||||||
this.writer.write(cbuf, off, len);
|
this.writer.write(cbuf, off, len);
|
||||||
@@ -195,10 +199,11 @@ public class JSONWriter extends Writer {
|
|||||||
/**
|
/**
|
||||||
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
|
* 写出值,自动处理分隔符和缩进,自动判断类型,并根据不同类型写出特定格式的值
|
||||||
*
|
*
|
||||||
* @param value 值
|
* @param value 值
|
||||||
|
* @param predicate 过滤修改器
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
private JSONWriter writeValueDirect(final Object value) {
|
private JSONWriter writeValueDirect(final Object value, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
if (arrayMode) {
|
if (arrayMode) {
|
||||||
if (needSeparator) {
|
if (needSeparator) {
|
||||||
//noinspection resource
|
//noinspection resource
|
||||||
@@ -212,22 +217,23 @@ public class JSONWriter extends Writer {
|
|||||||
writeRaw(CharUtil.COLON).writeSpace(1);
|
writeRaw(CharUtil.COLON).writeSpace(1);
|
||||||
}
|
}
|
||||||
needSeparator = true;
|
needSeparator = true;
|
||||||
return writeObjValue(value);
|
return writeObjValue(value, predicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 写出JSON的值,根据值类型不同,输出不同内容
|
* 写出JSON的值,根据值类型不同,输出不同内容
|
||||||
*
|
*
|
||||||
* @param value 值
|
* @param value 值
|
||||||
|
* @param predicate 过滤修改器
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
private JSONWriter writeObjValue(final Object value) {
|
private JSONWriter writeObjValue(final Object value, final Predicate<MutableEntry<Object, Object>> predicate) {
|
||||||
final int indent = indentFactor + this.indent;
|
final int indent = indentFactor + this.indent;
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
//noinspection resource
|
//noinspection resource
|
||||||
writeRaw(StrUtil.NULL);
|
writeRaw(StrUtil.NULL);
|
||||||
} else if (value instanceof JSON) {
|
} else if (value instanceof JSON) {
|
||||||
((JSON) value).write(writer, indentFactor, indent);
|
((JSON) value).write(writer, indentFactor, indent, predicate);
|
||||||
} else if (value instanceof Number) {
|
} else if (value instanceof Number) {
|
||||||
writeNumberValue((Number) value);
|
writeNumberValue((Number) value);
|
||||||
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
|
} else if (value instanceof Date || value instanceof Calendar || value instanceof TemporalAccessor) {
|
||||||
|
26
hutool-json/src/test/java/cn/hutool/json/IssueI5OMSCTest.java
Executable file
26
hutool-json/src/test/java/cn/hutool/json/IssueI5OMSCTest.java
Executable file
@@ -0,0 +1,26 @@
|
|||||||
|
package cn.hutool.json;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Predicate多层过滤
|
||||||
|
*/
|
||||||
|
public class IssueI5OMSCTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void filterTest(){
|
||||||
|
final JSONObject json = JSONUtil.parseObj(ResourceUtil.readUtf8Str("issueI5OMSC.json"));
|
||||||
|
|
||||||
|
final String s = json.toJSONString(0, (entry) -> {
|
||||||
|
final Object key = entry.getKey();
|
||||||
|
if(key instanceof String){
|
||||||
|
return ListUtil.of("store", "bicycle", "color", "book", "author").contains(key);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
Assert.assertEquals("{\"store\":{\"bicycle\":{\"color\":\"red\"},\"book\":[{\"author\":\"Evelyn Waugh\"},{\"author\":\"Evelyn Waugh02\"}]}}", s);
|
||||||
|
}
|
||||||
|
}
|
@@ -700,7 +700,7 @@ public class JSONObjectTest {
|
|||||||
.set("d", true);
|
.set("d", true);
|
||||||
|
|
||||||
final String s = json1.toJSONString(0, (pair) -> {
|
final String s = json1.toJSONString(0, (pair) -> {
|
||||||
pair.setKey(StrUtil.toUnderlineCase(pair.getKey()));
|
pair.setKey(StrUtil.toUnderlineCase((String)pair.getKey()));
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
Assert.assertEquals("{\"a_key\":\"value1\",\"b_job\":\"value2\",\"c_good\":\"value3\",\"d\":true}", s);
|
Assert.assertEquals("{\"a_key\":\"value1\",\"b_job\":\"value2\",\"c_good\":\"value3\",\"d\":true}", s);
|
||||||
|
@@ -116,6 +116,96 @@ public class JWTSignerTest {
|
|||||||
signAndVerify(signer);
|
signAndVerify(signer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hmd5Test(){
|
||||||
|
final String id = "hmd5";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKey(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hsha1Test(){
|
||||||
|
final String id = "hsha1";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKey(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sm4cmacTest(){
|
||||||
|
final String id = "sm4cmac";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKey(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rmd2Test(){
|
||||||
|
final String id = "rmd2";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rmd5Test(){
|
||||||
|
final String id = "rmd5";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void rsha1Test(){
|
||||||
|
final String id = "rsha1";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dnoneTest(){
|
||||||
|
final String id = "dnone";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dsha1Test(){
|
||||||
|
final String id = "dsha1";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void enoneTest(){
|
||||||
|
final String id = "enone";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void esha1Test(){
|
||||||
|
final String id = "esha1";
|
||||||
|
final JWTSigner signer = JWTSignerUtil.createSigner(id, KeyUtil.generateKeyPair(AlgorithmUtil.getAlgorithm(id)));
|
||||||
|
Assert.assertEquals(AlgorithmUtil.getAlgorithm(id), signer.getAlgorithm());
|
||||||
|
|
||||||
|
signAndVerify(signer);
|
||||||
|
}
|
||||||
|
|
||||||
private static void signAndVerify(final JWTSigner signer){
|
private static void signAndVerify(final JWTSigner signer){
|
||||||
final JWT jwt = JWT.of()
|
final JWT jwt = JWT.of()
|
||||||
.setPayload("sub", "1234567890")
|
.setPayload("sub", "1234567890")
|
||||||
|
32
hutool-json/src/test/resources/issueI5OMSC.json
Executable file
32
hutool-json/src/test/resources/issueI5OMSC.json
Executable file
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"store": {
|
||||||
|
"bicycle": {
|
||||||
|
"color": "red",
|
||||||
|
"price": 19.95
|
||||||
|
},
|
||||||
|
"book": [
|
||||||
|
{
|
||||||
|
"category": "fiction",
|
||||||
|
"author": "Evelyn Waugh",
|
||||||
|
"title": "Sword of Honour",
|
||||||
|
"price": 12.99,
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "wujing001",
|
||||||
|
"age": 18
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "wujing002",
|
||||||
|
"age": 18
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"category": "fiction02",
|
||||||
|
"author": "Evelyn Waugh02",
|
||||||
|
"title": "Sword of Honour02",
|
||||||
|
"price": 12.99
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user