Spring boot @JsonComponent注解 Spring boot + MongoDB

关于@JsonComponent注解我们来看看官方文档给出的解释。


The annotation allows us to expose an annotated class to be a Jackson serializer and/or deserializer without the need to add it to the ObjectMapper manually.

This is part of the core Spring Boot module, so there are no additional dependencies required in a plain Spring Boot application.

注释允许我们将带注释的类公开为Jackson序列化器和/或反序列化器,而无需手动将其添加到ObjectMapper

这是核心Spring Boot模块的一部分,因此在普通的Spring Boot应用程序中不需要额外的依赖项。


一次开发中需要的数据来自mongodb中俩Collections,MongoDB又没提供多Collections查询,也就是说直接查询无法把数据一次查出,把我就搞郁闷了,期初的做法是整一个方法将数据convert成ObjectNode:


    public static ObjectNode convertCrudeLogToJsonNode(CrudeLog crudeLog) {
        var root = JsonUtil.OBJECT_MAPPER.createObjectNode();

        root.put("id", crudeLog.getId().toString());
        root.put("asset_id", crudeLog.getAssetId().toString());
        root.put("facility", ConstantConfig.FACILITY_MAP.get(crudeLog.getFacility()));
        root.put("log_level", ConstantConfig.SEVERITY_MAP.get(crudeLog.getSeverity()));
        root.put("src_ip_address", crudeLog.getSrcIpAddress());
        root.put("timestamp", crudeLog.getTimestamp().getTime());
        root.put("log_create_time", crudeLog.getLogCreateTimestamp().getTime());
        
        return root;
    }

en,nice,我想要的数据得到了,可是方法的功能是多条件分页查询,查询使用的是PageRequest,这么一来就尴尬了,我不可能改了这个整个方法吧;贴一下查询方法:


public Page<Log> queryLog(String assetIpAddr, ObjectId assetId, Severity severity, String keyword,
                              String assetType, ObjectId groupId, LocalDateTime startTime, LocalDateTime endTime,
                              int pageSize, int pageNumber) {
        var query = new Query();

        if (assetId == null) {
            if (StringUtils.isNotBlank(assetIpAddr)) {
                query.addCriteria(where("src_ip_addr").is(assetIpAddr));
            }

            var assetIds = new HashSet<ObjectId>();
            if (StringUtils.isNotBlank(assetType)) {
                
                var assetExample = new Asset();
                
                var assetIdentifierExample = new AssetIdentifier();
                assetIdentifierExample.setType(assetType);
                assetExample.setAssetIdentifier(assetIdentifierExample);
                var assetIdsForType = assetRepository.findAll(Example.of(assetExample)).stream()
                        .map(Asset::getId)
                        .collect(toSet());
                if (assetIdsForType.isEmpty()) {
                    assetIdsForType.add(new ObjectId());
                }
                assetIds.addAll(assetIdsForType);
            }
            if (groupId != null) {
                var assetExample = new Asset();
                var groupExample = new AssetGroup();
                groupExample.setId(groupId);
                assetExample.setAssetGroup(groupExample);
                var assetIdsForGroup = assetRepository.findAll(Example.of(assetExample)).stream()
                        .map(Asset::getId)
                        .collect(toSet());
                if (assetIdsForGroup.isEmpty()) {
                    assetIdsForGroup.add(new ObjectId());
                }
                assetIds.addAll(assetIdsForGroup);
            }
            if (!assetIds.isEmpty()) {
                query.addCriteria(where("asset_id").in(assetIds));
            }
        } else {
            query.addCriteria(where("asset_id").is(assetId));
        }

        if (severity != null) {
            query.addCriteria(where("severity").is(severity));
        }

        Criteria timeCriteria = where("receive_time");
        if (startTime != null) {
            timeCriteria.gte(startTime);
        }
        if (endTime != null) {
            timeCriteria.lte(endTime);
        }
        query.addCriteria(timeCriteria);

        if (StringUtils.isNotBlank(keyword)) {
            var regexBuild = new StringBuilder("^");
            Arrays.stream(keyword.split(" ")).forEach(word -> {
                regexBuild.append("(?=.*");
                regexBuild.append(word);
                regexBuild.append(")");
            });
            query.addCriteria(where("msg").regex(regexBuild.toString(), "i"));
        }

        var pageable = PageRequest.of(pageNumber, pageSize, Sort.Direction.DESC, "_id");
        query.with(pageable);
        var logs = mongoOperations.find(query, Log.class);
        
        return PageableExecutionUtils.getPage(logs, pageable, () -> mongoOperations.count(query, Log.class));
    }

最后我舍弃了最初的方案,请教了写此方法的大佬,大佬给我安利了@JsonComponent。嗯哼 ,然后就有了它 :

@JsonComponent
public class LogJsonSerializer extends JsonSerializer<Log>{

    private AssetRepository assetRepository;

    @Autowired
    public LogJsonSerializer(AssetRepository assetRepository) {
        this.assetRepository = assetRepository;
    }

    @Override
    public void serialize(Log log, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
        jsonGenerator.writeStartObject();//开始写
        jsonGenerator.writeStringField("log_id",log.getId().toString());
        jsonGenerator.writeStringField("hostname",log.getHostname());
        jsonGenerator.writeStringField("msg",log.getMsg());
        jsonGenerator.writeStringField("severity",log.getSeverity().getCnName());
        jsonGenerator.writeStringField("facility",log.getFacility().getCnName());
        jsonGenerator.writeStringField("src_ip_addr",log.getSrcIpAddr());
        jsonGenerator.writeStringField("asset_id",log.getAssetId().toString());
        jsonGenerator.writeObjectField("send_time",log.getSendTime());
        jsonGenerator.writeObjectField("receive_time",log.getReceiveTime());
        jsonGenerator.writeFieldName("asset");
        var assetList = assetRepository.findById(log.getAssetId()).orElse(null);
        jsonGenerator.writeObject(assetList);
        jsonGenerator.writeEndObject();//用完记得关闭
    }
}

文章纯属白话文想到啥写啥。如有建议评论区指点。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值