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

Spring Boot REST服务中如何编写String转POJO转换器?

你遇到的这个转换异常,核心原因是**@RequestParam是用来处理URL查询参数或表单的简单类型参数**,而你传递的是复杂POJO列表,Spring默认没法把字符串形式的参数直接转换成ComponentDataForm对象。下面给你两种解决方案,优先推荐第一种更符合REST规范的实现:


方案一:改用@RequestBody传递请求体(推荐)

POST请求传递复杂对象列表时,标准做法是把数据放在请求体里,而不是拼在URL的查询参数中。这样既避免了URL长度限制,也更符合RESTful设计规范。

后端控制器修改

把参数注解从@RequestParam改成@RequestBody,Spring会自动解析请求体中的JSON数组为List<ComponentDataForm>:

@PostMapping
private ServerResponse creatAllCompDatas(@RequestBody final List<ComponentDataForm> componentDataFormValues) {
    if (isSessionValid()) {
        List<Long> datasIds = new ArrayList();
        componentDataFormValues.stream().forEach(formValue -> {
            MNG_COMPOSANT_DATA mng_composant_data = new MNG_COMPOSANT_DATA();
            mng_composant_data.setCmp_attr_code(formValue.getAttCode());
            mng_composant_data.setCmp_attr_label(formValue.getAttTitle());
            mng_composant_data.setCmp_attr_value(formValue.getAttVal());
            datasIds.add(mng_composant_data.getId());
        });
        initSuccessResponse(datasIds);
        return serverResponse;
    }
    initFailLoginResponse();
    return serverResponse;
}

前端JavaFX修改

将原来的queryString传参改成发送JSON请求体,Unirest会自动把列表序列化为JSON数组:

@FXML private void doCommit(ActionEvent event) throws UnirestException{
    if(validate()){
        final ObservableList<AppDataAttTDO> items = tableAtributes.getItems();
        final List<ComponentDataForm> componentDataFormValues = new ArrayList();
        items.stream().forEach(item -> {
            final ComponentDataForm requestItem = new ComponentDataForm();
            requestItem.setAttCode(item.getAttCode());
            requestItem.setAttTitle(item.getAttTitle());
            requestItem.setAttVal(item.getAttValue());
            componentDataFormValues.add(requestItem);
        });

        HttpResponse<String> asString = Unirest.post(APPLICATION_DATA_SERVICE_URL)
                .header("Content-Type", "application/json")
                .body(componentDataFormValues)
                .asString();

        System.out.println(asString.getStatus());
        System.out.println(asString.getBody());
    }
}

方案二:实现Converter(仅当必须用@RequestParam时)

如果因为特殊场景必须用查询参数传递,你可以实现Spring的Converter接口,把字符串形式的参数转换成ComponentDataForm对象。假设你传递的每个参数是JSON格式的字符串:

1. 实现转换器

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

@Component
public class StringToComponentDataFormConverter implements Converter<String, ComponentDataForm> {

    private final ObjectMapper objectMapper;

    // 注入Spring自动配置的ObjectMapper
    public StringToComponentDataFormConverter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public ComponentDataForm convert(String source) {
        try {
            // 将JSON字符串解析为ComponentDataForm对象
            return objectMapper.readValue(source, ComponentDataForm.class);
        } catch (Exception e) {
            throw new IllegalArgumentException("无法解析字符串为ComponentDataForm: " + source, e);
        }
    }
}

2. 注册转换器到Spring容器

在Spring Boot配置类中,把转换器注册到WebMvc配置里:

import org.springframework.context.annotation.Configuration;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    private final StringToComponentDataFormConverter converter;

    public WebConfig(StringToComponentDataFormConverter converter) {
        this.converter = converter;
    }

    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(converter);
    }
}

3. 前端修改

前端需要把每个ComponentDataForm对象序列化为JSON字符串,再作为查询参数传递:

@FXML private void doCommit(ActionEvent event) throws UnirestException, JsonProcessingException{
    if(validate()){
        final ObservableList<AppDataAttTDO> items = tableAtributes.getItems();
        final ObjectMapper objectMapper = new ObjectMapper();
        final List<String> componentDataJsonList = new ArrayList();
        
        items.stream().forEach(item -> {
            final ComponentDataForm requestItem = new ComponentDataForm();
            requestItem.setAttCode(item.getAttCode());
            requestItem.setAttTitle(item.getAttTitle());
            requestItem.setAttVal(item.getAttValue());
            try {
                // 将对象转为JSON字符串
                componentDataJsonList.add(objectMapper.writeValueAsString(requestItem));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        });

        HttpResponse<String> asString = Unirest.post(APPLICATION_DATA_SERVICE_URL)
                .queryString("componentDataFormValues", componentDataJsonList)
                .asString();

        System.out.println(asString.getStatus());
        System.out.println(asString.getBody());
    }
}

再次提醒:这种方式仅适用于特殊场景,日常开发优先选择方案一,它更规范且不易出问题。

内容的提问来源于stack exchange,提问作者Mohammed Housseyn Taleb

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:08:59