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

@Value注解字段传递至DTO层返回null的技术求助

问题分析与解决方案

看起来你遇到的核心问题是Spring的@Value注入未生效,加上映射逻辑没处理配置类数据,导致服务层拿到ConstantClass的null值。下面一步步拆解问题并给出修复方案:

1. 先修复ConstantClass的注入问题

你的ConstantClass存在两个关键错误:

  • 没有被Spring容器管理,导致@Value注解完全不起作用
  • 错误的无参构造函数,试图在Spring完成注入前获取值

修正后的ConstantClass代码

// 添加@Component让Spring扫描并创建实例
@Component
public class ConstantClass {
    // 用final保证不可变,更安全
    private final String hostName;
    private final String pathStart;

    // 构造注入:Spring会自动把配置文件中的值注入到构造参数中
    public ConstantClass(
            @Value("${api.url}") String hostName,
            @Value("${sign.path}") String pathStart
    ) {
        this.hostName = hostName;
        this.pathStart = pathStart;
    }

    // 提供getter方法供外部访问
    public String getHostName() {
        return hostName;
    }

    public String getPathStart() {
        return pathStart;
    }
}

这样Spring会在启动时自动读取application.properties中的值并注入到ConstantClass实例中。

2. 修正MyClass的实例化与依赖传递

你的MyClass构造函数名写错了(应该是MyClass而非DocumentToSignRestRequest),而且需要确保使用Spring管理的ConstantClass实例,而不是手动new一个未注入的对象。

修正后的MyClass代码

public class MyClass {
    private OptionClass optionClass;
    private ConstantClass constantClass;

    // 修正构造函数名,确保参数是Spring注入的ConstantClass
    public MyClass(OptionClass optionClass, ConstantClass constantClass) {
        this.optionClass = optionClass;
        this.constantClass = constantClass;
    }

    // 按需添加getter/setter
}

3. 修正Controller中的映射逻辑

documentToPrepare是请求体,只包含OptionClass的业务数据,不会包含ConstantClass的配置项,所以ModelMapper无法自动映射这部分数据。你需要手动将Spring管理的ConstantClass值设置到DTO中:

优化后的Controller代码

@RestController
public class YourController {
    // 注入Spring管理的实例,不要每次请求new ModelMapper
    @Autowired
    private ConstantClass constantClass;
    @Autowired
    private ModelMapper modelMapper;
    @Autowired
    private DocumentService documentService;

    @PostMapping(
            value="/sign",
            consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE},
            produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE}
    )
    public MyClassRest prepareDocument(@RequestBody DocumentToPrepare documentToPrepare) throws Exception {
        // 1. 映射请求体到MyClassDto的Option部分
        MyClassDto myClassDto = modelMapper.map(documentToPrepare, MyClassDto.class);
        
        // 2. 手动设置ConstantClass的配置值到DTO中
        // 如果MyClassDto包含ConstantClass对象:
        // myClassDto.setConstantClass(constantClass);
        // 如果MyClassDto直接包含hostName/pathStart字段:
        myClassDto.setHostName(constantClass.getHostName());
        myClassDto.setPathStart(constantClass.getPathStart());

        // 3. 调用服务层(注意原代码的documentDto应该是myClassDto的笔误)
        DocumentDto signedDocument = documentService.signDocument(myClassDto);
        
        // 4. 映射返回结果
        return modelMapper.map(signedDocument, MyClassRest.class);
    }
}

4. 额外优化:将ModelMapper配置为Spring Bean

不要每次请求都new ModelMapper,建议全局配置一个Bean:

@Configuration
public class ModelMapperConfig {
    @Bean
    public ModelMapper modelMapper() {
        return new ModelMapper();
    }
}

这样调整后,ConstantClass的配置值就能正常注入,服务层也能拿到正确的非null值了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:13:39