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

如何正确转换Spring Boot Entity为Angular对象实现列表展示

问题根因

两个异常本质都是前后端序列化/反序列化的字段、类型不匹配导致的,和手动转JSON的操作没有关系:

  1. 第一个getMessageCode is not a function报错:Angular的HttpClient里的泛型<Rule[]>只是TypeScript做编译时类型校验用的,不会自动把后端返回的纯JSON对象转换成你定义的Rule类实例。后端返回的JSON就是普通JS对象,根本没有你在Rule类里定义的那些getter方法,直接调用当然会报函数不存在。
  2. 改成public字段访问_messageCode后表格行数匹配但无值:Spring Boot默认用Jackson做JSON序列化,序列化规则是读取实体类的getter方法,把getter对应的属性名作为JSON的key。比如Java类里的getMessageCode()对应的key就是messageCode,根本不会带下划线前缀,前端去读_messageCode当然拿不到值。
实现思路合理性说明

你不使用JPA Repository、自行编写数据库查询逻辑加业务筛选、补充数据库未存储的关联信息的思路完全合理。Spring Boot默认已经集成配置好了Jackson序列化器,只要你返回的是可序列化的Java对象(实体、List、数组都支持),框架会自动转换成标准JSON格式返回,根本不需要手动做JSON格式转换,你之前在Controller里把List手动转成数组的操作属于多余逻辑。

分步修复方案

1. 后端代码修正

  • 不要手动实例化Spring上下文和Service类,所有Bean交给容器管理,避免出现上下文重复加载、数据库连接异常等问题,给RuleListService加@Service注解,通过注入方式获取依赖:
@Service
public class RuleListService {
    // 直接注入容器管理的RuleList Bean,不要自己new AnnotationConfigApplicationContext
    @Autowired
    private RuleList lister;
    
    public List<Rule> listRules() {
        ArrayList<HashMap<String, Rule>> ruleMaps = lister.loadRuleMap();
        ArrayList<Rule> ruleList = new ArrayList<Rule>();
        for(HashMap<String, Rule> ruleMap: ruleMaps) { 
            ruleList.addAll(ruleMap.values());
        }
        return ruleList;
    }
}
  • 简化Controller逻辑,直接返回List类型结果,Jackson会自动完成序列化:
@RestController
@RequestMapping("/api/v1")
public class RuleController {
    @Autowired
    private RuleListService ruleListService;

    @CrossOrigin(origins = "http://localhost:4200")
    @GetMapping(value = "/rules", produces = MediaType.APPLICATION_JSON_VALUE)
    public List<Rule> getAllRules() {
        return ruleListService.listRules();
    }
}
  • 额外检查:Rule实体中所有需要返回给前端的字段,都要添加public修饰的getter方法,没有getter的字段Jackson默认不会序列化;不需要返回的字段可以加@JsonIgnore注解排除。

2. 前端代码修正

  • 简化Rule类定义,不要照搬Java的私有字段+getter/setter写法,直接用interface定义数据结构即可,字段名和后端序列化返回的JSON key完全对应,不要加下划线前缀:
export interface Rule {
    fireType: string;
    multipleDrivers: boolean;
    messageCode: string;
    messageTypeCode: string;
    busRuleCode: string;
    externalMessageText: string;
    internalMessageText: string;
    serialVersionUID?: number; // 后端如果没返回这个字段可以直接删掉
}
  • 简化组件中的数据接收逻辑,不需要多余的map类型转换,HttpClient返回的JSON对象会自动匹配interface结构:
export class RuleListComponent implements OnInit {
  rules: Rule[] = []; // 初始化空数组避免模板渲染报错

  constructor(private ruleService: RuleService) { }

  ngOnInit(): void {
    this.getRules();
  }

  private getRules() {
    this.ruleService.getRuleList().subscribe(rules => {
      this.rules = rules;
      // 调试时可以打开控制台打印数据,确认字段结构匹配
      console.log('接收到的规则数据:', rules);
    });
  }
}
  • 修改模板中的字段访问方式,直接读取属性值,不要调用不存在的getter方法:
<h2> Rule List </h2>
<table class = "table table-striped">
    <thead>
        <tr>
            <th> MSG_CD </th>
            <th> MSG_TYP_CD </th>
            <th> BUS_RUL_CD </th>
            <th> MSG_EXTR_USER_TXT </th>
            <th> MSG_INTRL_USER_TXT </th>
            <th> Fire Type </th>
            <th> Multiple Drivers </th> 
        </tr>
    </thead>
    <tbody>
        <tr *ngFor = "let rule of rules" >
            <td> {{rule.messageCode}} </td>
            <td> {{rule.messageTypeCode}} </td>
            <td> {{rule.busRuleCode}} </td>
            <td> {{rule.externalMessageText}}</td>
            <td> {{rule.internalMessageText}} </td>
            <td> {{rule.fireType}} </td>
            <td> {{rule.multipleDrivers}} </td>
        </tr>
    </tbody>
</table>
验证方式

代码修改完成后,先直接在浏览器访问http://localhost:8080/api/v1/rules接口,确认返回的JSON结构、字段名和前端Rule接口定义完全一致,再启动前端项目即可正常渲染数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:01:09