You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Data Repository JSON对象反序列化:Solr后端配置技术问询

在Spring Data Solr中实现JSON反序列化的方案

Alright, let's break down how to handle JSON deserialization in your Spring Data Solr setup. You've already got your ProductCatalogRepository and Product domain object wired up with Spring Data's annotations, so we can build on that directly. Below are the most common scenarios and step-by-step solutions:

1. 默认序列化/反序列化(基础场景)

First off, Spring Data Solr (via SolrJ) automatically handles basic type mapping using your @SolrDocument and @Field annotations. For primitive types (strings, numbers, dates, etc.), you don't need extra configuration—this works out of the box.

The problem usually comes when you need to map JSON-formatted fields (e.g., a nested object stored as a JSON string in a Solr field) to your domain object's properties. Let's cover that next.

2. 场景:实体包含JSON格式的嵌套字段

Suppose your Product class has a field like productDetails which maps to a Solr string field (product_details_s) storing JSON data. Here's how to set up deserialization for this:

Step 1: Define your nested object

First, create the class representing the JSON structure:

package domain;

public class ProductDetails {
    private String material;
    private int weight;
    // Getters, setters, no-arg constructor
}

Step 2: Add the field to your Product entity

Update your Product domain object to include the nested field, and specify we'll use a custom converter:

package domain;

import org.apache.solr.client.solrj.beans.Field;
import org.springframework.data.annotation.Id;
import org.springframework.data.solr.core.mapping.SolrDocument;
import org.springframework.data.solr.core.mapping.Converter;

@SolrDocument(solrCoreName = "your-core-name")
public class Product {
    @Id
    @Field("id")
    private String id;
    
    @Field(value = "product_details_s", converter = JsonToProductDetailsConverter.class)
    private ProductDetails productDetails;
    
    // Other fields, getters, setters
}

Step 3: Implement the JSON converter

Create a converter that uses Jackson's ObjectMapper to deserialize the JSON string into your ProductDetails object (and serialize it back when saving):

package converter;

import com.fasterxml.jackson.databind.ObjectMapper;
import domain.ProductDetails;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class JsonToProductDetailsConverter implements Converter<String, ProductDetails> {

    private final ObjectMapper objectMapper;

    // Inject Spring's default ObjectMapper (auto-configured in Spring Boot)
    public JsonToProductDetailsConverter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public ProductDetails convert(String source) {
        try {
            return objectMapper.readValue(source, ProductDetails.class);
        } catch (IOException e) {
            throw new RuntimeException("Failed to deserialize JSON to ProductDetails", e);
        }
    }
}

// Don't forget the reverse converter for saving
@Component
public class ProductDetailsToJsonConverter implements Converter<ProductDetails, String> {

    private final ObjectMapper objectMapper;

    public ProductDetailsToJsonConverter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public String convert(ProductDetails source) {
        try {
            return objectMapper.writeValueAsString(source);
        } catch (IOException e) {
            throw new RuntimeException("Failed to serialize ProductDetails to JSON", e);
        }
    }
}

Step 4: Register the converters (if not using @Component)

If you don't use @Component, you can register them in a Spring configuration class:

package config;

import converter.JsonToProductDetailsConverter;
import converter.ProductDetailsToJsonConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.solr.core.convert.SolrConverter;
import org.springframework.data.solr.core.convert.MappingSolrConverter;
import org.springframework.data.solr.core.mapping.SimpleSolrMappingContext;

@Configuration
public class SolrConfig {

    @Bean
    public SolrConverter solrConverter(SimpleSolrMappingContext mappingContext, ObjectMapper objectMapper) {
        MappingSolrConverter converter = new MappingSolrConverter(mappingContext);
        converter.setCustomConverters(java.util.List.of(
            new JsonToProductDetailsConverter(objectMapper),
            new ProductDetailsToJsonConverter(objectMapper)
        ));
        converter.afterPropertiesSet();
        return converter;
    }
}

3. 自定义全局文档反序列化

If you need full control over how entire Solr documents are converted to your domain objects (not just individual fields), you can extend MappingSolrConverter:

package converter;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.data.solr.core.convert.MappingSolrConverter;
import org.springframework.data.solr.core.mapping.SolrMappingContext;

public class CustomSolrConverter extends MappingSolrConverter {

    private final ObjectMapper objectMapper;

    public CustomSolrConverter(SolrMappingContext mappingContext, ObjectMapper objectMapper) {
        super(mappingContext);
        this.objectMapper = objectMapper;
        // Add any global custom converters here
    }

    // Override methods like read() if you need to customize entire document deserialization
}

Then register this custom converter in your Solr configuration as shown in Step 4.

Key Notes

  • Ensure you have Jackson dependencies in your project (Spring Boot's spring-boot-starter-web includes jackson-databind by default).
  • If your Solr instance uses the native json field type (available in Solr 8+), you can map it directly to a Map<String, Object> or your custom object without a converter—SolrJ will handle it automatically.
  • Always include no-arg constructors in your domain classes—Spring Data needs them to instantiate objects during deserialization.

内容的提问来源于stack exchange,提问作者Jacob Tomaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:36:11