在默认情况下Thymeleaf对于js块中的对象解析是使用jackson进行序列化,但是特定情况下我们需要更换成其他类型的序列话工具。
例如:由于springboot默认的序列化使用的jackson,而我们的脱敏规则也是建立在jackson序列化时对属性进行脱敏。
在thymeleaf模板中注入html块变量时可以直接通过对象设值,不存在序列化的动作,但是对于js块中的对象需要javaScriptSerializer进行序列化
因此会存在列表中是脱敏的数据,进行编辑页面如果属性赋值是通过thymeleaf的js块,则会触发jackson的脱敏规则。
我们对象中已经存在很多jackson属性的注解例如日期等,所以为了避免大规模改动,我选择更改thymeleafjs块的序列化方式。
通过阅读Thymeleaf源码我们发现javaScriptSerializer默认使用的为Jackson的ObjectMapper进行序列化,但是观察调用方我们发现如果已经设置javaScriptSerializer。
则不会使用jackson,除jackson之外还存在一个默认的序列化器,由于其属于内部类,无法外部调用初始化,因而我选择通过实现IStandardJavaScriptSerializer来
定义自己的js对象序列化器,其中使用fastjson,至此我们可以规避在js中使用对象时,属性被脱敏的情况发生。

我们首先需要实现可以作为JavaScript序列化的通用接口类来自定义序列化器

package com.common.nmg.utils;

import com.alibaba.fastjson.JSONObject;
import org.thymeleaf.standard.serializer.IStandardJavaScriptSerializer;

import java.io.Writer;

public class FastJsonJavaScriptSerializer implements IStandardJavaScriptSerializer {

    @Override
    public void serializeValue(Object object, Writer writer) {
        JSONObject.writeJSONString(writer,object);
    }
}

再将自定义的序列化器注入到spring的thymeleaf模板解析器中

package com.nmg.framework.config;

import com.nmg.common.utils.FastJsonJavaScriptSerializer;
import com.nmg.common.utils.spring.SpringUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.CollectionUtils;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.standard.StandardDialect;

import javax.annotation.PostConstruct;

/**
 *
 * @author zengzp
 * @date 2022年6月14日 17点38分
 * @desc
 */
@Configuration
public class ThymeleafConfig {

    @PostConstruct
    public void init() {
        SpringTemplateEngine springTemplateEngine = SpringUtils.getBean(SpringTemplateEngine.class);
        StandardDialect standardDialect = CollectionUtils.findValueOfType(springTemplateEngine.getDialects(), StandardDialect.class);
        standardDialect.setJavaScriptSerializer(new FastJsonJavaScriptSerializer());
    }
}

独上兰舟
119 声望5 粉丝

路漫漫其修远兮,吾将上下而求索。