如何在Angular Post方法中传递JSON数组并在API中接收
看起来你遇到的核心问题是后端无法正确解析Angular发送的JSON数组请求体,报错提示"Required request body is missing",这主要是因为后端参数类型选择和Angular请求配置的双重问题,下面一步步帮你解决:
一、先修正Angular端的请求配置
你的Angular代码里存在几个小问题,可能影响请求体的正确发送:
- 重复且错误的Header设置:你重复添加了
Content-Type,而且HttpHeaders.ACCEPT的写法不对(应该是字符串'Accept',或者用Angular的HttpHeaders.ACCEPT常量);另外HttpClient会自动处理JSON序列化,不需要手动调用JSON.stringify()。 - 过时的RequestOptions:Angular 4.3+之后推荐直接用
HttpHeaders和HttpClient的参数配置,替代旧的RequestOptions。
修改后的Angular代码:
// 构建请求头的方法优化 private attachAuthorization(): HttpHeaders { const headers = new HttpHeaders() .set('Content-Type', 'application/json; charset=UTF-8') .set('Accept', 'application/json') .set('Authorization', sessionStorage.getItem('token') || ''); return headers; } // Post方法优化 public post(url: string, requestData: any): Observable<any> { const headers = this.attachAuthorization(); // 不需要手动JSON.stringify,HttpClient会自动序列化 return this.http.post(url, requestData, { headers }); }
二、后端Spring Boot的核心修正
你当前用org.json.JSONArray作为@RequestBody的参数,但Spring默认的消息转换器(MappingJackson2HttpMessageConverter)无法直接将JSON数组转换为这个类型,这才是导致"请求体缺失"报错的关键。推荐两种解决方案:
方案1:使用类型安全的DTO类(更推荐)
先创建一个对应前端数组元素的DTO类,匹配你的JSON结构:
public class FilterColumnDTO { private String columnname; private String filterby; private String values; private String time; private String datatype; // 生成无参构造、全参构造 // 生成getter和setter方法 }
然后修改后端Controller方法,用List<FilterColumnDTO>接收请求体:
@RequestMapping(value = {"/Oats-Exception-summary"}, method = RequestMethod.POST) public ResponseEntity<List<OatsExceptionSummary>> OatsExceptionSummaryPost( @RequestBody List<FilterColumnDTO> payload) throws SQLException, Exception { System.out.println("接收的过滤数组:" + payload); // 这里可以遍历payload处理每个过滤字段,比如拼接FilterData String FilterData = ""; for(FilterColumnDTO column : payload) { // 按你的业务逻辑处理,比如column.getColumnname()获取字段名 } List<OatsExceptionSummary> Data = ISurveillanceService.getOatsExecptionSummary(FilterData); if (Data.isEmpty()) { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { return new ResponseEntity<>(Data, HttpStatus.OK); } }
方案2:使用List<Map<String, Object>>(快速测试用)
如果不想创建DTO类,也可以用List<Map<String, Object>>来接收,适合快速验证:
@RequestMapping(value = {"/Oats-Exception-summary"}, method = RequestMethod.POST) public ResponseEntity<List<OatsExceptionSummary>> OatsExceptionSummaryPost( @RequestBody List<Map<String, Object>> payload) throws SQLException, Exception { System.out.println("接收的过滤数组:" + payload); // 遍历map获取字段:比如map.get("columnname") String FilterData = ""; // ... 业务逻辑处理 List<OatsExceptionSummary> Data = ISurveillanceService.getOatsExecptionSummary(FilterData); if (Data.isEmpty()) { return new ResponseEntity<>(HttpStatus.NO_CONTENT); } else { return new ResponseEntity<>(Data, HttpStatus.OK); } }
三、为什么之前会报错?
Spring的@RequestBody依赖消息转换器将HTTP请求体转换为Java对象,而org.json.JSONArray并不是Spring默认支持的转换类型(默认支持Jackson的List、自定义DTO等),所以Spring无法解析请求体,就会抛出"Required request body is missing"的错误——本质不是请求体没传,而是无法转换为你指定的参数类型。
四、验证测试
修改完代码后,你可以用Postman先测试后端接口:发送POST请求到/Oats-Exception-summary,请求体用你提供的JSON数组,Content-Type设为application/json,确认后端能正常接收后,再用Angular调用,就可以正常工作了。
内容的提问来源于stack exchange,提问作者Nitin Wahale

