JFinalJson在序列化时,无法将驼峰序列化成指定方式,比如下划线

/**
 * 配置 Model、Record 字段名的转换函数
 * 
 * <pre>
 * 例子:
 *    JFinalJson.setModelAndRecordFieldNameConverter(fieldName -> {
 *		   return StrKit.toCamelCase(fieldName, true);
 *	  });
 *  
 *  以上例子中的方法 StrKit.toCamelCase(...) 的第二个参数可以控制大小写转化的细节
 *  可以查看其方法上方注释中的说明了解详情
 * </pre>
 */
public static void setModelAndRecordFieldNameConverter(Function<String, String>converter) {
	JFinalJsonKit.modelAndRecordFieldNameConverter = converter;
}

此处有一个设置,可以在model或者record的时候指定序列化方式,但是在其它类型时无效,为什么不指定为全局的呢?一般的JSON格式都是下划线,这一点非常不方便。这些方法里面也未做任何处理,直接原样输出了。

static class BeanToJson implements ToJson<Object> {
	private static final Object[] NULL_ARGS = new Object[0];
	private String[] fields;
	private Method[] methods;
	
	public BeanToJson(String[] fields, Method[] methods) {
		if (fields.length != methods.length) {
			throw new IllegalArgumentException("fields 与 methods 长度必须相同");
		}
		
		this.fields = fields;
		this.methods = methods;
	}
	
	public void toJson(Object bean, int depth, JsonResult ret) {
		if (checkDepth(depth--, ret)) {
			return ;
		}
		
		try {
			ret.addChar('{');
			boolean first = true;
			for (int i = 0; i < fields.length; i++) {
				Object value = methods[i].invoke(bean, NULL_ARGS);
				
				if (value == null && skipNullValueField) {
					continue ;
				}
				
				if (first) {
					first = false;
				} else {
					ret.addChar(',');
				}
				
				ret.addStrNoEscape(fields[i]);
				
				ret.addChar(':');
				
				if (value != null) {
					ToJson tj = me.getToJson(value);
					tj.toJson(value, depth, ret);
				} else {
					ret.addNull();
				}
			}
			ret.addChar('}');
		} catch (ReflectiveOperationException e) {
			throw new RuntimeException(e);
		}
	}
}


如果在主配置已经设置为MixedJson,再去修改主配置为FastJson确实可以解决此问题,但是这也只是下下策,这样model和record又无法序列化了

    @Test    
    public void testRecordToJson() {
        JFinalJson.setModelAndRecordFieldNameConverter((s) -> {
            return Values.toWhichline(s, "_", true);
        });

        Record ret = new Record();
        ret.set("typeName", 1);
        ret.set("test_s", true);

        String json = JFinalJson.getJson().toJson(ret);
        System.out.println(json);
    }
    
    结果: {"test_s":true,"type_name":1}
    @Test    
    public void testBeanToJson() {
        Cat cat = new Cat("kitty", 10, "macro");

        // 无法将驼峰序列化成下划线或者其它指定方式
        String json = JFinalJson.getJson().toJson(cat);
        System.out.println("jfinal json: " + json);
        String json2 = FastJson.getJson().toJson(cat);
        System.out.println("fast json: " + json2);
    }
    
    jfinal json: {"name":"kitty","nickName":"macro","age":10}
      fast json: {"age":10,"name":"kitty","nick_name":"macro"}


评论区

JFinal

2022-09-06 09:21

json 转化时,不同的类型是分别控制的,例如 Model、Record 的转换会有
class ModelToJson extends ToJson
class RecordToJson extends ToJson

而 BeanToJson 也是一样的原理,要接管 BeanToJson 需要通过如下方法实现:
JFinalJsonKit.setToJsonFactory(Function> toJsonFactory);

建议看一下源码: 在 JFinalJsonKit.java 的 106 行

Leo.du

2022-09-06 09:46

@JFinal 如果这样处理,每个类型都要自己定义一次,使用成本是否有点高呀

JFinal

2022-09-06 12:20

@Leo.du 不用每个类型都转,当前你的场景大致处理一下 ModelToJson 就可以了,当然 Map 可能也要处理

JFinal

2022-09-06 12:22

JFinalJson 针对 Model、Record 重点处理,其它类型一般走的 getter 方法